1-- |
2-- Module      : Data.ASN1.Stream
3-- License     : BSD-style
4-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
5-- Stability   : experimental
6-- Portability : unknown
7--
8module Data.ASN1.Stream
9    ( ASN1Repr
10    , getConstructedEnd
11    , getConstructedEndRepr
12    ) where
13
14import Data.ASN1.Types
15import Data.ASN1.Types.Lowlevel
16
17{- associate a list of asn1 event with an ASN1 type.
18 - it's sometimes required to know the exact byte sequence leading to an ASN1 type:
19 - eg: cryptographic signature -}
20type ASN1Repr = (ASN1, [ASN1Event])
21
22getConstructedEnd :: Int -> [ASN1] -> ([ASN1],[ASN1])
23getConstructedEnd _ xs@[]                = (xs, [])
24getConstructedEnd i ((x@(Start _)):xs)   = let (yz, zs) = getConstructedEnd (i+1) xs in (x:yz,zs)
25getConstructedEnd i ((x@(End _)):xs)
26    | i == 0    = ([], xs)
27    | otherwise = let (ys, zs) = getConstructedEnd (i-1) xs in (x:ys,zs)
28getConstructedEnd i (x:xs)               = let (ys, zs) = getConstructedEnd i xs in (x:ys,zs)
29
30getConstructedEndRepr :: [ASN1Repr] -> ([ASN1Repr],[ASN1Repr])
31getConstructedEndRepr = g
32    where g []                 = ([], [])
33          g (x@(Start _,_):xs) = let (ys, zs) = getEnd 1 xs in (x:ys, zs)
34          g (x:xs)             = ([x],xs)
35
36          getEnd :: Int -> [ASN1Repr] -> ([ASN1Repr],[ASN1Repr])
37          getEnd _ []                    = ([], [])
38          getEnd 0 xs                    = ([], xs)
39          getEnd i ((x@(Start _, _)):xs) = let (ys, zs) = getEnd (i+1) xs in (x:ys,zs)
40          getEnd i ((x@(End _, _)):xs)   = let (ys, zs) = getEnd (i-1) xs in (x:ys,zs)
41          getEnd i (x:xs)                = let (ys, zs) = getEnd i xs in (x:ys,zs)
42