How to serialize little-endian PODs painlessly?
haskell, serialization
Solution
Data.Binary will let you serialize the structure to a bytestring, using explicitly little-endian operators.
{-# OPTIONS_GHC -funbox-strict-fields #-}
{-# LANGUAGE RecordWildCards #-}
import Data.Binary
import Data.Binary.Put
import qualified Data.ByteString.Char8 as C
import qualified Data.ByteString.Lazy as L
data WaveFormatChunk =
WaveFormatChunk {
compression :: !Word16,
channels :: !Word16,
sampleRate :: !Word32,
averageBps :: !Word32,
blockAlign :: !Word16,
significantBits :: !Word16
}
instance Binary WaveFormatChunk where
put (WaveFormatChunk{..}) = do
putWord16le compression
putWord16le channels
putWord32le sampleRate
putWord32le averageBps
putWord16le blockAlign
putWord16le significantBits
get = undefined
main = C.putStr $ C.concat $ L.toChunks $ encode test
where
test = WaveFormatChunk {
compression = 0xcafe
, channels = 0xface
, sampleRate = 0xdeadbeef
, averageBps = 0xf01dab1e
, blockAlign = 0x5566
, significantBits = 0xb01d
}
Will yield:
$ ./A | od -x
0000000 cafe face beef dead ab1e f01d 5566 b01d
So you have precise byte-level control of the representation. You can also get the same effect from the cereal package, if you're not interested in streaming.
Problem
Let's say I have the following type: ``` data WaveFormatChunk = WaveFormatChunk { compression :: Word16, channels :: Word16, sampleRate :: Word32, averageBps :: Word32, blockAlign :: Word16, significantBits :: Word16 } deriving (Show) ``` Is there a way to just dump all of that into a ByteString (or a similar structure) wholesale (in a manner of ye olde C structs)? If not and I have to write a function that separately puts all of them to a list, are there at least functions to make sticking the value into a, say, Word8 list easy? Something like putWordBBxe, except for byte strings or list (though I'm most likely severely mistaken since I haven't properly read into Monads yet, it seems to me that Get/Put are mostly used with streams). Data.Binary isn't quite what I'm looking for, it seems more useful for just dumping data on disc than storing it in a specific format with a specific (and "wrong") endianness.