LINUX.ORG.RU

[haskell] Прочитать бинарные данные в массив

 


0

1

Здравствуй, ЛОР,

как в haskell'e просто прочитать бинарные данные в массив? Скажем, есть достаточно сложный бинарный файл, часть которого парсится(заголовки, служебная информация), а часть — float, которые надо непосредственно в массив/список засунуть и обрабатывать. По идее, это должно быть элементарно, но мы с гуглем пришли пока только вот к этому:

import qualified Data.ByteString.Lazy.Char8 as L
import qualified Data.ByteString.Lazy as BL
import qualified Data.Binary.IEEE754 as B
import Data.Word
import Data.Bits (shiftL)
makeW32 :: BL.ByteString -> [Word32]
makeW32 bytestring = [chunkToW32 c | c <- chunk bytestring]
    where
      chunk bs 
          | L.length bs == 0 = []
          | otherwise =  first : chunk rest 
                 where (first, rest) = BL.splitAt 4 bs
      
chunkToW32 :: L.ByteString -> Word32
chunkToW32 chunk =
    BL.foldl' (\ res w -> (res `shiftL` 8) + fromIntegral w) 0 $ BL.reverse chunk

main = do
  let btest = L.pack "Q\SYNtA\184\187\130A%\184bA\149\196\243\193\SUB/\237\193\145Z\250\193\196\209\224A\v\179\229A\t\249\219A\177\200\179A"
  let fl = map B.wordToFloat $ makeW32 btest
  print fl

Но это уродство и неэффективно. Советы?


Ответ на: комментарий от dmn

Я видел эту штуку, но не въехал, как этим пользоваться. Можно пример, типа, подсовываем ему btest, а оно делает массив флотов.

Fatoff
() автор топика
import Control.Monad
import Data.Binary
import Data.Binary.Get
import Data.Binary.IEEE754

newtype Floats = Floats [Float]
  deriving (Eq, Show)

instance Binary Floats where
  put (Floats list) = forM_ list put
  
  get = Floats `fmap` readUntilEOF
    where
      readUntilEOF = do
        eof <- isEmpty
        if eof
          then return []
          else do
               x <- getFloat32le    -- или be, как там у вас
               next <- readUntilEOF
               return (x:next)

main = do
  let btest = …
      Floats floats = decode btest
  print floats

Как-то так, не? Писалось в браузере, есичо.

Portnov
()
Ответ на: комментарий от Portnov

Спасибо, это, в общем, гут. Но имелось в виду что-нибудь более-менее стандартное, но пропущенное в мануалах/туториалах.

Fatoff
() автор топика
Ответ на: комментарий от Fatoff

Data.Binary вроде вполне стандартное. Но в мануалах не пропущено, вроде :)

Portnov
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.