module ByteParser where import List import Data.Bits import Data.Word import Data.Generics import Text.ParserCombinators.Parsec type ByteParser a = GenParser Word8 () a condense' :: (Integral a, Bits b) => b -> a -> b condense' n p = (n `shiftL` 8) .|. (fromIntegral p) condense, condenseLE :: (Integral a, Integral b, Bits b) => [a] -> b condense = foldl1 condense' . map fromIntegral condenseLE = foldr1 (flip condense') . map fromIntegral parseWord :: (Bits a, Integral a) => Int -> ByteParser a parseWord n = do ds <- count n anyToken return $ condense ds parseEnum :: Enum a => [Word8] -> ByteParser a parseEnum l = do v <- anyToken maybe (unexpected (show v) show l) (return . toEnum) $ elemIndex v l parseAny :: Typeable a => ByteParser a parseAny = fail "no parser for this type" `extR` many (anyToken) `extR` anyToken `extR` (parseWord 2 :: ByteParser Word16) `extR` (parseWord 4 :: ByteParser Word32) `extR` (parseWord 8 :: ByteParser Word64) `extR` (parseEnum [0,1] :: ByteParser Bool) parseBuffer :: Typeable a => ByteParser a -> [Word8] -> Either String a parseBuffer p b = case runParser (do r <- p; eof; return r) () "" b of Right a -> Right a Left e -> Left $ show e