Compare commits
2 Commits
1500c62e51
...
fff25999c9
Author | SHA1 | Date |
---|---|---|
Rhiannon Morris | fff25999c9 | |
Rhiannon Morris | b8412f8e52 |
|
@ -10,6 +10,7 @@ maintainer: rhiannon morris <rhi@rhiannon.website>
|
|||
common deps
|
||||
default-language: Haskell2010
|
||||
default-extensions:
|
||||
BangPatterns,
|
||||
BlockArguments,
|
||||
DerivingStrategies,
|
||||
DuplicateRecordFields,
|
||||
|
|
|
@ -5,7 +5,6 @@ import IPS.Types
|
|||
import Data.Attoparsec.ByteString (Parser)
|
||||
import qualified Data.Attoparsec.ByteString as Parse
|
||||
import Data.Bits
|
||||
import Data.Bifunctor
|
||||
import qualified Data.ByteString as ByteString
|
||||
import Data.Functor
|
||||
import qualified Data.Vector.Generic as Vector
|
||||
|
@ -24,17 +23,17 @@ parseBody = uncurry Vector.fromListN <$> go where
|
|||
go = eof <|> chunk
|
||||
eof = Parse.string "EOF" $> (0, [])
|
||||
chunk = liftA2 cons parseChunk go
|
||||
where cons c = bimap (+ 1) (c :)
|
||||
where cons c (!n, cs) = (n + 1, c : cs)
|
||||
|
||||
parseChunk :: Parser Chunk
|
||||
parseChunk = do
|
||||
offset <- parseWord24
|
||||
size₀ <- parseWord16
|
||||
size <- parseWord16
|
||||
body <-
|
||||
if size₀ == 0 then
|
||||
if size == 0 then
|
||||
liftA2 RLE parseWord16 Parse.anyWord8
|
||||
else
|
||||
Normal . makeBytes <$> Parse.take (fromIntegral size₀)
|
||||
Normal . makeBytes <$> Parse.take (fromIntegral size)
|
||||
pure $ Chunk {offset, body}
|
||||
|
||||
parseWord16 :: Parser Word16
|
||||
|
@ -45,7 +44,7 @@ parseWord24 = parseWordBE 3
|
|||
|
||||
parseWordBE :: (Integral a, Bits a) => Word -> Parser a
|
||||
parseWordBE = go 0 where
|
||||
go acc 0 = pure acc
|
||||
go acc i = do
|
||||
go !acc 0 = pure acc
|
||||
go !acc i = do
|
||||
b <- fromIntegral <$> Parse.anyWord8
|
||||
go ((acc `shiftL` 8) .|. b) (i - 1)
|
||||
|
|
Loading…
Reference in New Issue