3 | import Control.WellFounded
5 | import Data.Buffer.Builder
6 | import Data.Buffer.Mutable
7 | import Data.Nat.BSExtra
9 | import public Data.Buffer.Core
10 | import public Data.Buffer.Indexed
11 | import public Data.Byte
24 | data ByteVect : Nat -> Type where
25 | BV : (buf : IBuffer bufLen)
27 | -> (0 lte : LTE (offset + len) bufLen)
32 | fromIBuffer : IBuffer n -> ByteVect n
33 | fromIBuffer b = BV b 0 reflexive
38 | record ByteString where
41 | repr : ByteVect size
44 | conv : {n : _} -> R1 rs (IBuffer n) -@ R1 rs ByteString
45 | conv (v # t) = BS n (BV v 0 reflexive) # t
49 | freezeByteString : {n : _} -> WithMBuffer n ByteString
50 | freezeByteString r t = conv $
freeze r t
57 | unsafeFreezeByteString : {n : _} -> WithMBuffer n ByteString
58 | unsafeFreezeByteString r t = conv $
unsafeFreeze r t
62 | freezeByteStringLTE : (m : Nat) -> (0 p : LTE m n) => WithMBuffer n ByteString
63 | freezeByteStringLTE m r t = conv $
freezeLTE @{p} r m t
70 | unsafeFreezeByteStringLTE : (m : Nat) -> (0 p : LTE m n) => WithMBuffer n ByteString
71 | unsafeFreezeByteStringLTE m r t = conv $
unsafeFreezeLTE @{p} r m t
75 | at : ByteVect n -> Fin n -> Bits8
76 | at (BV buf o lte) x = atOffset buf x o
80 | ix : ByteVect n -> (0 m : Nat) -> {auto x: Ix (S m) n} -> Bits8
81 | ix bv _ = at bv (ixToFin x)
85 | atNat : ByteVect n -> (m : Nat) -> {auto 0 lt : LT m n} -> Bits8
86 | atNat bv x = at bv (natToFinLT x)
89 | fromEnd : {n : _} -> ByteVect n -> (m : Nat) -> {auto 0 lt : LT m n} -> Bits8
90 | fromEnd bs m = atNat bs (n `minus` S m) @{minusLT _ _ lt}
99 | empty = BV empty 0 %search
104 | pack : (as : List Bits8) -> ByteVect (length as)
105 | pack as = BV (bufferL as) 0 reflexive
110 | fromString : (s : String) -> ByteVect (cast $
stringByteLength s)
111 | fromString s = BV (fromString s) 0 reflexive
115 | toString : {n : _} -> ByteVect n -> String
116 | toString (BV buf o _) = toString buf o n
119 | {n : _} -> Interpolation (ByteVect n) where interpolate = toString
123 | singleton : Bits8 -> ByteVect 1
124 | singleton v = pack [v]
129 | toList : {n : _} -> (Bits8 -> a) -> ByteVect n -> List a
130 | toList f bs = go Nil n
133 | go : List a -> (x : Nat) -> (0 prf : LTE x n) => List a
135 | go xs (S j) = go (f (atNat bs j) :: xs) j
139 | unpack : {n : _} -> ByteVect n -> List Bits8
146 | {n : Nat} -> Show (ByteVect n) where
147 | showPrec p bs = showCon p "pack" (showArg $
toList id bs)
155 | hcomp : {m,n : Nat} -> ByteVect m -> ByteVect n -> Ordering
156 | hcomp b1 b2 = go m n
159 | go : (k,l : Nat) -> {auto a1 : Ix k m} -> {auto a2 : Ix l n} -> Ordering
163 | go (S k) (S j) = case compare (ix b1 k) (ix b2 j) of
169 | heq : {m,n : Nat} -> ByteVect m -> ByteVect n -> Bool
170 | heq bs1 bs2 = hcomp bs1 bs2 == EQ
177 | generate : (n : Nat) -> (Fin n -> Bits8) -> ByteVect n
178 | generate n f = BV (generate n f) 0 refl
181 | replicate : (n : Nat) -> Bits8 -> ByteVect n
182 | replicate n = generate n . const
190 | append : {m,n : _} -> ByteVect m -> ByteVect n -> ByteVect (m + n)
191 | append (BV src1 o1 lte1) (BV src2 o2 lte2) =
192 | let buf := alloc (m+n) $
\r,t =>
193 | let _ # t := icopy {n = m+n} src1 o1 0 m @{lte1} @{lteAddRight _} r t
194 | _ # t := icopy src2 o2 m n @{lte2} @{reflexive} r t
195 | in unsafeFreeze r t
196 | in BV buf 0 reflexive
200 | cons : {n : _} -> Bits8 -> ByteVect n -> ByteVect (S n)
201 | cons = append . singleton
205 | snoc : {n : _} -> Bits8 -> ByteVect n -> ByteVect (n + 1)
206 | snoc w bs = bs `append` singleton w
214 | head : ByteVect (S n) -> Bits8
215 | head bv = atNat bv 0
219 | tail : ByteVect (S n) -> ByteVect n
220 | tail (BV buf o p) = BV buf (S o) (ltePlusSuccRight p)
224 | uncons : ByteVect (S n) -> (Bits8, ByteVect n)
225 | uncons bs = (head bs, tail bs)
229 | last : {n : _} -> ByteVect (S n) -> Bits8
230 | last bs = atNat bs n
234 | init : ByteVect (S n) -> ByteVect n
235 | init (BV buf o p) = BV buf o (lteSuccLeft $
ltePlusSuccRight p)
239 | unsnoc : {n : _} -> ByteVect (S n) -> (Bits8, ByteVect n)
240 | unsnoc bs = (last bs, init bs)
249 | map : {n : _} -> (Bits8 -> Bits8) -> ByteVect n -> ByteVect n
250 | map f bs = generate n (\x => f $
at bs x)
255 | toUpper : {n : _} -> ByteVect n -> ByteVect n
256 | toUpper = map toUpper
261 | toLower : {n : _} -> ByteVect n -> ByteVect n
262 | toLower = map toLower
266 | reverse : {n : _} -> ByteVect n -> ByteVect n
267 | reverse bs = generate n (\x => fromEnd bs (finToNat x) @{finToNatLT _})
272 | all : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> Bool
276 | go : (c : Nat) -> (x : Ix c n) => Bool
278 | go (S k) = if p (ix bv k) then go k else False
283 | any : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> Bool
287 | go : (c : Nat) -> (x : Ix c n) => Bool
289 | go (S k) = if p (ix bv k) then True else go k
293 | elem : {n : _} -> Bits8 -> ByteVect n -> Bool
294 | elem b = any (b ==)
298 | foldl : {n : _} -> (a -> Bits8 -> a) -> a -> ByteVect n -> a
299 | foldl f ini bv = go n ini
302 | go : (c : Nat) -> (v : a) -> (x : Ix c n) => a
304 | go (S k) v = go k (f v $
ix bv k)
308 | foldr : {n : _} -> (Bits8 -> a -> a) -> a -> ByteVect n -> a
309 | foldr f ini bs = go n ini
312 | go : (k : Nat) -> (v : a) -> (0 lt : LTE k n) => a
314 | go (S k) v = go k (f (atNat bs k) v)
320 | findIndex : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> Maybe (Fin n)
321 | findIndex p bv = go n
324 | go : (c : Nat) -> {auto x : Ix c n} -> Maybe (Fin n)
326 | go (S k) = if p (ix bv k) then Just (ixToFin x) else go k
332 | elemIndex : {n : _} -> Bits8 -> ByteVect n -> Maybe (Fin n)
333 | elemIndex c = findIndex (c ==)
338 | find : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> Maybe Bits8
339 | find p bs = at bs <$> findIndex p bs
342 | isPrefixOf : {m,n : _} -> ByteVect m -> ByteVect n -> Bool
343 | isPrefixOf bv1 bv2 = go m n
346 | go : (c1,c2 : Nat) -> {auto _ : Ix c1 m} -> {auto _ : Ix c2 n} -> Bool
349 | go (S x) (S y) = if ix bv1 x == ix bv2 y then go x y else False
352 | isSuffixOf : {m,n : _} -> ByteVect m -> ByteVect n -> Bool
353 | isSuffixOf bv1 bv2 = go m n
356 | go : (o1,o2 : Nat) -> (0 _ : LTE o1 m) => (0 _ : LTE o2 n) => Bool
359 | go (S x) (S y) = if atNat bv1 x == atNat bv2 y then go x y else False
365 | findIndexOrLength : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> SubLength n
366 | findIndexOrLength p bv = go n
369 | go : (c : Nat) -> {auto x : Ix c n} -> SubLength n
371 | go (S k) = if p (ix bv k) then fromIx x else go k
373 | findIndexOrLengthNL : {n : _} -> ByteVect n -> SubLength n
374 | findIndexOrLengthNL bv = go n
377 | go : (c : Nat) -> {auto x : Ix c n} -> SubLength n
379 | go (S k) = case ix bv k of 10 => fromIx x;
_ => go k
381 | findFromEndUntil : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> SubLength n
382 | findFromEndUntil p bv = go n
385 | go : (k : Nat) -> (0 lt : LTE k n) => SubLength n
386 | go 0 = Element 0 LTEZero
387 | go (S k) = if p (atNat bv k) then (Element (S k) lt) else go k
389 | 0 substrPrf : LTE (s + l) n -> LTE (o + n) n2 -> LTE ((o + s) + l) n2
391 | let pp := rewrite sym (plusAssociative o s l) in ltePlusRight o p
399 | (start,length : Nat)
401 | -> {auto 0 inBounds : LTE (start + length) n}
406 | substring start len (BV buf o p) =
407 | BV buf (o + start) (substrPrf inBounds p)
412 | substringFromTill :
414 | -> {auto 0 lt1 : LTE from till}
415 | -> {auto 0 lt2 : LTE till n}
417 | -> ByteVect (till `minus` from)
418 | substringFromTill f t bv =
419 | substring f (t `minus` f) bv @{transitive (plusMinusLTE _ _ lt1) lt2}
426 | -> {auto 0 lte : LTE from to}
427 | -> {auto 0 lt : LT to n}
429 | -> ByteVect (S to `minus` from)
430 | substringFromTo f t bv = substringFromTill f (S t) bv
433 | generateMaybe : (n : Nat) -> (Fin n -> Maybe Bits8) -> ByteString
434 | generateMaybe n f = alloc n (go n n)
437 | go : (k,m : Nat) -> (x : Ix k n) => (y : Ix m n) => WithMBuffer n ByteString
438 | go (S k) (S m) r t =
439 | case f (ixToFin x) of
440 | Nothing => go k (S m) r t
441 | Just v => let _ # t := setIx r m v t in go k m r t
442 | go _ _ r t = unsafeFreezeByteStringLTE (ixToNat y) @{ixLTE y} r t
445 | mapMaybe : {n : _} -> (Bits8 -> Maybe Bits8) -> ByteVect n -> ByteString
446 | mapMaybe f bv = generateMaybe n (f . at bv)
449 | filter : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> ByteString
450 | filter p = mapMaybe (\b => if p b then Just b else Nothing)
455 | take : (0 k : Nat) -> (0 lt : LTE k n) => ByteVect n -> ByteVect k
456 | take k (BV buf o p) =
460 | BV buf o (transitive (ltePlusRight o lt) p)
468 | -> {auto 0 lt : LTE k n}
471 | takeEnd k (BV buf o p) =
475 | let 0 q := plusMinus' k (o + n) (lteAddLeft o lt)
476 | in BV buf ((o + n) `minus` k) (rewrite q in p)
480 | drop : (k : Nat) -> (0 lt : LTE k n) => ByteVect n -> ByteVect (n `minus` k)
481 | drop k (BV buf o p) =
485 | let 0 q := cong (o +) (plusMinus k n lt)
486 | 0 r := plusAssociative o k (n `minus` k)
487 | in BV buf (o + k) (rewrite (trans (sym r) q) in p)
493 | -> {auto 0 lt : LTE k n}
495 | -> ByteVect (n `minus` k)
496 | dropEnd k (BV buf o p) =
500 | BV buf o (transitive (ltePlusRight o $
minusLTE n k) p)
506 | -> {auto 0 lte : LTE k n}
508 | -> (ByteVect k, ByteVect (n `minus` k))
509 | splitAt k bs = (take k bs, drop k bs)
514 | takeWhile : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> ByteString
516 | let Element k _ = findIndexOrLength (not . p) bs
517 | in BS k $
take k bs
522 | takeWhileEnd : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> ByteString
523 | takeWhileEnd f bs =
524 | let Element k _ = findFromEndUntil (not . f) bs
525 | in BS _ $
drop k bs
530 | dropWhile : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> ByteString
532 | let Element k _ = findIndexOrLength (not . f) bs
533 | in BS _ $
drop k bs
538 | dropWhileEnd : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> ByteString
539 | dropWhileEnd f bs =
540 | let Element k _ = findFromEndUntil (not . f) bs
541 | in BS k $
take k bs
545 | trimLeft : {n : _} -> ByteVect n -> ByteString
546 | trimLeft = dropWhile isSpace
550 | trimRight : {n : _} -> ByteVect n -> ByteString
551 | trimRight = dropWhileEnd isSpace
555 | trim : {n : _} -> ByteVect n -> ByteString
556 | trim bs = let BS k bs' := trimLeft bs in trimRight bs'
559 | record BreakRes (n : Nat) where
560 | constructor MkBreakRes
563 | fst : ByteVect lenFst
564 | snd : ByteVect lenSnd
565 | 0 prf : LTE (lenFst + lenSnd) n
568 | breakRes : {n : _} -> ByteVect n -> SubLength n -> BreakRes n
569 | breakRes bs (Element k p) =
570 | let bs1 := take k bs
572 | in MkBreakRes k (n `minus` k) bs1 bs2 (plusMinusLTE k n p)
577 | break : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> BreakRes n
578 | break p bs = breakRes bs (findIndexOrLength p bs)
582 | breakNL : {n : _} -> ByteVect n -> BreakRes n
583 | breakNL bs = breakRes bs (findIndexOrLengthNL bs)
588 | breakEnd : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> BreakRes n
589 | breakEnd p bs = breakRes bs (findFromEndUntil p bs)
594 | span : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> BreakRes n
595 | span p = break (not . p)
600 | spanEnd : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> BreakRes n
601 | spanEnd p bs = breakRes bs (findFromEndUntil (not . p) bs)
606 | substringIndex : {k,n : _} -> ByteVect k -> ByteVect n -> SubLength n
607 | substringIndex sep bv = go n
610 | go : (c : Nat) -> {auto x : Ix c n} -> SubLength n
613 | if isPrefixOf sep (drop (ixToNat x) @{ixLTE x} bv) then fromIx x else go k
619 | breakAtSubstring : {k,n : _} -> ByteVect k -> ByteVect n -> BreakRes n
620 | breakAtSubstring sep bs = breakRes bs (substringIndex sep bs)
627 | splitWith : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> List ByteString
628 | splitWith p bs = go Lin n bs (sizeAccessible n)
632 | SnocList ByteString
635 | -> (0 acc : SizeAccessible m)
637 | go sb m bs' (Access rec) = case break p bs' of
638 | MkBreakRes l1 0 b1 _ p => sb <>> [BS l1 b1]
639 | MkBreakRes l1 (S l2) b1 b2 p =>
640 | go (sb :< BS l1 b1) l2 (tail b2) (rec l2 $
ltPlusSuccRight' _ p)
644 | splitWithNonEmpty : {n : _} -> (Bits8 -> Bool) -> ByteVect n -> List ByteString
645 | splitWithNonEmpty p = filter ((/= Z) . size) . splitWith p
654 | split : {n : _} -> Bits8 -> ByteVect n -> List ByteString
655 | split b = splitWith (b ==)
659 | splitNonEmpty : {n : _} -> Bits8 -> ByteVect n -> List ByteString
660 | splitNonEmpty p = filter ((/= Z) . size) . split p
663 | lines : {n : _} -> ByteVect n -> List ByteString
664 | lines bs = go Lin n bs (sizeAccessible n)
668 | SnocList ByteString
671 | -> (0 acc : SizeAccessible m)
673 | go sb m bs' (Access rec) = case breakNL bs' of
674 | MkBreakRes l1 0 b1 _ p => sb <>> [BS l1 b1]
675 | MkBreakRes l1 (S l2) b1 b2 p =>
676 | go (sb :< BS l1 b1) l2 (tail b2) (rec l2 $
ltPlusSuccRight' _ p)
678 | 0 blocksLemma1 : (m,n : Nat) -> LT (S n `minus` S m) (S n)
679 | blocksLemma1 m n = LTESucc $
minusLTE _ _
681 | 0 blocksLemma2 : (m,n : Nat) -> LTE (S k) n -> LT (n `minus` S m) n
682 | blocksLemma2 m (S _) (LTESucc _) = blocksLemma1 m _
695 | -> (sep : ByteVect k)
696 | -> (val : ByteVect n)
698 | splitAtSubstring {k = 0} sep bv = [BS _ bv]
699 | splitAtSubstring {k = S m} sep bv = go [<] bv (sizeAccessible n)
702 | -> SnocList ByteString
703 | -> (body : ByteVect o)
704 | -> (0 acc : SizeAccessible o)
706 | go sb body (Access rec) =
707 | let MkBreakRes l1 l2 b1 b2 p1 := breakAtSubstring sep body
708 | in case tryLTE {n = l2} (S m) of
709 | Nothing0 => sb <>> [BS l1 b1]
711 | let 0 p3 := lteAddLeft {m = l2} l1 reflexive
712 | 0 p4 := blocksLemma2 m l2 p2
713 | 0 p5 := transitive (transitive p4 p3) p1
714 | in go (sb :< BS l1 b1) (drop (S m) b2) (rec _ p5)
717 | isInfixOf : {m,n : _} -> ByteVect m -> ByteVect n -> Bool
718 | isInfixOf bv1 bv2 = m == 0 || go n
721 | go : (c : Nat) -> (x : Ix c n) => Bool
723 | go (S k) = isPrefixOf bv1 (drop (ixToNat x) @{ixLTE x} bv2) || go k
734 | -> {auto 0 p1 : LTE 2 base}
735 | -> {auto 0 p2 : LTE base 16}
738 | parseAnyNat {n = Z} _ bv = Nothing
739 | parseAnyNat base bv = go n 0
742 | go : (c,res : Nat) -> (x : Ix c n) => Maybe Nat
743 | go 0 res = Just res
745 | let Just n := fromHexDigit $
ix bv k | Nothing => Nothing
746 | in if n < base then go k (res * base + n) else Nothing
750 | parseDecimalNat : {n : _} -> ByteVect n -> Maybe Nat
751 | parseDecimalNat {n = Z} bv = Nothing
752 | parseDecimalNat bv = go n 0
755 | go : (c,res : Nat) -> (x : Ix c n) => Maybe Nat
756 | go 0 res = Just res
758 | let Just n := fromDigit $
ix bv k | Nothing => Nothing
759 | in go k (res * 10 + n)
762 | parseHexadecimalNat : {n : _} -> ByteVect n -> Maybe Nat
763 | parseHexadecimalNat = parseAnyNat 10
766 | parseOctalNat : {n : _} -> ByteVect n -> Maybe Nat
767 | parseOctalNat = parseAnyNat 8
770 | parseBinaryNat : {n : _} -> ByteVect n -> Maybe Nat
771 | parseBinaryNat = parseAnyNat 2
774 | parseInteger : {n : _} -> ByteVect n -> Maybe Integer
775 | parseInteger {n = Z} _ = Nothing
776 | parseInteger {n = S _} bv = case head bv of
777 | 43 => cast <$> parseDecimalNat (tail bv)
778 | 45 => negate . cast <$> parseDecimalNat (tail bv)
779 | _ => cast <$> parseDecimalNat bv
784 | isE : Bits8 -> Bool
789 | fract : {n : _} -> ByteVect n -> Maybe Double
791 | let Just k := parseDecimalNat bv | Nothing => Nothing
792 | in Just (cast k / (pow 10 $
cast n))
794 | exp : {n : _} -> ByteVect n -> Maybe Double
796 | let Just exp := parseInteger bv | Nothing => Nothing
797 | in Just $
pow 10.0 (cast exp)
799 | parseDotted : {n : _} -> ByteVect n -> Maybe Double
800 | parseDotted bv = go 0 0 n
802 | go : (v,exp,c : Nat) -> (x : Ix c n) => Maybe Double
803 | go v exp 0 = case exp of
805 | _ => Just $
cast v / cast exp
808 | 48 => go (v * 10 + 0) (exp * 10) k
809 | 49 => go (v * 10 + 1) (exp * 10) k
810 | 50 => go (v * 10 + 2) (exp * 10) k
811 | 51 => go (v * 10 + 3) (exp * 10) k
812 | 52 => go (v * 10 + 4) (exp * 10) k
813 | 53 => go (v * 10 + 5) (exp * 10) k
814 | 54 => go (v * 10 + 6) (exp * 10) k
815 | 55 => go (v * 10 + 7) (exp * 10) k
816 | 56 => go (v * 10 + 8) (exp * 10) k
817 | 57 => go (v * 10 + 9) (exp * 10) k
823 | parsePosDbl : {n : _} -> ByteVect n -> Maybe Double
824 | parsePosDbl bv = case parseDotted bv of
826 | Nothing => case break isE bv of
827 | MkBreakRes lf (S _) dotStr expStr _ =>
828 | let Just fract := parseDotted dotStr | Nothing => Nothing
829 | Just e := exp (tail expStr) | Nothing => Nothing
830 | in Just $
fract * e
831 | MkBreakRes _ 0 _ _ _ => Nothing
834 | parseDouble : {n : _} -> ByteVect n -> Maybe Double
835 | parseDouble {n = Z} _ = Nothing
836 | parseDouble {n = S _} bv = case head bv of
837 | 43 => parsePosDbl (tail bv)
838 | 45 => negate <$> parsePosDbl (tail bv)
839 | _ => parsePosDbl bv
846 | putByteVect : Builder q => {n : _} -> ByteVect n -> F1' q
847 | putByteVect (BV buf off _) = putBytesFrom off n buf