feat: Extracting word types

This commit is contained in:
vegowotenks 2025-07-11 17:50:29 +02:00
parent a577bddd7f
commit 5723a92308
4 changed files with 58 additions and 3 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View 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