+1
-31
bini.c
+1
-31
bini.c
···
1
-
/*
2
-
Bini license: BSD 3-Clause.
3
-
4
-
Copyright 2025 Emmeline Coats
5
-
6
-
Redistribution and use in source and binary forms, with or without
7
-
modification, are permitted provided that the following conditions are met:
8
-
9
-
1. Redistributions of source code must retain the above copyright notice, this
10
-
list of conditions and the following disclaimer.
11
-
12
-
2. Redistributions in binary form must reproduce the above copyright notice,
13
-
this list of conditions and the following disclaimer in the documentation
14
-
and/or other materials provided with the distribution.
15
-
16
-
3. Neither the name of the copyright holder nor the names of its contributors
17
-
may be used to endorse or promote products derived from this software
18
-
without specific prior written permission.
19
-
20
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
21
-
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
-
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
-
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
-
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
-
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
-
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
-
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
-
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
-
*/
31
-
32
1
#ifndef bini_impl
33
2
#define bini_impl
34
3
#endif
4
+
35
5
#include <bini.h>
+72
-36
bini.h
+72
-36
bini.h
···
1
-
#ifndef __bini__
2
-
#define __bini__
1
+
#ifndef __kf_bini__
2
+
#define __kf_bini__
3
3
4
-
/* License at end of file. */
4
+
/*
5
+
bini.h: endian-independent binary IO.
6
+
License: BSD 3-Clause. See EOF for license text.
7
+
8
+
Version: 1.1
9
+
10
+
Changelog:
11
+
1.0 (Dec 28, 2025): Initial version.
12
+
1.1 (Dec 30, 2025): Use an offset instead of shifting the
13
+
byte buffer so carelessly. _bini_grow will shift the
14
+
buffer on-demand instead so as to conserve CPU time.
15
+
*/
5
16
6
17
/* Used to add functions for version-specific types. */
7
18
#define bini_c 1989
···
92
103
{
93
104
/* Read mode for the stream. Should be either BINI_STACK or BINI_STREAM. */
94
105
int mode;
106
+
/* Offset from the start of the buffer in bytes. Only used for BINI_STREAM. */
107
+
size_t off;
95
108
size_t cap;
96
109
size_t len;
97
110
uint8_t *buffer;
···
117
130
buffer, and frees the provided variable as well. */
118
131
void bini_close(struct bini_stream *bs);
119
132
133
+
/* Shift a binary stream, resetting the offset and shifting the array. */
134
+
void bini_shift(struct bini_stream *);
120
135
/* Flush a binary stream, clearing its buffer. */
121
136
int bini_flush(struct bini_stream *);
122
137
/* Dump the binary stream's buffer to fp. */
···
247
262
bs->buffer = calloc(BINI_BUFSIZ, 1);
248
263
if (!bs->buffer)
249
264
return BINI_ERR;
265
+
bs->off = 0;
250
266
bs->len = 0;
251
267
bs->cap = BINI_BUFSIZ;
252
268
bs->mode = BINI_STREAM;
···
270
286
{
271
287
bini_end(bs);
272
288
free(bs);
289
+
}
290
+
291
+
static
292
+
#if bini_c >= 1999
293
+
inline
294
+
#endif
295
+
void _bini_shiftleft(struct bini_stream *bs, size_t n)
296
+
{
297
+
size_t i;
298
+
_bini_dbg("shift %d: (len=%lu)\n", n, bs->len);
299
+
for (i = 0 ; i < bs->len ; i++)
300
+
{
301
+
if (i+n >= bs->len)
302
+
{
303
+
_bini_dbg(" %d: [%d] (out of bounds) to [%d]\n", n, i+n, i);
304
+
bs->buffer[i] = 0;
305
+
continue;
306
+
}
307
+
_bini_dbg(" %d: [%d] (%02x '%c') to [%d]\n",
308
+
n,
309
+
i+n,
310
+
bs->buffer[i+n],
311
+
bs->buffer[i+n],
312
+
i);
313
+
bs->buffer[i] = bs->buffer[i+n];
314
+
}
315
+
}
316
+
317
+
void bini_shift(struct bini_stream *bs)
318
+
{
319
+
_bini_shiftleft(bs, bs->off);
320
+
bs->off = 0;
273
321
}
274
322
275
323
int bini_flush(struct bini_stream *bs)
···
299
347
int _bini_grow(struct bini_stream *bs, size_t n)
300
348
{
301
349
uint8_t *newbuf;
350
+
351
+
if (bs->off + bs->len + n < bs->cap)
352
+
return BINI_OK;
353
+
354
+
/* Shifting the array could give enough space to
355
+
fit `n`, avoiding the need to realloc. */
356
+
bini_shift(bs);
357
+
302
358
if (bs->len + n < bs->cap)
303
359
return BINI_OK;
360
+
304
361
while (bs->len + n >= bs->cap)
305
362
{
306
363
newbuf = realloc(bs->buffer, bs->cap * 2);
···
309
366
bs->buffer = newbuf;
310
367
bs->cap *= 2;
311
368
}
369
+
312
370
return BINI_OK;
313
371
}
314
372
···
326
384
return fwrite(bs->buffer, size, n, fp);
327
385
}
328
386
329
-
static
330
-
#if bini_c >= 1999
331
-
inline
332
-
#endif
333
-
void _bini_shiftleft(struct bini_stream *bs, size_t n)
334
-
{
335
-
size_t i;
336
-
_bini_dbg("shift %d: (len=%lu)\n", n, bs->len);
337
-
for (i = 0 ; i < bs->len ; i++)
338
-
{
339
-
if (i+n >= bs->len)
340
-
{
341
-
_bini_dbg(" %d: [%d] (out of bounds) to [%d]\n", n, i+n, i);
342
-
bs->buffer[i] = 0;
343
-
continue;
344
-
}
345
-
_bini_dbg(" %d: [%d] (%02x '%c') to [%d]\n",
346
-
n,
347
-
i+n,
348
-
bs->buffer[i+n],
349
-
bs->buffer[i+n],
350
-
i);
351
-
bs->buffer[i] = bs->buffer[i+n];
352
-
}
353
-
}
354
-
355
387
#define _bini_rwx(_type, _name) \
356
388
void bini_w##_name(struct bini_stream *bs, _type v) \
357
389
{ \
···
368
400
l ? sizeof(v)-i-1 : i, \
369
401
bytes[l ? sizeof(v)-i-1 : i], \
370
402
bytes[l ? sizeof(v)-i-1 : i], \
371
-
bs->len+i); \
372
-
bs->buffer[bs->len+i] = bytes[l ? sizeof(v)-i-1 : i]; \
403
+
bs->off+bs->len+i); \
404
+
bs->buffer[bs->off+bs->len+i] = bytes[l ? sizeof(v)-i-1 : i]; \
373
405
} \
374
406
bs->len += i; \
375
407
_bini_dbg("-> %s: %d (%lu bytes)\n", __FUNCTION__, *(int *)bytes, sizeof(v)); \
···
383
415
int m = bs->mode == BINI_STREAM; \
384
416
for (i = 0 ; i < sizeof(v) ; i++) \
385
417
{ \
418
+
const size_t p = bs->off + (m ? i : (bs->len-sizeof(v)+i)); \
386
419
_bini_dbg("%s: byte index [%lu] from buffer index %lu (= %02x '%c')\n", \
387
420
__FUNCTION__, \
388
421
l ? sizeof(v)-i-1 : i, \
389
-
m ? i : (bs->len-sizeof(v)+i), \
390
-
bs->buffer[m ? i : (bs->len-sizeof(v)+i)], \
391
-
bs->buffer[m ? i : (bs->len-sizeof(v)+i)]); \
392
-
bytes[l ? sizeof(v)-i-1 : i] = bs->buffer[m ? i : (bs->len-sizeof(v)+i)]; \
422
+
p, \
423
+
bs->buffer[p], \
424
+
bs->buffer[p]); \
425
+
bytes[l ? sizeof(v)-i-1 : i] = bs->buffer[p]; \
393
426
} \
394
427
if (m) \
395
-
_bini_shiftleft(bs, i); \
428
+
{ \
429
+
bs->off += i; \
430
+
/* _bini_shiftleft(bs, i); */ \
431
+
} \
396
432
bs->len -= i; \
397
433
return v; \
398
434
}