14 | data Buffer : Type where [external]
16 | %foreign "scheme:blodwen-buffer-size"
17 | "RefC:getBufferSize"
18 | "node:lambda:b => b.length"
19 | prim__bufferSize : Buffer -> Int
22 | rawSize : HasIO io => Buffer -> io Int
23 | rawSize buf = pure (prim__bufferSize buf)
25 | %foreign "scheme:blodwen-new-buffer"
27 | "node:lambda:s=>Buffer.alloc(s)"
28 | prim__newBuffer : Int -> PrimIO Buffer
31 | newBuffer : HasIO io => Int -> io (Maybe Buffer)
34 | then do buf <- primIO (prim__newBuffer size)
48 | %foreign "scheme:blodwen-buffer-setbyte"
49 | "RefC:setBufferUInt8"
50 | "node:lambda:(buf,offset,value)=>buf.writeUInt8(value, offset)"
51 | prim__setByte : Buffer -> (offset : Int) -> (val : Int) -> PrimIO ()
53 | %foreign "scheme:blodwen-buffer-setbyte"
54 | "RefC:setBufferUInt8"
55 | "node:lambda:(buf,offset,value)=>buf.writeUInt8(value, offset)"
56 | prim__setBits8 : Buffer -> (offset : Int) -> (val: Bits8) -> PrimIO ()
62 | setByte : HasIO io => Buffer -> (offset : Int) -> (val : Int) -> io ()
63 | setByte buf offset val
64 | = primIO (prim__setByte buf offset val)
67 | setBits8 : HasIO io => Buffer -> (offset : Int) -> (val : Bits8) -> io ()
68 | setBits8 buf offset val
69 | = primIO (prim__setBits8 buf offset val)
72 | %foreign "scheme:blodwen-buffer-getbyte"
73 | "RefC:getBufferByte"
74 | "node:lambda:(buf,offset)=>buf.readUInt8(offset)"
75 | prim__getByte : Buffer -> (offset : Int) -> PrimIO Int
77 | %foreign "scheme:blodwen-buffer-getbyte"
78 | "RefC:getBufferUInt8"
79 | "node:lambda:(buf,offset)=>buf.readUInt8(offset)"
80 | prim__getBits8 : Buffer -> (offset : Int) -> PrimIO Bits8
85 | getByte : HasIO io => Buffer -> (offset : Int) -> io Int
87 | = primIO (prim__getByte buf offset)
90 | getBits8 : HasIO io => Buffer -> (offset : Int) -> io Bits8
92 | = primIO (prim__getBits8 buf offset)
94 | %foreign "scheme:blodwen-buffer-setbits16"
95 | "RefC:setBufferUInt16LE"
96 | "node:lambda:(buf,offset,value)=>buf.writeUInt16LE(value, offset)"
97 | prim__setBits16 : Buffer -> (offset : Int) -> (value : Bits16) -> PrimIO ()
100 | setBits16 : HasIO io => Buffer -> (offset : Int) -> (val : Bits16) -> io ()
101 | setBits16 buf offset val
102 | = primIO (prim__setBits16 buf offset val)
104 | %foreign "scheme:blodwen-buffer-getbits16"
105 | "RefC:getBufferUInt16LE"
106 | "node:lambda:(buf,offset)=>buf.readUInt16LE(offset)"
107 | prim__getBits16 : Buffer -> (offset : Int) -> PrimIO Bits16
110 | getBits16 : HasIO io => Buffer -> (offset : Int) -> io Bits16
111 | getBits16 buf offset
112 | = primIO (prim__getBits16 buf offset)
114 | %foreign "scheme:blodwen-buffer-setbits32"
115 | "RefC:setBufferUInt32LE"
116 | "node:lambda:(buf,offset,value)=>buf.writeUInt32LE(value, offset)"
117 | prim__setBits32 : Buffer -> (offset : Int) -> (value : Bits32) -> PrimIO ()
120 | setBits32 : HasIO io => Buffer -> (offset : Int) -> (val : Bits32) -> io ()
121 | setBits32 buf offset val
122 | = primIO (prim__setBits32 buf offset val)
124 | %foreign "scheme:blodwen-buffer-getbits32"
125 | "RefC:getBufferUInt32LE"
126 | "node:lambda:(buf,offset)=>buf.readUInt32LE(offset)"
127 | prim__getBits32 : Buffer -> Int -> PrimIO Bits32
130 | getBits32 : HasIO io => Buffer -> (offset : Int) -> io Bits32
131 | getBits32 buf offset
132 | = primIO (prim__getBits32 buf offset)
134 | %foreign "scheme:blodwen-buffer-setbits64"
135 | "RefC:setBufferUInt64LE"
136 | "node:lambda:(buf,offset,value)=>buf.writeBigUInt64LE(value, offset)"
137 | prim__setBits64 : Buffer -> Int -> Bits64 -> PrimIO ()
140 | setBits64 : HasIO io => Buffer -> (offset : Int) -> (val : Bits64) -> io ()
141 | setBits64 buf offset val
142 | = primIO (prim__setBits64 buf offset val)
144 | %foreign "scheme:blodwen-buffer-getbits64"
145 | "RefC:getBufferUInt64LE"
146 | "node:lambda:(buf,offset)=>buf.readBigUInt64LE(offset)"
147 | prim__getBits64 : Buffer -> (offset : Int) -> PrimIO Bits64
150 | getBits64 : HasIO io => Buffer -> (offset : Int) -> io Bits64
151 | getBits64 buf offset
152 | = primIO (prim__getBits64 buf offset)
159 | %foreign "scheme:blodwen-buffer-setint8"
160 | prim__setInt8 : Buffer -> (offset : Int) -> (val : Int8) -> PrimIO ()
163 | setInt8 : HasIO io => Buffer -> (offset : Int) -> (val : Int8) -> io ()
164 | setInt8 buf offset val
165 | = primIO (prim__setInt8 buf offset val)
167 | %foreign "scheme:blodwen-buffer-getint8"
168 | prim__getInt8 : Buffer -> (offset : Int) -> PrimIO Int8
171 | getInt8 : HasIO io => Buffer -> (offset : Int) -> io Int8
173 | = primIO (prim__getInt8 buf offset)
175 | %foreign "scheme:blodwen-buffer-setint16"
176 | "RefC:setBufferInt16LE"
177 | "node:lambda:(buf,offset,value)=>buf.writeInt16LE(value, offset)"
178 | prim__setInt16 : Buffer -> (offset : Int) -> (val : Int16) -> PrimIO ()
181 | setInt16 : HasIO io => Buffer -> (offset : Int) -> (val : Int16) -> io ()
182 | setInt16 buf offset val
183 | = primIO (prim__setInt16 buf offset val)
185 | %foreign "scheme:blodwen-buffer-getint16"
186 | prim__getInt16 : Buffer -> (offset : Int) -> PrimIO Int16
189 | getInt16 : HasIO io => Buffer -> (offset : Int) -> io Int16
190 | getInt16 buf offset
191 | = primIO (prim__getInt16 buf offset)
194 | %foreign "scheme:blodwen-buffer-setint32"
195 | "RefC:setBufferInt32LE"
196 | "node:lambda:(buf,offset,value)=>buf.writeInt32LE(value, offset)"
197 | prim__setInt32 : Buffer -> (offset : Int) -> (val : Int32) -> PrimIO ()
200 | setInt32 : HasIO io => Buffer -> (offset : Int) -> (val : Int32) -> io ()
201 | setInt32 buf offset val
202 | = primIO (prim__setInt32 buf offset val)
204 | %foreign "scheme:blodwen-buffer-getint32"
205 | "RefC:getBufferInt32LE"
206 | "node:lambda:(buf,offset)=>buf.readInt32LE(offset)"
207 | prim__getInt32 : Buffer -> (offset : Int) -> PrimIO Int32
210 | getInt32 : HasIO io => Buffer -> (offset : Int) -> io Int32
211 | getInt32 buf offset
212 | = primIO (prim__getInt32 buf offset)
214 | %foreign "scheme:blodwen-buffer-setint64"
215 | prim__setInt64 : Buffer -> (offset : Int) -> (val : Int64) -> PrimIO ()
218 | setInt64 : HasIO io => Buffer -> (offset : Int) -> (val : Int64) -> io ()
219 | setInt64 buf offset val
220 | = primIO (prim__setInt64 buf offset val)
222 | %foreign "scheme:blodwen-buffer-getint64"
223 | prim__getInt64 : Buffer -> (offset : Int) -> PrimIO Int64
226 | getInt64 : HasIO io => Buffer -> (offset : Int) -> io Int64
227 | getInt64 buf offset
228 | = primIO (prim__getInt64 buf offset)
233 | %foreign "scheme:blodwen-buffer-setint"
234 | "RefC:setBufferInt64LE"
235 | "node:lambda:(buf,offset,value)=>buf.writeInt32LE(value, offset)"
236 | prim__setInt : Buffer -> (offset : Int) -> (val : Int) -> PrimIO ()
239 | setInt : HasIO io => Buffer -> (offset : Int) -> (val : Int) -> io ()
240 | setInt buf offset val
241 | = primIO (prim__setInt buf offset val)
243 | %foreign "scheme:blodwen-buffer-getint"
244 | "RefC:getBufferInt64LE"
245 | "node:lambda:(buf,offset)=>buf.readInt32LE(offset)"
246 | prim__getInt : Buffer -> (offset : Int) -> PrimIO Int
249 | getInt : HasIO io => Buffer -> (offset : Int) -> io Int
251 | = primIO (prim__getInt buf offset)
256 | %foreign "scheme:blodwen-buffer-setdouble"
257 | "RefC:setBufferDouble"
258 | "node:lambda:(buf,offset,value)=>buf.writeDoubleLE(value, offset)"
259 | prim__setDouble : Buffer -> (offset : Int) -> (val : Double) -> PrimIO ()
262 | setDouble : HasIO io => Buffer -> (offset : Int) -> (val : Double) -> io ()
263 | setDouble buf offset val
264 | = primIO (prim__setDouble buf offset val)
266 | %foreign "scheme:blodwen-buffer-getdouble"
267 | "RefC:getBufferDouble"
268 | "node:lambda:(buf,offset)=>buf.readDoubleLE(offset)"
269 | prim__getDouble : Buffer -> (offset : Int) -> PrimIO Double
272 | getDouble : HasIO io => Buffer -> (offset : Int) -> io Double
273 | getDouble buf offset
274 | = primIO (prim__getDouble buf offset)
280 | setBool : HasIO io => Buffer -> (offset : Int) -> (val : Bool) -> io ()
281 | setBool buf offset val = setBits8 buf offset (ifThenElse val 0 1)
284 | getBool : HasIO io => Buffer -> (offset : Int) -> io Bool
285 | getBool buf offset = (0 ==) <$> getBits8 buf offset
292 | setNat : HasIO io => Buffer -> (offset : Int) -> (val : Nat) -> io Int
293 | setNat buf offset val
294 | = do let limbs = toLimbs (cast val)
295 | let len = foldl (const . (1+)) 0 limbs
296 | setInt64 buf offset len
297 | setLimbs (offset + 8) limbs
301 | toLimbs : Integer -> List Bits32
303 | toLimbs (-
1) = [-
1]
304 | toLimbs x = fromInteger (prim__and_Integer x 0xffffffff) ::
305 | toLimbs (assert_smaller x (prim__shr_Integer x 32))
307 | setLimbs : (offset : Int) -> List Bits32 -> io Int
308 | setLimbs offset [] = pure offset
309 | setLimbs offset (limb :: limbs)
310 | = do setBits32 buf offset limb
311 | setLimbs (offset + 4) limbs
315 | getNat : HasIO io => Buffer -> (offset : Int) -> io (Int, Nat)
317 | = do len <- getInt64 buf offset
318 | when (len < 0) $
assert_total $
idris_crash "INTERNAL ERROR: getNat -> corrupt Nat"
319 | limbs <- getLimbs [<] (offset + 8) len
320 | pure (offset + 8 + 4 * cast len, cast $
fromLimbs limbs)
324 | fromLimbs : List Bits32 -> Integer
326 | fromLimbs (x :: xs) = cast x + prim__shl_Integer (fromLimbs xs) 32
328 | getLimbs : SnocList Bits32 -> (offset : Int) -> (len : Int64) -> io (List Bits32)
329 | getLimbs acc offset 0 = pure (acc <>> [])
330 | getLimbs acc offset len
331 | = do limb <- getBits32 buf offset
332 | getLimbs (acc :< limb) (offset + 4) (assert_smaller len (len -1))
336 | setInteger : HasIO io => Buffer -> (offset : Int) -> (val : Integer) -> io Int
337 | setInteger buf offset val = if val < 0
338 | then do setBool buf offset True
339 | setNat buf (offset + 1) (cast (- val))
340 | else do setBool buf offset False
341 | setNat buf (offset + 1) (cast val)
345 | getInteger : HasIO io => Buffer -> (offset : Int) -> io (Int, Integer)
346 | getInteger buf offset
347 | = do b <- getBool buf offset
348 | map (ifThenElse b negate id . cast) <$> getNat buf (offset + 1)
355 | %foreign "scheme:blodwen-stringbytelen"
357 | "javascript:lambda:(string)=>new TextEncoder().encode(string).length"
358 | stringByteLength : String -> Int
360 | %foreign "scheme:blodwen-buffer-setstring"
361 | "RefC:setBufferString"
362 | "node:lambda:(buf,offset,value)=>buf.write(value, offset,buf.length - offset, 'utf-8')"
363 | prim__setString : Buffer -> (offset : Int) -> (val : String) -> PrimIO ()
366 | setString : HasIO io => Buffer -> (offset : Int) -> (val : String) -> io ()
367 | setString buf offset val
368 | = primIO (prim__setString buf offset val)
370 | %foreign "scheme:blodwen-buffer-getstring"
371 | "RefC:getBufferString"
372 | "node:lambda:(buf,offset,len)=>buf.slice(offset, offset+len).toString('utf-8')"
373 | prim__getString : Buffer -> (offset : Int) -> (len : Int) -> PrimIO String
376 | getString : HasIO io => Buffer -> (offset : Int) -> (len : Int) -> io String
377 | getString buf offset len
378 | = primIO (prim__getString buf offset len)
384 | bufferData : HasIO io => Buffer -> io (List Int)
386 | = do len <- rawSize buf
390 | unpackTo : List Int -> Int -> io (List Int)
391 | unpackTo acc 0 = pure acc
392 | unpackTo acc offset
393 | = do val <- getBits8 buf (offset - 1)
394 | unpackTo (cast val :: acc) (offset - 1)
400 | bufferData' : HasIO io => Buffer -> io (List Bits8)
402 | = do len <- rawSize buf
406 | unpackTo : List Bits8 -> Int -> io (List Bits8)
407 | unpackTo acc 0 = pure acc
408 | unpackTo acc offset
409 | = do val <- getBits8 buf (offset - 1)
410 | unpackTo (val :: acc) (offset - 1)
413 | %foreign "scheme:blodwen-buffer-copydata"
415 | "node:lambda:(b1,o1,length,b2,o2)=>b1.copy(b2,o2,o1,o1+length)"
416 | prim__copyData : (src : Buffer) -> (srcOffset, len : Int) ->
417 | (dst : Buffer) -> (dstOffset : Int) -> PrimIO ()
420 | copyData : HasIO io => Buffer -> (srcOffset, len : Int) ->
421 | (dst : Buffer) -> (dstOffset : Int) -> io ()
422 | copyData src start len dest offset
423 | = primIO (prim__copyData src start len dest offset)
426 | resizeBuffer : HasIO io => Buffer -> Int -> io (Maybe Buffer)
427 | resizeBuffer old newsize
428 | = do Just buf <- newBuffer newsize
429 | | Nothing => pure Nothing
432 | oldsize <- rawSize old
433 | let len = if newsize < oldsize then newsize else oldsize
434 | copyData old 0 len buf 0
440 | concatBuffers : HasIO io => List Buffer -> io (Maybe Buffer)
442 | = do let sizes = map prim__bufferSize xs
443 | let (totalSize, revCumulative) = foldl scanSize (0,[]) sizes
444 | let cumulative = reverse revCumulative
445 | Just buf <- newBuffer totalSize
446 | | Nothing => pure Nothing
447 | traverse_ (\(b, size, watermark) => copyData b 0 size buf watermark) (zip3 xs sizes cumulative)
450 | scanSize : (Int, List Int) -> Int -> (Int, List Int)
451 | scanSize (s, cs) x = (s+x, s::cs)
455 | splitBuffer : HasIO io => Buffer -> Int -> io (Maybe (Buffer, Buffer))
456 | splitBuffer buf pos = do size <- rawSize buf
457 | if pos > 0 && pos < size
458 | then do Just first <- newBuffer pos
459 | | Nothing => pure Nothing
460 | Just second <- newBuffer (size - pos)
461 | | Nothing => pure Nothing
462 | copyData buf 0 pos first 0
463 | copyData buf pos (size-pos) second 0
464 | pure $
Just (first, second)