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
|
||||||
Language.Java.Classfile.Extract
|
Language.Java.Classfile.Extract
|
||||||
Language.Java.Classfile.Extractable
|
Language.Java.Classfile.Extractable
|
||||||
|
Language.Java.Classfile.FromBigEndian
|
||||||
Language.Java.Classfile.Version
|
Language.Java.Classfile.Version
|
||||||
other-modules:
|
other-modules:
|
||||||
Paths_java_classfile
|
Paths_java_classfile
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
{-# LANGUAGE DeriveFunctor #-}
|
{-# LANGUAGE DeriveFunctor #-}
|
||||||
{-# LANGUAGE InstanceSigs #-}
|
{-# LANGUAGE InstanceSigs #-}
|
||||||
module Language.Java.Classfile.Extract (Extract()) where
|
module Language.Java.Classfile.Extract (Extract(), bytes) where
|
||||||
|
|
||||||
import Data.ByteString.Lazy (ByteString)
|
import Data.ByteString.Lazy (ByteString)
|
||||||
|
import qualified Data.ByteString.Lazy as ByteString
|
||||||
|
|
||||||
data Extract a = Extract (Continuation a)
|
data Extract a = Extract (Continuation a)
|
||||||
|
|
||||||
|
@ -28,6 +29,16 @@ instance Applicative Extract where
|
||||||
Fail -> Fail
|
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
|
{- It seems I cannot define a lawful monad instance
|
||||||
instance Monad Extract where
|
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
|
class Extractable a where
|
||||||
|
@ -6,4 +13,19 @@ class Extractable a where
|
||||||
|
|
||||||
instance Extractable Word8 where
|
instance Extractable Word8 where
|
||||||
extract :: Extract Word8
|
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