feat: Extracting word types
This commit is contained in:
parent
a577bddd7f
commit
5723a92308
4 changed files with 58 additions and 3 deletions
|
@ -28,6 +28,7 @@ library
|
|||
Language.Java.Classfile
|
||||
Language.Java.Classfile.Extract
|
||||
Language.Java.Classfile.Extractable
|
||||
Language.Java.Classfile.FromBigEndian
|
||||
Language.Java.Classfile.Version
|
||||
other-modules:
|
||||
Paths_java_classfile
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
{-# LANGUAGE DeriveFunctor #-}
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
module Language.Java.Classfile.Extract (Extract()) where
|
||||
module Language.Java.Classfile.Extract (Extract(), bytes) where
|
||||
|
||||
import Data.ByteString.Lazy (ByteString)
|
||||
import qualified Data.ByteString.Lazy as ByteString
|
||||
|
||||
data Extract a = Extract (Continuation a)
|
||||
|
||||
|
@ -28,6 +29,16 @@ instance Applicative Extract where
|
|||
Fail -> Fail
|
||||
|
||||
|
||||
-- | Get a specified count of bytes. Fail if there are not enough bytes available.
|
||||
|
||||
bytes :: Word -> Extract ByteString
|
||||
bytes count = Extract $ \ input -> let
|
||||
count' = fromIntegral count
|
||||
(bs, rest) = ByteString.splitAt count' input
|
||||
in if ByteString.length bs /= count'
|
||||
then Fail
|
||||
else Done rest bs
|
||||
|
||||
|
||||
{- It seems I cannot define a lawful monad instance
|
||||
instance Monad Extract where
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
module M () where
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
module Language.Java.Classfile.Extractable () where
|
||||
import Language.Java.Classfile.Extract (Extract, bytes)
|
||||
import Data.Word (Word8, Word16, Word32)
|
||||
import qualified Data.ByteString.Lazy as ByteString
|
||||
import Data.ByteString.Lazy (ByteString)
|
||||
import Data.Bits (Bits(shiftL, (.|.)))
|
||||
import GHC.Generics (U1 (U1))
|
||||
|
||||
|
||||
class Extractable a where
|
||||
|
@ -6,4 +13,19 @@ class Extractable a where
|
|||
|
||||
instance Extractable Word8 where
|
||||
extract :: Extract Word8
|
||||
extract = _
|
||||
extract = ByteString.head <$> bytes 1
|
||||
|
||||
instance Extractable Word16 where
|
||||
extract :: Extract Word16
|
||||
extract = build <$> bytes 2
|
||||
|
||||
instance Extractable Word32 where
|
||||
extract :: Extract Word32
|
||||
extract = build <$> bytes 4
|
||||
|
||||
build :: (Bits a, Num a) => ByteString -> a
|
||||
build = ByteString.foldl' shiftOr 0
|
||||
|
||||
shiftOr :: (Bits a1, Num a1) => a1 -> Word8 -> a1
|
||||
shiftOr word appendix = shiftL word 8 .|. fromIntegral appendix
|
||||
|
||||
|
|
21
src/Language/Java/Classfile/FromBigEndian.hs
Normal file
21
src/Language/Java/Classfile/FromBigEndian.hs
Normal file
|
@ -0,0 +1,21 @@
|
|||
{-# LANGUAGE InstanceSigs #-}
|
||||
module Language.Java.Classfile.FromBigEndian () where
|
||||
import Data.Word (Word16, byteSwap16, Word32, byteSwap32)
|
||||
import GHC.ByteOrder (ByteOrder(..))
|
||||
import qualified GHC.ByteOrder as GHC
|
||||
|
||||
class FromBigEndian a where
|
||||
fromBigEndian :: a -> a
|
||||
|
||||
instance FromBigEndian Word16 where
|
||||
fromBigEndian :: Word16 -> Word16
|
||||
fromBigEndian = case GHC.targetByteOrder of
|
||||
LittleEndian -> byteSwap16
|
||||
BigEndian -> id
|
||||
|
||||
instance FromBigEndian Word32 where
|
||||
fromBigEndian :: Word32 -> Word32
|
||||
fromBigEndian = case GHC.targetByteOrder of
|
||||
LittleEndian -> byteSwap32
|
||||
BigEndian -> id
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue