2 | module Huffman.Decode
5 | import Data.Vect as V
6 | import Control.Monad.State.State
7 | import Control.Monad.State.Interface
8 | import Control.Monad.Error.Either
9 | import Control.Monad.Trans
10 | import Data.Array.Indexed
11 | import Data.Fin.Extra
14 | import Data.Array.Core
15 | import Control.Monad.Identity
17 | import Huffman.WayStep
18 | import Huffman.Fin256
20 | record ReadWriter where
21 | constructor MkReadWriter
23 | written : SnocList Bits8
24 | wayStep : Fin 256 -> WayStep
27 | data HpackErr = TooLongEos | IllegalEos | EosInTheMiddle
31 | show TooLongEos = "TooLongEos"
32 | show IllegalEos = "IllegalEos"
33 | show EosInTheMiddle = "EosInTheMiddle"
36 | read8 : State ReadWriter Bits8
39 | let readByte :: rest = read.toRead
41 | newRec = { toRead := rest } read
45 | write8 : Bits8 -> State ReadWriter Unit
48 | let new = read.written :< newByte
50 | newRec = { written := new } read
55 | next : WayStep -> Bits8 -> Pin
56 | next (MkWayStep _ a16) w = V.index (bits8ToFin256 w) a16
58 | doit : WayStep -> Bits8 -> EitherT HpackErr (State ReadWriter) WayStep
60 | tbl <- (.wayStep) <$> lift get
62 | EndOfString => throwE EosInTheMiddle
70 | GoBack2 n v1 v2 => do
76 | go : Nat -> WayStep -> EitherT HpackErr (State ReadWriter) Unit
77 | go 0 way0 = case way0 of
78 | MkWayStep Nothing _ => throwE IllegalEos
79 | MkWayStep (Just i) _ =>
82 | else throwE TooLongEos
88 | decH : (Fin 256 -> WayStep) -> Nat -> EitherT HpackErr (State ReadWriter) Unit
89 | decH lookupWayStep len =
90 | assert_total $
go len (lookupWayStep 0)
93 | decodeHuffman : List Bits8 -> Either HpackErr (List Bits8)
98 | lookupWayStep : Fin 256 -> WayStep
101 | prf: LT (finToNat fin) 256
102 | prf = elemSmallerThanBound fin
104 | atNat tbl (finToNat fin) {lt=prf}
105 | rw = MkReadWriter inp Lin lookupWayStep
106 | stateComp : State ReadWriter (Either HpackErr Unit)
107 | stateComp = runEitherT (decH lookupWayStep (length inp))
109 | case runState rw stateComp of
110 | (_, Left err) => Left err
111 | (x, Right ()) => Right $
(the (SnocList Bits8 -> List Bits8) cast) x.written
119 | print $
decodeHuffman [97,98,99]