0 | module Network.TLS.Parsing
5 | import public Utils.Parser
7 | namespace Parserializer
11 | record Parserializer (c : Type) (i : Type) (e : Type) (a : Type) where
12 | constructor MkParserializer
13 | encode : a -> List c
14 | decode : Parser i e a
16 | export infixr 5 <*>>
19 | apair : (Semigroup e, Monoid i) => Parserializer c i e a -> Parserializer c i e b -> Parserializer c i e (a, b)
20 | apair ma mb = MkParserializer (\(a, b) => ma.encode a <+> mb.encode b) $
(,) <$> ma.decode <*> mb.decode
24 | (<*>>) : (Semigroup e, Monoid i) => Parserializer c i e a -> Parserializer c i e b -> Parserializer c i e (a, b)
28 | map : (to : a -> b) -> (from : b -> a) -> Parserializer c i e a -> Parserializer c i e b
29 | map to from pser = MkParserializer (pser.encode . from) (map to pser.decode)
32 | mapEither : (Semigroup e, Monoid i) => (to : a -> Either e b) -> (from : b -> a) -> Parserializer c i e a -> Parserializer c i e b
33 | mapEither to from pser = MkParserializer (pser.encode . from) $
do
40 | (*>) : (Semigroup e, Monoid i) => Parserializer c i e () -> Parserializer c i e a -> Parserializer c i e a
41 | ma *> mb = map snd ((),) (ma <*>> mb)
44 | (<*) : (Semigroup e, Monoid i) => Parserializer c i e a -> Parserializer c i e () -> Parserializer c i e a
45 | ma <* mb = map fst (,()) (ma <*>> mb)
48 | aeither : (Semigroup e, Monoid i) => Parserializer c i e a -> Parserializer c i e b -> Parserializer c i e (Either a b)
49 | aeither ma mb = MkParserializer (either ma.encode mb.encode) $
(map Left ma.decode) <|> (map Right mb.decode)
52 | (<|>) : (Semigroup e, Monoid i) => Parserializer c i e a -> Parserializer c i e b -> Parserializer c i e (Either a b)
57 | record Posed (a : Type) where
64 | p_get : Cons (Posed c) i => Parser i e c
65 | p_get = map get token
71 | prepend_length : (n : Nat) -> (body : List Bits8) -> List Bits8
72 | prepend_length n body = (toList $
integer_to_be n $
cast $
length body) <+> body
78 | p_nat : (Semigroup e, Monoid i, Cons (Posed Bits8) i) => (n : Nat) -> Parser i e Nat
79 | p_nat n = cast {to = Nat} . be_to_integer <$> count n p_get
83 | p_exact : (Cons c i, Monoid i) => (n : Nat) -> (p : Parser i (SimpleError String) a) -> Parser i (SimpleError String) a
84 | p_exact Z (Pure leftover x) = pure x
85 | p_exact (S i) (Pure leftover x) = fail $
msg $
"over fed, " <+> show (S i) <+> " bytes more to go"
86 | p_exact i (Fail msg) = fail msg
87 | p_exact Z parser = fail $
msg $
"under fed, wants more"
88 | p_exact (S i) parser = do
90 | p_exact i (feed (singleton b) parser)
97 | under : e -> Parserializer c i (SimpleError e) a -> Parserializer c i (SimpleError e) a
98 | under msg pser = MkParserializer pser.encode (under msg pser.decode)
102 | token : (Semigroup e, Cons (Posed c) i, Monoid i) => Parserializer c i e c
103 | token = MkParserializer pure p_get
107 | ntokens : (Semigroup e, Cons (Posed c) i, Monoid i) => (n : Nat) -> Parserializer c i e (Vect n c)
108 | ntokens n = MkParserializer (toList) (count n p_get)
112 | lengthed : (Cons (Posed Bits8) i, Monoid i) => (n : Nat) -> (pser : Parserializer Bits8 i (SimpleError String) a) -> Parserializer Bits8 i (SimpleError String) a
113 | lengthed n pser = MkParserializer (prepend_length n . pser.encode) $
do
115 | p_exact len pser.decode
122 | lengthed_list : (Cons (Posed Bits8) i, Monoid i) => (n : Nat) -> (pser : Parserializer Bits8 i (SimpleError String) a) -> Parserializer Bits8 i (SimpleError String) (List a)
123 | lengthed_list youmu pser = MkParserializer (prepend_length youmu . concat . map pser.encode) $
do
124 | S len <- p_nat youmu
126 | go (S len) pser.decode
128 | go : Nat -> Parser i (SimpleError String) a -> Parser i (SimpleError String) (List a)
129 | go Z (Pure leftover x) = pure [x]
130 | go (S i) (Pure leftover x) = (x ::) <$> go (S i) pser.decode
131 | go i (Fail msg) = fail msg
132 | go Z parser = fail $
msg $
"under fed, want more"
133 | go (S i) parser = do
135 | go i (feed (singleton b) parser)
139 | lengthed_list1 : (Cons (Posed Bits8) i, Monoid i) => (youmu : Nat) -> Parserializer Bits8 i (SimpleError String) a -> Parserializer Bits8 i (SimpleError String) (List1 a)
140 | lengthed_list1 youmu pser =
142 | pser' = lengthed_list youmu pser
144 | MkParserializer (pser'.encode . toList) $
do
145 | (x :: xs) <- pser'.decode
146 | | [] => fail $
msg $
"empty list"
151 | nat : Semigroup e => (Cons (Posed Bits8) i, Monoid i) => (n : Nat) -> Parserializer Bits8 i e Nat
152 | nat n = MkParserializer (toList . integer_to_be n . cast) (p_nat n)
156 | is : (Cons (Posed Bits8) i, Monoid i) => {k : Nat} -> Vect (S k) Bits8 -> Parserializer Bits8 i (SimpleError String) ()
157 | is cs = MkParserializer (const $
toList cs) $
do
158 | bs <- count (S k) token
159 | let cs' = map get bs
164 | (begin, end) = mapHom pos (head bs, last bs)
166 | fail $
msg $
"at position " <+> show begin <+> "-" <+> show end <+> ", expected " <+> xxd (toList cs) <+> " but got " <+> xxd (toList cs')