@@ -5,7 +5,7 @@ module Data.Buffer
5-- !!! TODO: Open issues:
5-- !!! TODO: Open issues:
6-- 1. It may be theoretically nice to represent Buffer size as
6-- 1. It may be theoretically nice to represent Buffer size as
7-- Fin (2 ^ WORD_BITS) instead of Nat
7-- Fin (2 ^ WORD_BITS) instead of Nat
8−-- 2. Primitives take Integers when really they should take the
8+-- 2. Primitives take Bits64 when really they should take the
9-- equivalent of C's size_t (ideally unboxed)
9-- equivalent of C's size_t (ideally unboxed)
10-- 3. If we had access to host system information, we could reduce
10-- 3. If we had access to host system information, we could reduce
11-- the needed primitives by implementing the LE/BE variants on
11-- the needed primitives by implementing the LE/BE variants on
@@ -16,55 +16,80 @@ module Data.Buffer
16-- 5. Would be nice to be able to peek/append the vector types, but
16-- 5. Would be nice to be able to peek/append the vector types, but
17-- for now I'm only touching the C backend which AFAICT doesn't
17-- for now I'm only touching the C backend which AFAICT doesn't
18-- support them.
18-- support them.
19−-- 6. Conversion from Fin to Integer (which, re 2, should eventually
19+-- 6. Conversion from Fin to Bits64 (which, re 2, should eventually
20-- be a fixed-width implementation-dependent type) is likely
20-- be a fixed-width implementation-dependent type) is likely
21−-- inefficient relative to conversion from Nat to Integer
21+-- inefficient relative to conversion from Nat to Bits64
23-- A contiguous chunk of n bytes
23-- A contiguous chunk of n bytes
25record Buffer : Nat -> Type where
25record Buffer : Nat -> Type where
26 MkBuffer : ( realBuffer : prim__UnsafeBuffer ) -> Buffer n
26 MkBuffer : ( realBuffer : prim__UnsafeBuffer ) -> Buffer n
28+bitsFromNat : Nat -> Bits64
30+bitsFromNat (S k) = 1 + bitsFromNat k
32+bitsFromFin : Fin n -> Bits64
34+bitsFromFin (fS k) = 1 + bitsFromFin k
28-- Allocate an empty Buffer. The size hint can be used to avoid
36-- Allocate an empty Buffer. The size hint can be used to avoid
29-- unnecessary reallocations and copies under the hood if the
37-- unnecessary reallocations and copies under the hood if the
30−-- approximate ultimate size of the Buffer is known
38+-- approximate ultimate size of the Buffer is known. Users can assume
39+-- the new Buffer is word-aligned.
32allocate : ( hint : Nat ) -> Buffer 0
41allocate : ( hint : Nat ) -> Buffer 0
33−allocate = MkBuffer . prim__allocate . toIntegerNat
42+allocate = MkBuffer . prim__allocate . bitsFromNat
35-- Copy a buffer. Since multiple buffers can reference the same
44-- Copy a buffer. Since multiple buffers can reference the same
36-- underlying chunk of memory, it may happen that a reference to
45-- underlying chunk of memory, it may happen that a reference to
37-- a relatively small bit of data might be preventing the runtime
46-- a relatively small bit of data might be preventing the runtime
38-- from freeing a much larger chunk. copy allows giving up references
47-- from freeing a much larger chunk. copy allows giving up references
39-- to the larger chunk without losing the smaller one.
48-- to the larger chunk without losing the smaller one.
41copy : Buffer n -> Buffer n
51copy : Buffer n -> Buffer n
42−copy = MkBuffer . prim__copy ( toIntegerNat n ) . realBuffer
52+copy { n } = MkBuffer . prim__copy ( bitsFromNat n ) . realBuffer
44-- Read a Buffer from another Buffer starting at offset
54-- Read a Buffer from another Buffer starting at offset
45-- (i.e. create a view of a subset of the Buffer)
55-- (i.e. create a view of a subset of the Buffer)
47−peekBufferNative : Buffer ( n + m ) -> ( offset : Fin n ) -> Buffer m
58+peekBufferNative : Buffer ( m + n ) ->
59+ ( offset : Fin ( n + 1 ) ) ->
48peekBufferNative ( MkBuffer real ) =
61peekBufferNative ( MkBuffer real ) =
49− MkBuffer . prim__peekBufferNative real . finToInteger
62+ MkBuffer . prim__peekBufferNative real . bitsFromFin
52−peekBufferLE : Buffer ( n + m ) -> ( offset : Fin n ) -> Buffer m
65+peekBufferLE : Buffer ( m + n ) ->
66+ ( offset : Fin ( n + 1 ) ) ->
53peekBufferLE = peekBufferNative
68peekBufferLE = peekBufferNative
56−peekBufferBE : Buffer ( n + m ) -> ( offset : Fin n ) -> Buffer m
71+peekBufferBE : Buffer ( m + n ) ->
72+ ( offset : Fin ( n + 1 ) ) ->
57peekBufferBE = peekBufferNative
74peekBufferBE = peekBufferNative
59-- Append count repetitions of a Buffer to another Buffer
76-- Append count repetitions of a Buffer to another Buffer
61appendBufferNative : Buffer n ->
79appendBufferNative : Buffer n ->
62 ( count : Nat ) ->
80 ( count : Nat ) ->
63 Buffer m ->
81 Buffer m ->
64 Buffer ( n + m * count )
82 Buffer ( n + m * count )
65−appendBufferNative ( MkBuffer input ) count = MkBuffer .
83+appendBufferNative { n } { m } ( MkBuffer input ) count =
84+ MkBuffer . app . realBuffer
87+ nBits = bitsFromNat n
89+ mBits = bitsFromNat m
91+ cBits = bitsFromNat count
66− prim__appendBufferNative input ( toIntegerNat count ) . realBuffer
92+ app = prim__appendBufferNative input nBits cBits mBits
70appendBufferLE : Buffer n ->
95appendBufferLE : Buffer n ->
@@ -80,173 +105,207 @@ appendBufferBE : Buffer n ->
80 Buffer ( n + m * count )
105 Buffer ( n + m * count )
81appendBufferBE = appendBufferNative
106appendBufferBE = appendBufferNative
83−peekBits : ( prim__UnsafeBuffer -> Integer -> a ) ->
109+peekBits : ( prim__UnsafeBuffer -> Bits64 -> a ) ->
84− Buffer ( n + m ) ->
110+ Buffer ( m + n ) ->
85− ( offset : Fin n ) ->
111+ ( offset : Fin ( n + 1 ) ) ->
87−peekBits prim ( MkBuffer real ) = prim real . finToInteger
113+peekBits prim ( MkBuffer real ) = prim real . bitsFromFin
89appendBits : ( prim__UnsafeBuffer ->
115appendBits : ( prim__UnsafeBuffer ->
90− Integer ->
116+ Bits64 ->
92 prim__UnsafeBuffer ) ->
119 prim__UnsafeBuffer ) ->
93 Buffer n ->
120 Buffer n ->
94 ( count : Nat) ->
121 ( count : Nat) ->
96 Buffer ( n + count * size )
123 Buffer ( n + count * size )
97−appendBits prim ( MkBuffer real ) count =
124+appendBits { n } prim ( MkBuffer real ) count =
98− MkBuffer . prim real ( toIntegerNat count )
125+ MkBuffer . prim real ( bitsFromNat n ) ( bitsFromNat count )
101-- Read a Bits8 from a Buffer starting at offset
128-- Read a Bits8 from a Buffer starting at offset
103−peekBits8Native : Buffer ( n + 1 ) -> ( offset : Fin n ) -> Bits8
131+peekBits8Native : Buffer ( 1 + n ) ->
132+ ( offset : Fin ( n + 1 ) ) ->
104−peekBits8Native = peekBits prim__peekBits8Native
134+peekBits8Native = peekBits { m = 1 } prim__peekB8Native
107−peekBits8LE : Buffer ( n + 1 ) -> ( offset : Fin n ) -> Bits8
138+peekBits8LE : Buffer ( 1 + n ) -> ( offset : Fin ( n + 1 ) ) -> Bits8
108−peekBits8LE = peekBits8Native
139+peekBits8LE = peekBits { m = 1 } prim__peekB8LE
111−peekBits8BE : Buffer ( n + 1 ) -> ( offset : Fin n ) -> Bits8
143+peekBits8BE : Buffer ( 1 + n ) -> ( offset : Fin ( n + 1 ) ) -> Bits8
112−peekBits8BE = peekBits8Native
144+peekBits8BE = peekBits { m = 1 } prim__peekB8BE
114-- Append count repetitions of a Bits8 to a Buffer
146-- Append count repetitions of a Bits8 to a Buffer
116appendBits8Native : Buffer n ->
149appendBits8Native : Buffer n ->
117 ( count : Nat ) ->
150 ( count : Nat ) ->
119− Buffer ( n + count )
152+ Buffer ( n + count * 1 )
120−appendBits8Native = appendBits prim__appendBits8Native
153+appendBits8Native = appendBits prim__appendB8Native
123appendBits8LE : Buffer n ->
157appendBits8LE : Buffer n ->
124 ( count : Nat ) ->
158 ( count : Nat ) ->
126− Buffer ( n + count )
160+ Buffer ( n + count * 1 )
127−appendBits8LE = appendBits8Native
161+appendBits8LE = appendBits prim__appendB8LE
130appendBits8BE : Buffer n ->
165appendBits8BE : Buffer n ->
131 ( count : Nat ) ->
166 ( count : Nat ) ->
133− Buffer ( n + count )
168+ Buffer ( n + count * 1 )
134−appendBits8BE = appendBits8Native
169+appendBits8BE = appendBits prim__appendB8BE
137-- Read a Bits16 in native byte order from a Buffer starting at offset
172-- Read a Bits16 in native byte order from a Buffer starting at offset
139−peekBits16Native : Buffer ( n + 2 ) -> ( offset : Fin n ) -> Bits8
175+peekBits16Native : Buffer ( 2 + n ) ->
176+ ( offset : Fin ( n + 1 ) ) ->
140−peekBits16Native = peekBits prim__peekBits16Native
178+peekBits16Native = peekBits { m = 2 } prim__peekB16Native
142-- Read a little-endian Bits16 from a Buffer starting at offset
180-- Read a little-endian Bits16 from a Buffer starting at offset
144−peekBits16LE : Buffer ( n + 2 ) -> ( offset : Fin n ) -> Bits8
183+peekBits16LE : Buffer ( 2 + n ) -> ( offset : Fin ( n + 1 ) ) -> Bits16
145−peekBits16LE = peekBits prim__peekBits16LE
184+peekBits16LE = peekBits { m = 2 } prim__peekB16LE
147-- Read a big-endian Bits16 from a Buffer starting at offset
186-- Read a big-endian Bits16 from a Buffer starting at offset
149−peekBits16BE : Buffer ( n + 2 ) -> ( offset : Fin n ) -> Bits8
189+peekBits16BE : Buffer ( 2 + n ) -> ( offset : Fin ( n + 1 ) ) -> Bits16
150−peekBits16BE = peekBits prim__peekBits16LE
190+peekBits16BE = peekBits { m = 2 } prim__peekB16BE
152-- Append count repetitions of a Bits16 in native byte order to a Buffer
192-- Append count repetitions of a Bits16 in native byte order to a Buffer
154appendBits16Native : Buffer n ->
195appendBits16Native : Buffer n ->
155 ( count : Nat ) ->
196 ( count : Nat ) ->
156 Bits16 ->
197 Bits16 ->
157− Buffer ( n + 2 * count )
198+ Buffer ( n + count * 2 )
158−appendBits16Native = appendBits prim__appendBits16Native
199+appendBits16Native = appendBits prim__appendB16Native
160-- Append count repetitions of a little-endian Bits16 to a Buffer
201-- Append count repetitions of a little-endian Bits16 to a Buffer
162appendBits16LE : Buffer n ->
204appendBits16LE : Buffer n ->
163 ( count : Nat ) ->
205 ( count : Nat ) ->
164 Bits16 ->
206 Bits16 ->
165− Buffer ( n + 2 * count )
207+ Buffer ( n + count * 2 )
166−appendBits16LE = appendBits prim__appendBits16LE
208+appendBits16LE = appendBits prim__appendB16LE
168-- Append count repetitions of a big-endian Bits16 to a Buffer
210-- Append count repetitions of a big-endian Bits16 to a Buffer
170appendBits16BE : Buffer n ->
213appendBits16BE : Buffer n ->
171 ( count : Nat ) ->
214 ( count : Nat ) ->
172 Bits16 ->
215 Bits16 ->
173− Buffer ( n + 2 * count )
216+ Buffer ( n + count * 2 )
174−appendBits16BE = appendBits prim__appendBits16BE
217+appendBits16BE = appendBits prim__appendB16BE
176-- Read a Bits32 in native byte order from a Buffer starting at offset
219-- Read a Bits32 in native byte order from a Buffer starting at offset
178−peekBits32Native : Buffer ( n + 4 ) -> ( offset : Fin n ) -> Bits8
222+peekBits32Native : Buffer ( 4 + n ) ->
223+ ( offset : Fin ( n + 1 ) ) ->
179−peekBits32Native = peekBits prim__peekBits32Native
225+peekBits32Native = peekBits { m = 4 } prim__peekB32Native
181-- Read a little-endian Bits32 from a Buffer starting at offset
227-- Read a little-endian Bits32 from a Buffer starting at offset
183−peekBits32LE : Buffer ( n + 4 ) -> ( offset : Fin n ) -> Bits8
230+peekBits32LE : Buffer ( 4 + n ) -> ( offset : Fin ( n + 1 ) ) -> Bits32
184−peekBits32LE = peekBits prim__peekBits32LE
231+peekBits32LE = peekBits { m = 4 } prim__peekB32LE
186-- Read a big-endian Bits32 from a Buffer starting at offset
233-- Read a big-endian Bits32 from a Buffer starting at offset
188−peekBits32BE : Buffer ( n + 4 ) -> ( offset : Fin n ) -> Bits8
236+peekBits32BE : Buffer ( 4 + n ) -> ( offset : Fin ( n + 1 ) ) -> Bits32
189−peekBits32BE = peekBits prim__peekBits32LE
237+peekBits32BE = peekBits { m = 4 } prim__peekB32BE
191-- Append count repetitions of a Bits32 in native byte order to a Buffer
239-- Append count repetitions of a Bits32 in native byte order to a Buffer
193appendBits32Native : Buffer n ->
242appendBits32Native : Buffer n ->
194 ( count : Nat ) ->
243 ( count : Nat ) ->
195 Bits32 ->
244 Bits32 ->
196− Buffer ( n + 4 * count )
245+ Buffer ( n + count * 4 )
197−appendBits32Native = appendBits prim__appendBits32Native
246+appendBits32Native = appendBits prim__appendB32Native
199-- Append count repetitions of a little-endian Bits32 to a Buffer
248-- Append count repetitions of a little-endian Bits32 to a Buffer
201appendBits32LE : Buffer n ->
251appendBits32LE : Buffer n ->
202 ( count : Nat ) ->
252 ( count : Nat ) ->
203 Bits32 ->
253 Bits32 ->
204− Buffer ( n + 4 * count )
254+ Buffer ( n + count * 4 )
205−appendBits32LE = appendBits prim__appendBits32LE
255+appendBits32LE = appendBits prim__appendB32LE
207-- Append count repetitions of a big-endian Bits32 to a Buffer
257-- Append count repetitions of a big-endian Bits32 to a Buffer
209appendBits32BE : Buffer n ->
260appendBits32BE : Buffer n ->
210 ( count : Nat ) ->
261 ( count : Nat ) ->
211 Bits32 ->
262 Bits32 ->
212− Buffer ( n + 4 * count )
263+ Buffer ( n + count * 4 )
213−appendBits32BE = appendBits prim__appendBits32BE
264+appendBits32BE = appendBits prim__appendB32BE
215-- Read a Bits64 in native byte order from a Buffer starting at offset
266-- Read a Bits64 in native byte order from a Buffer starting at offset
217−peekBits64Native : Buffer ( n + 8 ) -> ( offset : Fin n ) -> Bits8
269+peekBits64Native : Buffer ( 8 + n ) ->
270+ ( offset : Fin ( n + 1 ) ) ->
218−peekBits64Native = peekBits prim__peekBits64Native
272+peekBits64Native = peekBits { m = 8 } prim__peekB64Native
220-- Read a little-endian Bits64 from a Buffer starting at offset
274-- Read a little-endian Bits64 from a Buffer starting at offset
222−peekBits64LE : Buffer ( n + 8 ) -> ( offset : Fin n ) -> Bits8
277+peekBits64LE : Buffer ( 8 + n ) -> ( offset : Fin ( n + 1 ) ) -> Bits64
223−peekBits64LE = peekBits prim__peekBits64LE
278+peekBits64LE = peekBits { m = 8 } prim__peekB64LE
225-- Read a big-endian Bits64 from a Buffer starting at offset
280-- Read a big-endian Bits64 from a Buffer starting at offset
227−peekBits64BE : Buffer ( n + 8 ) -> ( offset : Fin n ) -> Bits8
283+peekBits64BE : Buffer ( 8 + n ) -> ( offset : Fin ( n + 1 ) ) -> Bits64
228−peekBits64BE = peekBits prim__peekBits64LE
284+peekBits64BE = peekBits { m = 8 } prim__peekB64BE
230-- Append count repetitions of a Bits64 in native byte order to a Buffer
286-- Append count repetitions of a Bits64 in native byte order to a Buffer
232appendBits64Native : Buffer n ->
289appendBits64Native : Buffer n ->
233 ( count : Nat ) ->
290 ( count : Nat ) ->
234 Bits64 ->
291 Bits64 ->
235− Buffer ( n + 8 * count )
292+ Buffer ( n + count * 8 )
236−appendBits64Native = appendBits prim__appendBits64Native
293+appendBits64Native = appendBits prim__appendB64Native
238-- Append count repetitions of a little-endian Bits64 to a Buffer
295-- Append count repetitions of a little-endian Bits64 to a Buffer
240appendBits64LE : Buffer n ->
298appendBits64LE : Buffer n ->
241 ( count : Nat ) ->
299 ( count : Nat ) ->
242 Bits64 ->
300 Bits64 ->
243− Buffer ( n + 8 * count )
301+ Buffer ( n + count * 8 )
244−appendBits64LE = appendBits prim__appendBits64LE
302+appendBits64LE = appendBits prim__appendB64LE
246-- Append count repetitions of a big-endian Bits64 to a Buffer
304-- Append count repetitions of a big-endian Bits64 to a Buffer
248appendBits64BE : Buffer n ->
307appendBits64BE : Buffer n ->
249 ( count : Nat ) ->
308 ( count : Nat ) ->
250 Bits64 ->
309 Bits64 ->
251− Buffer ( n + 8 * count )
310+ Buffer ( n + count * 8 )
252−appendBits64BE = appendBits prim__appendBits64BE
311+appendBits64BE = appendBits prim__appendB64BE