I want to write a structured binary file in Haskell. For example, assume that the first four bytes should be "TEST" (as ASCII), followed by the numbers 1, 2, 3, 4, then 32 bytes each with the value 128 and then the number 2048 in Little Endian format.
That means, the created file (as hex) should look like this:
54 45 53 54 01 02 03 04 80 80 [... 30 bytes more ...] 00 08
So basically I have a custom data structure, let's say
data MyData = MyData {
header :: String -- "TEST"
n1 :: Integer -- 1
n2 :: Integer -- 2
n3 :: Integer -- 3
block :: [Integer] -- 32 times 128
offset :: Integer -- 2048
}
Now I want to write this data to file. So basically I need to convert this structure into one long ByteString. I could not find out a clean idiomatic way to do this. Ideally I have a function
MyDataToByteString :: MyData -> ByteString
or
MyDataToPut :: MyData -> Put
but I could not find out how to create such a function.
Background information: I want to write a song in the impulse tracker format (http://schismtracker.org/wiki/ITTECH.TXT), which is the binary format for the schism tracker software.
Update 1
For the endian conversion, I guess I can just extract the individual Bytes as follows:
getByte :: Int -> Int -> Int
getByte b num = shift (num .&. bitMask b) (8-8*b)
where bitMask b = sum $ map (2^) [8*b-8 .. 8*b-1]