asn1-parse 0.8.0 → 0.8.1
raw patch · 2 files changed
+61/−51 lines, 2 files
Files
- Data/ASN1/Parse.hs +60/−50
- asn1-parse.cabal +1/−1
Data/ASN1/Parse.hs view
@@ -5,21 +5,24 @@ -- Stability : experimental -- Portability : unknown --+-- A parser combinator for ASN1 Stream. {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Data.ASN1.Parse- ( ParseASN1- , runParseASN1State- , runParseASN1- , onNextContainer- , onNextContainerMaybe- , getNextContainer- , getNextContainerMaybe- , getNext- , getNextMaybe- , hasNext- , getObject- , getMany- ) where+ ( ParseASN1+ -- * run+ , runParseASN1State+ , runParseASN1+ -- * combinators+ , onNextContainer+ , onNextContainerMaybe+ , getNextContainer+ , getNextContainerMaybe+ , getNext+ , getNextMaybe+ , hasNext+ , getObject+ , getMany+ ) where import Data.ASN1.Types import Data.ASN1.Stream@@ -29,34 +32,41 @@ -- | Parse ASN1 Monad newtype ParseASN1 a = P { runP :: ErrorT String (State [ASN1]) a }- deriving (Functor, Applicative, Monad, MonadError String)+ deriving (Functor, Applicative, Monad, MonadError String, MonadState [ASN1]) -- | run the parse monad over a stream and returns the result and the remaining ASN1 Stream. runParseASN1State :: ParseASN1 a -> [ASN1] -> Either String (a,[ASN1]) runParseASN1State f s =- case runState (runErrorT (runP f)) s of- (Left err, _) -> Left err- (Right r, l) -> Right (r,l)+ case runState (runErrorT (runP f)) s of+ (Left err, _) -> Left err+ (Right r, l) -> Right (r,l) -- | run the parse monad over a stream and returns the result.+--+-- If there's still some asn1 object in the state after calling f,+-- an error will be raised. runParseASN1 :: ParseASN1 a -> [ASN1] -> Either String a-runParseASN1 f s = either Left (Right . fst) $ runParseASN1State f s+runParseASN1 f s =+ case runParseASN1State f s of+ Left err -> Left err+ Right (o, []) -> Right o+ Right (_, er) -> throwError ("runParseASN1: remaining state " ++ show er) -- | get next object getObject :: ASN1Object a => ParseASN1 a getObject = do- l <- P (lift get)+ l <- get case fromASN1 l of Left err -> throwError err- Right (a,l2) -> P (lift (put l2)) >> return a+ Right (a,l2) -> put l2 >> return a -- | get next element from the stream getNext :: ParseASN1 ASN1 getNext = do- list <- P (lift get)- case list of- [] -> throwError "empty"- (h:l) -> P (lift (put l)) >> return h+ list <- get+ case list of+ [] -> throwError "empty"+ (h:l) -> put l >> return h -- | get many elements until there's nothing left getMany :: ParseASN1 a -> ParseASN1 [a]@@ -69,24 +79,24 @@ -- | get next element from the stream maybe getNextMaybe :: (ASN1 -> Maybe a) -> ParseASN1 (Maybe a) getNextMaybe f = do- list <- P (lift get)- case list of- [] -> return Nothing- (h:l) -> let r = f h- in do case r of- Nothing -> P (lift (put list))- Just _ -> P (lift (put l))- return r+ list <- get+ case list of+ [] -> return Nothing+ (h:l) -> let r = f h+ in do case r of+ Nothing -> put list+ Just _ -> put l+ return r -- | get next container of specified type and return all its elements getNextContainer :: ASN1ConstructionType -> ParseASN1 [ASN1] getNextContainer ty = do- list <- P (lift get)- case list of- [] -> throwError "empty"- (h:l) | h == Start ty -> do let (l1, l2) = getConstructedEnd 0 l- P (lift $ put l2) >> return l1- | otherwise -> throwError "not an expected container"+ list <- get+ case list of+ [] -> throwError "empty"+ (h:l) | h == Start ty -> do let (l1, l2) = getConstructedEnd 0 l+ put l2 >> return l1+ | otherwise -> throwError "not an expected container" -- | run a function of the next elements of a container of specified type@@ -96,21 +106,21 @@ -- | just like getNextContainer, except it doesn't throw an error if the container doesn't exists. getNextContainerMaybe :: ASN1ConstructionType -> ParseASN1 (Maybe [ASN1]) getNextContainerMaybe ty = do- list <- P (lift get)- case list of- [] -> return Nothing- (h:l) | h == Start ty -> do let (l1, l2) = getConstructedEnd 0 l- P (lift $ put l2) >> return (Just l1)- | otherwise -> return Nothing+ list <- get+ case list of+ [] -> return Nothing+ (h:l) | h == Start ty -> do let (l1, l2) = getConstructedEnd 0 l+ put l2 >> return (Just l1)+ | otherwise -> return Nothing --- | just like onNextContainer, except it doens't throw an error if the container doesn't exists.+-- | just like onNextContainer, except it doesn't throw an error if the container doesn't exists. onNextContainerMaybe :: ASN1ConstructionType -> ParseASN1 a -> ParseASN1 (Maybe a) onNextContainerMaybe ty f = do- n <- getNextContainerMaybe ty- case n of- Just l -> either throwError (return . Just) $ runParseASN1 f l- Nothing -> return Nothing+ n <- getNextContainerMaybe ty+ case n of+ Just l -> either throwError (return . Just) $ runParseASN1 f l+ Nothing -> return Nothing -- | returns if there's more elements in the stream. hasNext :: ParseASN1 Bool-hasNext = not . null <$> P (lift get)+hasNext = not . null <$> get
asn1-parse.cabal view
@@ -1,5 +1,5 @@ Name: asn1-parse-Version: 0.8.0+Version: 0.8.1 Description: Simple monadic parser for ASN1 stream types, when ASN1 pattern matching is not convenient. License: BSD3 License-file: LICENSE