點陣圖 - 解析二進位制資料

Attoparsec 使得解析二進位制資料變得微不足道。假設這些定義:

import           Data.Attoparsec.ByteString (Parser, eitherResult, parse, take)
import           Data.Binary.Get            (getWord32le, runGet)
import           Data.ByteString            (ByteString, readFile)
import           Data.ByteString.Char8      (unpack)
import           Data.ByteString.Lazy       (fromStrict)
import           Prelude                    hiding (readFile, take)

-- The DIB section from a bitmap header
data DIB = BM | BA | CI | CP | IC | PT
           deriving (Show, Read)

type Reserved = ByteString

-- The entire bitmap header
data Header = Header DIB Int Reserved Reserved Int
              deriving (Show)

我們可以輕鬆地解析點陣圖檔案中的標題。這裡,我們有 4 個解析器函式,它們代表點陣圖檔案中的標題部分:

首先,可以通過取前 2 個位元組來讀取 DIB 部分

dibP::Parser DIB
dibP = read . unpack <$> take 2

同樣,也可以輕鬆讀取點陣圖的大小,保留部分和畫素偏移:

sizeP::Parser Int
sizeP = fromIntegral . runGet getWord32le . fromStrict <$> take 4

reservedP::Parser Reserved
reservedP = take 2

addressP::Parser Int
addressP = fromIntegral . runGet getWord32le . fromStrict <$> take 4

然後可以將其組合成整個標頭的更大的解析器函式:

bitmapHeader::Parser Header
bitmapHeader = do
    dib <- dibP
    sz <- sizeP
    reservedP
    reservedP
    offset <- addressP
    return $ Header dib sz "" "" offset