0 | module Data.Buffer.Core
2 | import Data.Array.Index
4 | import Data.Linear.Token
5 | import public Data.Fin
6 | import public Data.Nat
17 | %foreign "scheme:(lambda (b o) (bytevector-u8-ref b o))"
18 | "javascript:lambda:(buf,offset)=>buf[Number(offset)]"
19 | prim__getByte : Buffer -> (offset : Integer) -> Bits8
25 | %foreign "scheme:(lambda (b a o) (bytevector-u8-ref b (+ a o)))"
26 | "scheme,chez:(lambda (b a o) (bytevector-u8-ref b (fx+ a o)))"
27 | "javascript:lambda:(buf,at,offset)=>buf[Number(offset) + Number(at)]"
28 | prim__getByteOffset : Buffer -> (at, offset : Integer) -> Bits8
31 | %foreign "scheme:(lambda (b o v) (bytevector-u8-set! b o v))"
32 | "javascript:lambda:(buf,offset,value,t)=>{buf[Number(offset)] = value; return t}"
33 | prim__setByte : Buffer -> (offset : Integer) -> (val : Bits8) -> PrimIO ()
36 | %foreign "scheme:(lambda (n) (make-bytevector n 0))"
37 | "javascript:lambda:(s,w)=>new Uint8Array(Number(s))"
38 | prim__newBuf : Integer -> PrimIO Buffer
41 | %foreign "scheme:blodwen-buffer-getstring"
42 | "javascript:lambda:(buf,offset,len)=> new TextDecoder().decode(buf.subarray(Number(offset), Number(offset+len)))"
43 | prim__getString : Buffer -> (offset,len : Integer) -> String
46 | %foreign "scheme:(lambda (v) (string->utf8 v))"
47 | "javascript:lambda:(v)=> new TextEncoder().encode(v)"
48 | prim__fromString : (val : String) -> Buffer
51 | %foreign "scheme:(lambda (b1 o1 len b2 o2) (bytevector-copy! b1 o1 b2 o2 len))"
52 | "javascript:lambda:(b1,bo1,blen,b2,bo2,t)=> {const o1 = Number(bo1); const len = Number(blen); const o2 = Number(bo2); for (let i = 0; i < len; i++) {b2[o2+i] = b1[o1+i];}; return t}"
53 | prim__copy : (src : Buffer) -> (srcOffset, len : Integer) ->
54 | (dst : Buffer) -> (dstOffset : Integer) -> PrimIO ()
62 | record IBuffer (n : Nat) where
68 | at : IBuffer n -> Fin n -> Bits8
69 | at (IB buf) m = prim__getByte buf (cast $
finToNat m)
74 | atOffset : IBuffer n -> Fin m -> (off : Nat) -> (0 p : LTE (off+m) n) => Bits8
75 | atOffset (IB buf) m off =
76 | prim__getByteOffset buf (cast $
finToNat m) (cast off)
85 | take : (0 m : Nat) -> IBuffer n -> {auto 0 lte : LTE m n} -> IBuffer m
86 | take _ (IB buf) = IB buf
90 | fromString : (s : String) -> IBuffer (cast $
stringByteLength s)
91 | fromString s = IB (prim__fromString s)
95 | toString : IBuffer n -> (off,len : Nat) -> (0 _ : LTE (off + len) n) => String
96 | toString (IB buf) off len = prim__getString buf (cast off) (cast len)
104 | unsafeGetBuffer : IBuffer n -> Buffer
105 | unsafeGetBuffer (IB buf) = buf
112 | unsafeMakeBuffer : Buffer -> IBuffer k
113 | unsafeMakeBuffer = IB
116 | record AnyBuffer where
119 | ibuf : IBuffer size
127 | data MBuffer : (s : Type) -> (n : Nat) -> Type where
128 | MB : (buf : Buffer) -> MBuffer s n
132 | 0 IOBuffer : Nat -> Type
133 | IOBuffer = MBuffer World
137 | unsafeMBuffer : Buffer -> MBuffer s n
142 | unsafeFromMBuffer : MBuffer s n -> Buffer
143 | unsafeFromMBuffer (MB buf) = buf
151 | mbuffer1 : (n : Nat) -> F1 s (MBuffer s n)
153 | let MkIORes b _ := prim__newBuf (cast n) %MkWorld
158 | mbuffer : Lift1 s f => (n : Nat) -> f (MBuffer s n)
159 | mbuffer n = lift1 (mbuffer1 n)
163 | set : (r : MBuffer s n) -> Fin n -> Bits8 -> F1' s
164 | set (MB buf) ix v = ffi (prim__setByte buf (cast $
finToNat ix) v)
168 | get : (r : MBuffer s n) -> Fin n -> F1 s Bits8
169 | get (MB buf) ix t = prim__getByte buf (cast $
finToNat ix) # t
173 | modify : (r : MBuffer s n) -> Fin n -> (Bits8 -> Bits8) -> F1' s
174 | modify r m f t = let v # t := get r m t in set r m (f v) t
178 | bufString : (r : MBuffer s n) -> (m : Nat) -> (0 lte : LTE m n) => F1 s String
179 | bufString (MB buf) m t = prim__getString buf 0 (cast m) # t
184 | bufStringFromTill :
186 | -> (from, till : Nat)
187 | -> {auto 0 lt1 : LTE from till}
188 | -> {auto 0 lt2 : LTE till n}
190 | bufStringFromTill (MB buf) from till t =
191 | prim__getString buf (cast from) (cast $
till `minus` from) # t
198 | -> (from, to : Nat)
199 | -> {auto 0 lte : LTE from to}
200 | -> {auto 0 lt : LT to n}
202 | bufStringFromTo buf from to = bufStringFromTill buf from (S to)
206 | mtake : MBuffer s n -> (0 m : Nat) -> (0 lte : LTE m n) => F1 s (MBuffer s m)
207 | mtake (MB buf) _ t = MB buf # t
214 | 0 WithMBuffer : Nat -> (a : Type) -> Type
215 | WithMBuffer n a = forall s . (r : MBuffer s n) -> F1 s a
219 | alloc : (n : Nat) -> (fun : WithMBuffer n a) -> a
220 | alloc n f = run1 $
\t => let r # t := mbuffer1 n t in f r t
229 | -> (srcOffset,dstOffset : Nat)
231 | -> {auto 0 p1 : LTE (srcOffset + len) m}
232 | -> {auto 0 p2 : LTE (dstOffset + len) n}
233 | -> (r : MBuffer s n)
235 | copy (MB src) srcOffset dstOffset len (MB dst) =
236 | ffi (prim__copy src (cast srcOffset) (cast len) dst (cast dstOffset))
241 | -> (srcOffset,dstOffset : Nat)
243 | -> {auto 0 p1 : LTE (srcOffset + len) m}
244 | -> {auto 0 p2 : LTE (dstOffset + len) n}
245 | -> (r : MBuffer s n)
247 | icopy (IB src) = copy {m} (MB src)
254 | -> {auto 0 lte : LTE (off+len) n}
255 | -> F1 s (IBuffer len)
256 | bufSubstring (MB src) off len t =
257 | let MB dst # t := mbuffer1 len t
258 | _ # t := ffi (prim__copy src (cast off) (cast len) dst 0) t
264 | bufSubstringFromTill :
266 | -> (from, till : Nat)
267 | -> {auto 0 lt1 : LTE from till}
268 | -> {auto 0 lt2 : LTE till n}
269 | -> F1 s (IBuffer (till `minus` from))
270 | bufSubstringFromTill r f t =
271 | bufSubstring r f (t `minus` f) @{transitive (plusMinusLTE _ _ lt1) lt2}
276 | bufSubstringFromTo :
278 | -> (from, to : Nat)
279 | -> {auto 0 lte : LTE from to}
280 | -> {auto 0 lt : LT to n}
281 | -> F1 s (IBuffer (S to `minus` from))
282 | bufSubstringFromTo r f t = bufSubstringFromTill r f (S t)
286 | thaw : {n : _} -> IBuffer n -> F1 s (MBuffer s n)
288 | let r # t := mbuffer1 n t
289 | _ # t := icopy src 0 0 n @{reflexive} @{reflexive} r t
309 | -> {auto 0 _ : LTE m n}
310 | -> F1 s (IBuffer m)
311 | unsafeFreezeLTE (MB buf) _ t = IB buf # t
315 | unsafeFreeze : (r : MBuffer s n) -> F1 s (IBuffer n)
316 | unsafeFreeze r = unsafeFreezeLTE @{reflexive} r n
320 | freezeLTE : MBuffer s n -> (m : Nat) -> (0 p : LTE m n) => F1 s (IBuffer m)
321 | freezeLTE src m t =
322 | let r@(MB buf) # t := mbuffer1 m t
323 | _ # t := copy src 0 0 m @{p} @{reflexive} r t
328 | freeze : {n : _} -> MBuffer s n -> F1 s (IBuffer n)
329 | freeze src = freezeLTE src n @{reflexive}
338 | {auto has : HasIO io}
341 | -> io (Either FileError (
n ** IBuffer n)
)
342 | readIBuffer max f = do
343 | buf <- primIO (prim__newBuf (cast max))
344 | Right r <- readBufferData f buf 0 (cast max) | Left x => pure (Left x)
346 | then pure (Right (
cast r ** IB buf)
)
347 | else pure (Left FileReadError)
353 | {auto has : HasIO io}
355 | -> (offset,len : Nat)
357 | -> {auto 0 prf : LTE (offset + len) n}
358 | -> io (Either (FileError,Int) ())
359 | writeIBuffer h o s (IB buf) = writeBufferData h buf (cast o) (cast s)
365 | {auto has : HasIO io}
367 | -> (offset,len : Nat)
368 | -> {auto 0 prf : LTE (offset + len) n}
369 | -> (r : MBuffer s n)
370 | -> io (Either (FileError,Int) ())
371 | writeMBuffer h o s (MB b) =
372 | writeBufferData h b (cast o) (cast s)