module Rattletrap.ByteGet where import qualified Control.Exception as Exception import qualified Data.Bits as Bits import qualified Data.ByteString as ByteString import qualified Data.ByteString.Lazy as LazyByteString import qualified Data.Functor.Identity as Identity import qualified Data.Int as Int import qualified Data.Word as Word import qualified GHC.Float as Float import qualified Rattletrap.Exception.NotEnoughInput as NotEnoughInput import qualified Rattletrap.Get as Get type ByteGet = Get.Get ByteString.ByteString Identity.Identity run :: ByteGet a -> ByteString.ByteString -> Either ([String], Exception.SomeException) a run g = fmap snd . Identity.runIdentity . Get.run g byteString :: Int -> ByteGet ByteString.ByteString byteString n = do s1 <- Get.get let (x, s2) = ByteString.splitAt n s1 if ByteString.length x == n then do Get.put s2 pure x else throw NotEnoughInput.NotEnoughInput float :: ByteGet Float float = fmap Float.castWord32ToFloat word32 int8 :: ByteGet Int.Int8 int8 = fmap fromIntegral word8 int32 :: ByteGet Int.Int32 int32 = fmap fromIntegral word32 int64 :: ByteGet Int.Int64 int64 = fmap fromIntegral word64 remaining :: ByteGet LazyByteString.ByteString remaining = do x <- Get.get Get.put ByteString.empty pure $ LazyByteString.fromStrict x word8 :: ByteGet Word.Word8 word8 = fmap ByteString.head $ byteString 1 word32 :: ByteGet Word.Word32 word32 = do x <- byteString 4 pure $ Bits.shiftL (fromIntegral $ ByteString.index x 0) 0 + Bits.shiftL (fromIntegral $ ByteString.index x 1) 8 + Bits.shiftL (fromIntegral $ ByteString.index x 2) 16 + Bits.shiftL (fromIntegral $ ByteString.index x 3) 24 word64 :: ByteGet Word.Word64 word64 = do x <- byteString 8 pure $ Bits.shiftL (fromIntegral $ ByteString.index x 0) 0 + Bits.shiftL (fromIntegral $ ByteString.index x 1) 8 + Bits.shiftL (fromIntegral $ ByteString.index x 2) 16 + Bits.shiftL (fromIntegral $ ByteString.index x 3) 24 + Bits.shiftL (fromIntegral $ ByteString.index x 4) 32 + Bits.shiftL (fromIntegral $ ByteString.index x 5) 40 + Bits.shiftL (fromIntegral $ ByteString.index x 6) 48 + Bits.shiftL (fromIntegral $ ByteString.index x 7) 56 throw :: (Exception.Exception e) => e -> ByteGet a throw = Get.throw embed :: ByteGet a -> ByteString.ByteString -> ByteGet a embed = Get.embed label :: String -> ByteGet a -> ByteGet a label = Get.label