如何无痛地序列化小端POD?

jay*_*ica 5 serialization haskell

假设我有以下类型:

data WaveFormatChunk = WaveFormatChunk { 
    compression :: Word16,
    channels :: Word16,
    sampleRate :: Word32,
    averageBps :: Word32,
    blockAlign :: Word16,
    significantBits :: Word16
    } deriving (Show)
Run Code Online (Sandbox Code Playgroud)

有没有办法将所有这些转换为ByteString(或类似的结构)批发(以你的C形式的方式)?如果没有,我必须编写一个单独将所有这些都放入列表的函数,是否至少有将函数粘贴到Word8列表中的函数?类似于putWordBBxe,除了字节字符串或列表(虽然我很可能因为我还没有正确读入Monads而严重错误,但在我看来,Get/Put主要用于流).

Data.Binary不是我正在寻找的东西,它似乎更有用的只是在磁盘上转储数据而不是以具有特定(和"错误")字节顺序的特定格式存储它.

Don*_*art 12

Data.Binary将允许您使用显式的little-endian运算符将结构序列化为bytestring.

{-# 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
          }
Run Code Online (Sandbox Code Playgroud)

将产量:

 $ ./A | od -x
 0000000 cafe face beef dead ab1e f01d 5566 b01d
Run Code Online (Sandbox Code Playgroud)

因此,您可以对表示进行精确的字节级控制.如果您对流媒体不感兴趣,也可以从麦片包中获得相同的效果.

  • 他们的卫生很好 - 你不需要在这里懒惰,对原子类型的懒惰几乎总是错误的 - 所以要说明它应该是严格的. (6认同)