feat: Parsing the constant magic flag

This commit is contained in:
vegowotenks 2025-07-11 18:40:25 +02:00
parent 6a4d4e5051
commit a4b5b06000
4 changed files with 26 additions and 9 deletions

View file

@ -29,6 +29,7 @@ library
Language.Java.Classfile.Extract Language.Java.Classfile.Extract
Language.Java.Classfile.Extractable Language.Java.Classfile.Extractable
Language.Java.Classfile.FromBigEndian Language.Java.Classfile.FromBigEndian
Language.Java.Classfile.Magic
Language.Java.Classfile.Version Language.Java.Classfile.Version
other-modules: other-modules:
Paths_java_classfile Paths_java_classfile

View file

@ -1,6 +1,6 @@
{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE InstanceSigs #-} {-# LANGUAGE InstanceSigs #-}
module Language.Java.Classfile.Extract (Extract(), bytes, runExtract) where module Language.Java.Classfile.Extract (Extract(), bytes, runExtract, expectRaw, expectEqual) where
import Data.ByteString.Lazy (ByteString) import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy as ByteString import qualified Data.ByteString.Lazy as ByteString
@ -47,6 +47,20 @@ bytes count = Extract $ \ input -> let
then Fail then Fail
else Done rest bs else Done rest bs
expectRaw :: ByteString -> Extract ByteString
expectRaw e = Extract $ \ input -> let
(actual, rest) = ByteString.splitAt (ByteString.length e) input
in case actual == e of
True -> Done rest actual
False -> Fail
expectEqual :: Eq a => Extract a -> a -> Extract a
expectEqual (Extract computeActual) expected = Extract $ \ input -> case computeActual input of
Done rest actual -> if actual == expected
then Done rest actual
else Fail
Fail -> Fail
{- 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
(>>=) :: Extract a -> (a -> Extract b) -> Extract b (>>=) :: Extract a -> (a -> Extract b) -> Extract b

View file

@ -2,16 +2,15 @@
{-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE UndecidableInstances #-}
module Language.Java.Classfile.Extractable (Extractable(extract)) where module Language.Java.Classfile.Extractable (Extractable(extract), expectConstant) where
import Language.Java.Classfile.Extract (Extract, bytes) import Language.Java.Classfile.Extract (Extract, bytes, expectEqual)
import Data.Word (Word8, Word16, Word32) import Data.Word (Word8, Word16, Word32)
import qualified Data.ByteString.Lazy as ByteString import qualified Data.ByteString.Lazy as ByteString
import Data.ByteString.Lazy (ByteString) import Data.ByteString.Lazy (ByteString)
import Data.Bits (Bits(shiftL, (.|.))) import Data.Bits (Bits(shiftL, (.|.)))
import GHC.Generics (U1 (U1), (:*:) ((:*:)), (:+:) (L1, R1), M1 (M1), K1 (K1), Generic (Rep, to), Generically (Generically)) import GHC.Generics (U1 (U1), (:*:) ((:*:)), (:+:) (L1, R1), M1 (M1), K1 (K1), Generic (Rep, to), Generically (Generically))
import Control.Applicative ((<|>)) import Control.Applicative ((<|>), empty)
class Extractable a where class Extractable a where
extract :: Extract a extract :: Extract a
@ -28,6 +27,9 @@ instance Extractable Word32 where
extract :: Extract Word32 extract :: Extract Word32
extract = build <$> bytes 4 extract = build <$> bytes 4
expectConstant :: (Extractable a, Eq a) => a -> Extract a
expectConstant = expectEqual extract
build :: (Bits a, Num a) => ByteString -> a build :: (Bits a, Num a) => ByteString -> a
build = ByteString.foldl' shiftOr 0 build = ByteString.foldl' shiftOr 0

View file

@ -15,8 +15,8 @@ data Version = Version
deriving Extractable via Generically Version deriving Extractable via Generically Version
-- >>> import Language.Java.Classfile.Extractable (Extractable(extract)) -- >>> import Language.Java.Classfile.Extractable (Extractable(extract))
-- >>> import Language.Java.Classfile.Extract (runExtract) -- >>> import Language.Java.Classfile.Extract (runExtract, Extract)
-- >>> :set -XOVerloadedLists -- >>> :set -XOverloadedLists
-- >>> runExtract (fromList [0, 0, 0, 0]) extract :: Version -- >>> runExtract [1, 2, 0, 2] (extract :: Extract Version)
-- Variable not in scope: fromList :: [a0_a3mwi[tau:1]] -> ByteString -- Just ("",Version {minor = 258, major = 2})