X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/mLib/blobdiff_plain/31d0247cc58abc0b0720aa7e9972011c5a66995c..08bb7015a9e28c5c9d38fe05a6f6644bc21fa527:/struct/buf.h diff --git a/struct/buf.h b/struct/buf.h index 7dd5555..2a37220 100644 --- a/struct/buf.h +++ b/struct/buf.h @@ -142,6 +142,11 @@ extern void buf_init(buf */*b*/, void */*p*/, size_t /*sz*/); */ extern void dbuf_create(dbuf */*db*/); +#define DBCREATE(db) do { \ + (db)->_b.base = (db)->_b.p = (db)->_b.limit = 0; \ + (db)->_b.f = BF_ALLOC | BF_WRITE; \ + (db)->a = &arena_stdlib; (db)->sz = 0; \ +} while (0) /* --- @dbuf_reset@ --- * * @@ -153,7 +158,6 @@ extern void dbuf_create(dbuf */*db*/); */ extern void dbuf_reset(dbuf */*db*/); - #define DBRESET(db) do { \ (db)->_b.p = (db)->_b.base; (db)->_b.limit = (db)->_b.base + (db)->sz; \ (db)->_b.f = ((db)->_b.f&~BF_BROKEN) | BF_WRITE; \ @@ -169,6 +173,11 @@ extern void dbuf_reset(dbuf */*db*/); */ extern void dbuf_destroy(dbuf */*db*/); +#define DBDESTROY(db) do { \ + if ((db)->_b.base) x_free((db)->a, (db)->_b.base); \ + (db)->_b.base = (db)->_b.p = (db)->_b.limit = 0; \ + (db)->_b.f = BF_ALLOC | BF_WRITE; (db)->sz = 0; \ +} while (0) /* --- @{,d}buf_break@ --- * * @@ -182,6 +191,8 @@ extern void dbuf_destroy(dbuf */*db*/); extern int buf_break(buf */*b*/); extern int dbuf_break(dbuf */*db*/); #define dbuf_break(db) (buf_break(DBUF_BUF(db))) +#define BBREAK(b) do { (b)->f |= BF_BROKEN; } while (0) +#define DBBREAK(db) BBREAK(DBUF_BUF(db)) /* --- @{,d}buf_flip@ --- * * @@ -389,6 +400,60 @@ extern int dbuf_putk64b(dbuf */*db*/, kludge64 /*w*/); #define dbuf_putk64l(db, w) (buf_putk64l(DBUF_BUF(db), (w))) #define dbuf_putk64b(db, w) (buf_putk64b(DBUF_BUF(db), (w))) +/* --- @buf_getf{32,64}{,l,b} --- * + * + * Arguments: @buf *b@ = a buffer to read from + * @float *x_out@, @double *x_out@ = where to put the result + * + * Returns: Zero on success, %$-1$% on failure (and the buffer is + * broken). + * + * Use: Get an IEEE Binary32 or Binary64 value from the buffer. + * Conversion is performed using the `fltfmt' machinery, with + * the usual round-to-nearest/ties-to-even rounding mode. + */ + +extern int buf_getf32(buf */*b*/, float */*x_out*/); +extern int buf_getf32l(buf */*b*/, float */*x_out*/); +extern int buf_getf32b(buf */*b*/, float */*x_out*/); +#define dbuf_getf32(db, x_out) (buf_getf32(DBUF_BUF(db), (x_out))) +#define dbuf_getf32l(db, x_out) (buf_getf32l(DBUF_BUF(db), (x_out))) +#define dbuf_getf32b(db, x_out) (buf_getf32b(DBUF_BUF(db), (x_out))) + +extern int buf_getf64(buf */*b*/, double */*x_out*/); +extern int buf_getf64l(buf */*b*/, double */*x_out*/); +extern int buf_getf64b(buf */*b*/, double */*x_out*/); +#define dbuf_getf64(db, x_out) (buf_getf64(DBUF_BUF(db), (x_out))) +#define dbuf_getf64l(db, x_out) (buf_getf64l(DBUF_BUF(db), (x_out))) +#define dbuf_getf64b(db, x_out) (buf_getf64b(DBUF_BUF(db), (x_out))) + +/* --- @buf_putf{32,64}{,l,b} --- * + * + * Arguments: @buf *b@ = a buffer to write to + * @double x@ = a number to write + * + * Returns: Zero on success, %$-1$% on failure (and the buffer is + * broken). + * + * Use: Get an IEEE Binary32 or Binary64 value from the buffer. + * Conversion is performed using the `fltfmt' machinery, with + * the usual round-to-nearest/ties-to-even rounding mode. + */ + +extern int buf_putf32(buf */*b*/, float /*x*/); +extern int buf_putf32l(buf */*b*/, float /*x*/); +extern int buf_putf32b(buf */*b*/, float /*x*/); +#define dbuf_putf32(db, x) (buf_putf32(DBUF_BUF(db), (x))) +#define dbuf_putf32l(db, x) (buf_putf32l(DBUF_BUF(db), (x))) +#define dbuf_putf32b(db, x) (buf_putf32b(DBUF_BUF(db), (x))) + +extern int buf_putf64(buf */*b*/, double /*x*/); +extern int buf_putf64l(buf */*b*/, double /*x*/); +extern int buf_putf64b(buf */*b*/, double /*x*/); +#define dbuf_putf64(db, x) (buf_putf64(DBUF_BUF(db), (x))) +#define dbuf_putf64l(db, x) (buf_putf64l(DBUF_BUF(db), (x))) +#define dbuf_putf64b(db, x) (buf_putf64b(DBUF_BUF(db), (x))) + /* --- @{,d}buf_getmem{8,{16,24,32,64}{,l,b},z} --- * * * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block @@ -599,63 +664,6 @@ BUF_DOSUFFIXES(BUF_DECL_PUTSTR_) #define dbuf_putstr64b(db, p) (buf_putstr64b(DBUF_BUF(db), (p))) #define dbuf_putstrz(db, p) (buf_putstrz(DBUF_BUF(db), (p))) -/* --- @{,d}buf_getf64{,l,b} --- * - * - * Arguments: @buf *b@ = pointer to a bfufer block - * @double *x_out@ = where to put the result - * - * Returns: Zero on success, @-1@ on failure (and the buffer is broken). - * - * If the system supports NaNs, then any encoded NaN is returned - * as the value of @NAN@ in @@; otherwise, this function - * reports failure. - * - * In general, values are rounded to the nearest available - * value, in the way that the system usually rounds. If the - * system doesn't support infinities, then any encoded infinity - * is reported as the largest-possible-magnitude finite value - * instead. - */ - -extern int buf_getf64(buf */*b*/, double */*x_out*/); -extern int buf_getf64l(buf */*b*/, double */*x_out*/); -extern int buf_getf64b(buf */*b*/, double */*x_out*/); -extern int dbuf_getf64(dbuf */*db*/, double */*x_out*/); -extern int dbuf_getf64l(dbuf */*db*/, double */*x_out*/); -extern int dbuf_getf64b(dbuf */*db*/, double */*x_out*/); -#define dbuf_getf64(db, x_out) (buf_getf64(DBUF_BUF(db), (x_out))) -#define dbuf_getf64l(db, x_out) (buf_getf64l(DBUF_BUF(db), (x_out))) -#define dbuf_getf64b(db, x_out) (buf_getf64b(DBUF_BUF(db), (x_out))) - -/* --- @{,d}buf_putf64{,l,b} --- * - * - * Arguments: @buf *b@ or @dbuf *db@ = pointer to a buffer block - * @double x@ = a number to write - * - * Returns: Zero on success, @-1@ on failure (and the buffer is broken). - * - * On C89, this function can't detect negative zero so these - * will be silently written as positive zero. - * - * This function doesn't distinguish NaNs. Any NaN is written - * as a quiet NaN with all payload bits zero. - * - * A finite value with too large a magnitude to be represented - * is rounded to the appropriate infinity. Other finite values - * are rounded as necessary, in the usual IEEE 754 round-to- - * nearest-or-even way. - */ - -extern int buf_putf64(buf */*b*/, double /*x*/); -extern int buf_putf64l(buf */*b*/, double /*x*/); -extern int buf_putf64b(buf */*b*/, double /*x*/); -extern int dbuf_putf64(dbuf */*db*/, double /*x*/); -extern int dbuf_putf64l(dbuf */*db*/, double /*x*/); -extern int dbuf_putf64b(dbuf */*db*/, double /*x*/); -#define dbuf_putf64(db, x) (buf_putf64(DBUF_BUF(db), (x))) -#define dbuf_putf64l(db, x) (buf_putf64l(DBUF_BUF(db), (x))) -#define dbuf_putf64b(db, x) (buf_putf64b(DBUF_BUF(db), (x))) - /* --- @{,D}BUF_ENCLOSETAG@ --- * * * Arguments: @tag@ = a control-structure macro tag @@ -683,8 +691,8 @@ extern int dbuf_putf64b(dbuf */*db*/, double /*x*/); }) \ MC_AFTER(tag##__poke, { \ size_t _delta = BLEN(b) - (mk) - (lensz); \ - assert(check); \ - if (BOK(b)) poke(BBASE(b) + (mk), _delta); \ + if (!(check)) (b)->f |= BF_BROKEN; \ + else if (BOK(b)) poke(BBASE(b) + (mk), _delta); \ }) #define DBUF_ENCLOSETAG(tag, b, mk, check, poke, lensz) \ @@ -705,17 +713,17 @@ extern int dbuf_putf64b(dbuf */*db*/, double /*x*/); * @kludge64@ machinery. */ -#define BUF_STORESZK64(p, sz) \ +#define MLIB__BUF_STORESZK64(p, sz) \ do { kludge64 _k; ASSIGN64(_k, (sz)); STORE64_((p), _k); } while (0) -#define BUF_STORESZK64_B(p, sz) \ +#define MLIB__BUF_STORESZK64_B(p, sz) \ do { kludge64 _k; ASSIGN64(_k, (sz)); STORE64_B_((p), _k); } while (0) -#define BUF_STORESZK64_L(p, sz) \ +#define MLIB__BUF_STORESZK64_L(p, sz) \ do { kludge64 _k; ASSIGN64(_k, (sz)); STORE64_L_((p), _k); } while (0) #define BUF_ENCLOSEITAG(tag, b, mk, W) \ BUF_ENCLOSETAG(tag, (b), (mk), (_delta <= MASK##W), STORE##W, SZ_##W) -#define BUF_ENCLOSEKTAG(tag, b, mk, W) \ - BUF_ENCLOSE(tag, (b), (mk), 1, BUF_STORESZK##W, 8) +#define BUF_ENCLOSEKTAG(tag, b, mk, W) \ + BUF_ENCLOSETAG(tag, (b), (mk), 1, MLIB__BUF_STORESZK##W, 8) #define BUF_ENCLOSEZTAG(tag, b) \ MC_AFTER(tag##__zero, { buf_putbyte((b), 0); }) @@ -743,43 +751,43 @@ extern int dbuf_putf64b(dbuf */*db*/, double /*x*/); #define BUF_ENCLOSE8(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 8) #define BUF_ENCLOSE16(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 16) -#define BUF_ENCLOSE16_B(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 16_B) #define BUF_ENCLOSE16_L(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 16_L) +#define BUF_ENCLOSE16_B(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 16_B) #define BUF_ENCLOSE24(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 24) -#define BUF_ENCLOSE24_B(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 24_B) #define BUF_ENCLOSE24_L(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 24_L) +#define BUF_ENCLOSE24_B(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 24_B) #define BUF_ENCLOSE32(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 32) -#define BUF_ENCLOSE32_B(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 32_B) #define BUF_ENCLOSE32_L(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 32_L) +#define BUF_ENCLOSE32_B(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 32_B) #ifdef HAVE_UINT64 # define BUF_ENCLOSE64(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 64) -# define BUF_ENCLOSE64_B(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 64_B) # define BUF_ENCLOSE64_L(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 64_L) +# define BUF_ENCLOSE64_B(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 64_B) #else # define BUF_ENCLOSE64(b, mk) BUF_ENCLOSEKTAG(encl, (b), (mk), 64) -# define BUF_ENCLOSE64_B(b, mk) BUF_ENCLOSEKTAG(encl, (b), (mk), 64_B) # define BUF_ENCLOSE64_L(b, mk) BUF_ENCLOSEKTAG(encl, (b), (mk), 64_L) +# define BUF_ENCLOSE64_B(b, mk) BUF_ENCLOSEKTAG(encl, (b), (mk), 64_B) #endif #define BUF_ENCLOSEZ(b) BUF_ENCLOSEZTAG(encl, (b)) #define DBUF_ENCLOSE8(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 8) #define DBUF_ENCLOSE16(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 16) -#define DBUF_ENCLOSE16_B(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 16_B) #define DBUF_ENCLOSE16_L(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 16_L) +#define DBUF_ENCLOSE16_B(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 16_B) #define DBUF_ENCLOSE24(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 24) -#define DBUF_ENCLOSE24_B(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 24_B) #define DBUF_ENCLOSE24_L(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 24_L) +#define DBUF_ENCLOSE24_B(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 24_B) #define DBUF_ENCLOSE32(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 32) -#define DBUF_ENCLOSE32_B(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 32_B) #define DBUF_ENCLOSE32_L(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 32_L) +#define DBUF_ENCLOSE32_B(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 32_B) #ifdef HAVE_UINT64 # define DBUF_ENCLOSE64(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 64) -# define DBUF_ENCLOSE64_B(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 64_B) # define DBUF_ENCLOSE64_L(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 64_L) +# define DBUF_ENCLOSE64_B(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 64_B) #else # define DBUF_ENCLOSE64(db, mk) DBUF_ENCLOSEKTAG(encl, (db), (mk), 64) -# define DBUF_ENCLOSE64_B(db, mk) DBUF_ENCLOSEKTAG(encl, (db), (mk), 64_B) # define DBUF_ENCLOSE64_L(db, mk) DBUF_ENCLOSEKTAG(encl, (db), (mk), 64_L) +# define DBUF_ENCLOSE64_B(db, mk) DBUF_ENCLOSEKTAG(encl, (db), (mk), 64_B) #endif #define DBUF_ENCLOSEZ(db) DBUF_ENCLOSEZTAG(encl, (db))