2 * UCW Library -- Fast Buffered I/O on Binary Values
4 * (c) 1997--2007 Martin Mares <mj@ucw.cz>
5 * (c) 2004 Robert Spalek <robert@ucw.cz>
7 * This software may be freely distributed and used according to the terms
8 * of the GNU Lesser General Public License.
11 #ifndef _UCW_FF_BINARY_H
12 #define _UCW_FF_BINARY_H
14 #include "ucw/fastbuf.h"
15 #include "ucw/unaligned.h"
25 * We define several functions to read or write binary integer values.
27 * The name patterns for such routines are:
29 * - `TYPE bget \#\# NAME \#\# ENDIAN(struct fastbuf *f);`
30 * - `void bput \#\# NAME \#\# ENDIAN(struct fastbuf *f, TYPE value);`
32 * where `NAME` together with `TYPE` can be:
34 * - `w` for 16-bit unsigned integers stored in sequences of 2 bytes, the `TYPE` is int
35 * - `l` for 32-bit unsigned integers stored in sequences of 4 bytes, the `TYPE` is uns
36 * - `5` for 40-bit unsigned integers stored in sequences of 5 bytes, the `TYPE` is u64
37 * - `q` for 64-bit unsigned integers stored in sequences of 8 bytes, the `TYPE` is u64
39 * and supported `ENDIAN` suffixes are:
41 * - empty for the default order of bytes (defined by CPU)
42 * - `_le` for little-endian
43 * - `_be` for big-endian
45 * If we fail to read enough bytes because of EOF, the reading function returns `(TYPE)-1`.
49 #define GET_FUNC(type, name, bits, endian) \
50 type bget##name##_##endian##_slow(struct fastbuf *f); \
51 static inline type bget##name##_##endian(struct fastbuf *f) \
53 if (bavailr(f) >= bits/8) \
55 type w = get_u##bits##_##endian(f->bptr); \
60 return bget##name##_##endian##_slow(f); \
63 #define PUT_FUNC(type, name, bits, endian) \
64 void bput##name##_##endian##_slow(struct fastbuf *f, type x); \
65 static inline void bput##name##_##endian(struct fastbuf *f, type x) \
67 if (bavailw(f) >= bits/8) \
69 put_u##bits##_##endian(f->bptr, x); \
73 return bput##name##_##endian##_slow(f, x); \
76 #define FF_ALL_X(type, name, bits, defendian) \
77 GET_FUNC(type, name, bits, be) \
78 GET_FUNC(type, name, bits, le) \
79 PUT_FUNC(type, name, bits, be) \
80 PUT_FUNC(type, name, bits, le) \
81 static inline type bget##name(struct fastbuf *f) { return bget##name##_##defendian(f); } \
82 static inline void bput##name(struct fastbuf *f, type x) { bput##name##_##defendian(f, x); }
84 #define FF_ALL(type, name, bits, defendian) FF_ALL_X(type, name, bits, defendian)
86 FF_ALL(int, w, 16, FF_ENDIAN)
87 FF_ALL(uns, l, 32, FF_ENDIAN)
88 FF_ALL(u64, q, 64, FF_ENDIAN)
89 FF_ALL(u64, 5, 40, FF_ENDIAN)
97 /* I/O on uintptr_t (only native endianity) */
99 #ifdef CPU_64BIT_POINTERS
100 #define bputa(x,p) bputq(x,p)
101 #define bgeta(x) bgetq(x)
103 #define bputa(x,p) bputl(x,p)
104 #define bgeta(x) bgetl(x)