packages feed

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