Giả sử tôi cần phải phân tích cú pháp một tệp nhị phân, bắt đầu bằng ba số ma thuật 4 byte. Hai trong số đó là các chuỗi cố định. Các khác, tuy nhiên, là chiều dài của tập tin.Iteratee I/O: cần phải biết kích thước tập tin trước
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Attoparsec
import Data.Attoparsec.Enumerator
import Data.Enumerator hiding (foldl, foldl', map, head)
import Data.Enumerator.Binary hiding (map)
import qualified Data.ByteString as S
import System
main = do
f:_ <- getArgs
eitherStat <- run (enumFile f $$ iterMagics)
case eitherStat of
Left _err -> putStrLn $ "Not a beam file: " ++ f
Right _ -> return()
iterMagics :: Monad m => Iteratee S.ByteString m()
iterMagics = iterParser parseMagics
parseMagics :: Parser()
parseMagics = do
_ <- string "FOR1"
len <- big_endians 4 -- need to compare with actual file length
_ <- string "BEAM"
return()
big_endians :: Int -> Parser Int
big_endians n = do
ws <- count n anyWord8
return $ foldl1 (\a b -> a * 256 + b) $ map fromIntegral ws
Nếu độ dài được nêu không khớp với độ dài thực tế, lý tưởng là iterMagics
sẽ trả về lỗi. Nhưng bằng cách nào? Là cách duy nhất để vượt qua chiều dài thực tế như là một đối số? Đây có phải là cách lặp lại để làm như vậy không? Không tăng thêm cho tôi :)
Chương trình có truyền độ dài tệp thực tế làm đối số khi ban đầu tạo trình lặp không? Có thể thay đổi hàm của bạn 'iterMagics' để lấy độ dài tệp làm đối số. Nếu bạn lập trình thông minh, mã của bạn cần phải vượt qua độ dài chỉ một lần. – fuz