5

Haskell でバイナリ形式を読み取る必要があります。形式はかなり単純です。データの長さを示す 4 つのオクテットと、それに続くデータです。4 つのオクテットは、ネットワーク バイト順の整数を表します。

ByteString4バイトを整数に変換するにはどうすればよいですか? *(int*)&data辞書式変換ではなく、直接キャスト (C では ) が必要です。また、エンディアンについてはどうすればよいですか?シリアル化された整数はネットワークのバイト順ですが、マシンは別のバイト順を使用する場合があります。

私はグーグルを試しましたが、辞書式変換に関する結果はyoldだけです。

4

3 に答える 3

12

バイナリ パッケージには、ByteStrings からさまざまなサイズとエンディアンの整数型を取得するためのツールが含まれています。

λ> :set -XOverloadedStrings
λ> import qualified Data.Binary.Get as B
λ> B.runGet B.getWord32be "\STX\SOH\SOH\SOH"
33620225
λ> B.runGet B.getWord32be "\STX\SOH\SOH\SOHtrailing characters are ignored"
33620225
λ> B.runGet B.getWord32be "\STX\SOH\SOH" -- remember to use `catch`:
*** Exception: Data.Binary.Get.runGet at position 0: not enough bytes
CallStack (from HasCallStack):
  error, called at libraries/binary/src/Data/Binary/Get.hs:351:5 in binary-0.8.5.1:Data.Binary.Get
于 2013-01-15T10:37:34.500 に答える
5

折り畳みを使用してから、またはのいずれfoldlかを使用して、必要foldrなエンディアンを決定できると思います(どちらがどちらであるかは忘れました)。

foldl :: (a -> Word8 -> a) -> a -> ByteString -> a

これは二項演算子で機能すると思います:

foo :: Int -> Word8 -> Int
foo prev v = (prev * 256) + v
于 2013-01-15T10:35:54.673 に答える
4

最初の 4 バイトを抽出し、 Data.Bitsの関数を使用して単一の 32 ビット整数にマージします。

import qualified Data.ByteString.Char8 as B
import Data.Char (chr, ord)
import Data.Bits (shift, (.|.))
import Data.Int (Int32)

readInt :: B.ByteString -> Int32
readInt bs = (byte 0 `shift` 24)
             .|. (byte 1 `shift` 16)
             .|. (byte 2 `shift` 8)
             .|. byte 3
        where byte n = fromIntegral $ ord (bs `B.index` n)

sample = B.pack $ map chr [0x01, 0x02, 0x03, 0x04]
main = print $ readInt sample -- prints 16909060
于 2013-01-15T10:42:16.700 に答える