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>
17 #ifdef CONFIG_UCW_CLEAN_ABI
18 #define bget5_be_slow ucw_bget5_be_slow
19 #define bget5_le_slow ucw_bget5_le_slow
20 #define bget5_slow ucw_bget5_slow
21 #define bgetl_be_slow ucw_bgetl_be_slow
22 #define bgetl_le_slow ucw_bgetl_le_slow
23 #define bgetl_slow ucw_bgetl_slow
24 #define bgetq_be_slow ucw_bgetq_be_slow
25 #define bgetq_le_slow ucw_bgetq_le_slow
26 #define bgetq_slow ucw_bgetq_slow
27 #define bgetw_be_slow ucw_bgetw_be_slow
28 #define bgetw_le_slow ucw_bgetw_le_slow
29 #define bgetw_slow ucw_bgetw_slow
30 #define bput5_be_slow ucw_bput5_be_slow
31 #define bput5_le_slow ucw_bput5_le_slow
32 #define bput5_slow ucw_bput5_slow
33 #define bputl_be_slow ucw_bputl_be_slow
34 #define bputl_le_slow ucw_bputl_le_slow
35 #define bputl_slow ucw_bputl_slow
36 #define bputq_be_slow ucw_bputq_be_slow
37 #define bputq_le_slow ucw_bputq_le_slow
38 #define bputq_slow ucw_bputq_slow
39 #define bputw_be_slow ucw_bputw_be_slow
40 #define bputw_le_slow ucw_bputw_le_slow
41 #define bputw_slow ucw_bputw_slow
52 * We define several functions to read or write binary integer values.
54 * The name patterns for such routines are:
56 * - `TYPE bget \#\# NAME \#\# ENDIAN(struct fastbuf *f);`
57 * - `void bput \#\# NAME \#\# ENDIAN(struct fastbuf *f, TYPE value);`
59 * where `NAME` together with `TYPE` can be:
61 * - `w` for 16-bit unsigned integers stored in sequences of 2 bytes, the `TYPE` is int
62 * - `l` for 32-bit unsigned integers stored in sequences of 4 bytes, the `TYPE` is uint
63 * - `5` for 40-bit unsigned integers stored in sequences of 5 bytes, the `TYPE` is u64
64 * - `q` for 64-bit unsigned integers stored in sequences of 8 bytes, the `TYPE` is u64
66 * and supported `ENDIAN` suffixes are:
68 * - empty for the default order of bytes (defined by CPU)
69 * - `_le` for little-endian
70 * - `_be` for big-endian
72 * If we fail to read enough bytes because of EOF, the reading function returns `(TYPE)-1`.
76 #define GET_FUNC(type, name, bits, endian) \
77 type bget##name##_##endian##_slow(struct fastbuf *f); \
78 static inline type bget##name##_##endian(struct fastbuf *f) \
80 if (bavailr(f) >= bits/8) \
82 type w = get_u##bits##_##endian(f->bptr); \
87 return bget##name##_##endian##_slow(f); \
90 #define PUT_FUNC(type, name, bits, endian) \
91 void bput##name##_##endian##_slow(struct fastbuf *f, type x); \
92 static inline void bput##name##_##endian(struct fastbuf *f, type x) \
94 if (bavailw(f) >= bits/8) \
96 put_u##bits##_##endian(f->bptr, x); \
100 return bput##name##_##endian##_slow(f, x); \
103 #define FF_ALL_X(type, name, bits, defendian) \
104 GET_FUNC(type, name, bits, be) \
105 GET_FUNC(type, name, bits, le) \
106 PUT_FUNC(type, name, bits, be) \
107 PUT_FUNC(type, name, bits, le) \
108 static inline type bget##name(struct fastbuf *f) { return bget##name##_##defendian(f); } \
109 static inline void bput##name(struct fastbuf *f, type x) { bput##name##_##defendian(f, x); }
111 #define FF_ALL(type, name, bits, defendian) FF_ALL_X(type, name, bits, defendian)
113 FF_ALL(int, w, 16, FF_ENDIAN)
114 FF_ALL(uint, l, 32, FF_ENDIAN)
115 FF_ALL(u64, q, 64, FF_ENDIAN)
116 FF_ALL(u64, 5, 40, FF_ENDIAN)
124 /* I/O on uintptr_t (only native endianity) */
126 #ifdef CPU_64BIT_POINTERS
127 #define bputa(x,p) bputq(x,p)
128 #define bgeta(x) bgetq(x)
130 #define bputa(x,p) bputl(x,p)
131 #define bgeta(x) bgetl(x)