rattletrap-14.1.4: src/lib/Rattletrap/ByteGet.hs
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