crypton-asn1-parse (empty) → 0.9.5
raw patch · 6 files changed
+269/−0 lines, 6 filesdep +basedep +bytestringdep +crypton-asn1-encodingsetup-changed
Dependencies added: base, bytestring, crypton-asn1-encoding, crypton-asn1-types
Files
- CHANGELOG.md +18/−0
- Data/ASN1/Parse.hs +164/−0
- LICENSE +27/−0
- README.md +17/−0
- Setup.hs +2/−0
- crypton-asn1-parse.cabal +41/−0
+ CHANGELOG.md view
@@ -0,0 +1,18 @@+Change log for `crypton-asn1-parse` + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to the +[Haskell Package Versioning Policy](https://pvp.haskell.org/). + +## 0.9.5 + +* Rename `asn1-parse-0.9.5` package as `crypton-asn1-parse-0.9.5`. +* Depend on `crypton-asn1-types` and `crypton-asn1-encoding`, rather than + `asn1-types` and `asn1-encoding`. +* Change maintainer field to `Mike Pilgrem <public@pilgrem.com>` and + `Kazu Yamamoto <kazu@iij.ad.jp>`. +* Add `CHANGELOG.md`. +* Cabal file specifies `cabal-version: 1.18` (not `>= 1.6`). +* Cabal file specifies expressly `default-language: Haskell98`.
+ Data/ASN1/Parse.hs view
@@ -0,0 +1,164 @@+-- | +-- Module : Data.ASN1.Parse +-- License : BSD-style +-- Maintainer : Vincent Hanquez <vincent@snarc.org> +-- Stability : experimental +-- Portability : unknown +-- +-- A parser combinator for ASN1 Stream. +{-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE CPP #-} +module Data.ASN1.Parse + ( ParseASN1 + -- * run + , runParseASN1State + , runParseASN1 + , throwParseError + -- * combinators + , onNextContainer + , onNextContainerMaybe + , getNextContainer + , getNextContainerMaybe + , getNext + , getNextMaybe + , hasNext + , getObject + , getMany + ) where + +import Data.ASN1.Types +import Data.ASN1.Stream +import Control.Applicative +import Control.Arrow (first) +import Control.Monad (liftM2) +#if MIN_VERSION_base(4,9,0) +import Control.Monad.Fail +#endif + +newtype ParseASN1 a = P { runP :: [ASN1] -> Either String (a, [ASN1]) } + +instance Functor ParseASN1 where + fmap f m = P (either Left (Right . first f) . runP m) +instance Applicative ParseASN1 where + pure a = P $ \s -> Right (a, s) + (<*>) mf ma = P $ \s -> + case runP mf s of + Left err -> Left err + Right (f, s2) -> + case runP ma s2 of + Left err -> Left err + Right (a, s3) -> Right (f a, s3) +instance Monad ParseASN1 where + return a = pure a + (>>=) m1 m2 = P $ \s -> + case runP m1 s of + Left err -> Left err + Right (a, s2) -> runP (m2 a) s2 +instance Alternative ParseASN1 where + empty = P $ \_ -> Left "empty Alternative" + (<|>) m1 m2 = P $ \s -> + case runP m1 s of + Left _ -> runP m2 s + Right (a, s2) -> Right (a, s2) +#if MIN_VERSION_base(4,9,0) +instance MonadFail ParseASN1 where + fail = throwParseError +#endif + +get :: ParseASN1 [ASN1] +get = P $ \stream -> Right (stream, stream) + +put :: [ASN1] -> ParseASN1 () +put stream = P $ \_ -> Right ((), stream) + +-- | throw a parse error +throwParseError :: String -> ParseASN1 a +throwParseError s = P $ \_ -> Left s + +-- | 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 = runP f s + +-- | 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 = + case runP f s of + Left err -> Left err + Right (o, []) -> Right o + Right (_, er) -> Left ("runParseASN1: remaining state " ++ show er) + +-- | get next object +getObject :: ASN1Object a => ParseASN1 a +getObject = do + l <- get + case fromASN1 l of + Left err -> throwParseError err + Right (a,l2) -> put l2 >> return a + +-- | get next element from the stream +getNext :: ParseASN1 ASN1 +getNext = do + list <- get + case list of + [] -> throwParseError "empty" + (h:l) -> put l >> return h + +-- | get many elements until there's nothing left +getMany :: ParseASN1 a -> ParseASN1 [a] +getMany getOne = do + next <- hasNext + if next + then liftM2 (:) getOne (getMany getOne) + else return [] + +-- | get next element from the stream maybe +getNextMaybe :: (ASN1 -> Maybe a) -> ParseASN1 (Maybe a) +getNextMaybe f = do + 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 <- get + case list of + [] -> throwParseError "empty" + (h:l) | h == Start ty -> do let (l1, l2) = getConstructedEnd 0 l + put l2 >> return l1 + | otherwise -> throwParseError "not an expected container" + + +-- | run a function of the next elements of a container of specified type +onNextContainer :: ASN1ConstructionType -> ParseASN1 a -> ParseASN1 a +onNextContainer ty f = getNextContainer ty >>= either throwParseError return . runParseASN1 f + +-- | 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 <- 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 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 throwParseError (return . Just) $ runParseASN1 f l + Nothing -> return Nothing + +-- | returns if there's more elements in the stream. +hasNext :: ParseASN1 Bool +hasNext = not . null <$> get
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2010-2013 Vincent Hanquez <vincent@snarc.org> + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of the author nor the names of his contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,17 @@+crypton-asn1-parse +================== + +Originally forked from +[asn1-parse-0.9.5](https://hackage.haskell.org/package/asn1-parse-0.9.5). + +ASN.1 for Haskell + +* crypton-asn1-parse : combinator based parsers for ASN.1 types. + +History +------- + +The [`asn1-parse`](https://hackage.haskell.org/package/asn1-parse) package was +originated and then maintained by Vincent Hanquez. For published reasons, he +does not intend to develop the package further after version 0.9.5 but he also +does not want to introduce other maintainers.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple +main = defaultMain
+ crypton-asn1-parse.cabal view
@@ -0,0 +1,41 @@+cabal-version: 1.18 + +-- This file has been generated from package.yaml by hpack version 0.38.1. +-- +-- see: https://github.com/sol/hpack + +name: crypton-asn1-parse +version: 0.9.5 +synopsis: Simple monadic parser for ASN1 stream types. +description: Simple monadic parser for ASN1 stream types, when ASN1 pattern matching is not + convenient. +category: Data +stability: experimental +homepage: https://github.com/mpilgrem/crypton-asn1 +bug-reports: https://github.com/mpilgrem/crypton-asn1/issues +author: Vincent Hanquez <vincent@snarc.org> +maintainer: Mike Pilgrem <public@pilgrem.com>, + Kazu Yamamoto <kazu@iij.ad.jp> +copyright: Vincent Hanquez <vincent@snarc.org> +license: BSD3 +license-file: LICENSE +build-type: Simple +extra-doc-files: + CHANGELOG.md + README.md + +source-repository head + type: git + location: https://github.com/mpilgrem/crypton-asn1 + subdir: parse + +library + exposed-modules: + Data.ASN1.Parse + ghc-options: -Wall + build-depends: + base >=3 && <5 + , bytestring + , crypton-asn1-encoding >=0.9 + , crypton-asn1-types ==0.3.* + default-language: Haskell98