]> mj.ucw.cz Git - libucw.git/blob - ucw/ff-binary.h
ucw docs: lizard_decompress_save update
[libucw.git] / ucw / ff-binary.h
1 /*
2  *      UCW Library -- Fast Buffered I/O on Binary Values
3  *
4  *      (c) 1997--2007 Martin Mares <mj@ucw.cz>
5  *      (c) 2004 Robert Spalek <robert@ucw.cz>
6  *
7  *      This software may be freely distributed and used according to the terms
8  *      of the GNU Lesser General Public License.
9  */
10
11 #ifndef _UCW_FF_BINARY_H
12 #define _UCW_FF_BINARY_H
13
14 #include "ucw/fastbuf.h"
15 #include "ucw/unaligned.h"
16
17 #ifdef CPU_BIG_ENDIAN
18 #define FF_ENDIAN be
19 #else
20 #define FF_ENDIAN le
21 #endif
22
23 /***
24  *
25  * We define several functions to read or write binary integer values.
26  *
27  * The name patterns for such routines are:
28  *
29  * - `TYPE bget \#\# NAME \#\# ENDIAN(struct fastbuf *f);`
30  * - `void bput \#\# NAME \#\# ENDIAN(struct fastbuf *f, TYPE value);`
31  *
32  * where `NAME` together with `TYPE` can be:
33  *
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
38  *
39  * and supported `ENDIAN` suffixes are:
40  *
41  * - empty for the default order of bytes (defined by CPU)
42  * - `_le` for little-endian
43  * - `_be` for big-endian
44  *
45  * If we fail to read enough bytes because of EOF, the reading function returns `(TYPE)-1`.
46  *
47  ***/
48
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)   \
52   {                                                             \
53     if (bavailr(f) >= bits/8)                                   \
54       {                                                         \
55         type w = get_u##bits##_##endian(f->bptr);               \
56         f->bptr += bits/8;                                      \
57         return w;                                               \
58       }                                                         \
59     else                                                        \
60       return bget##name##_##endian##_slow(f);                   \
61   }
62
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)   \
66   {                                                             \
67     if (bavailw(f) >= bits/8)                                   \
68       {                                                         \
69         put_u##bits##_##endian(f->bptr, x);                     \
70         f->bptr += bits/8;                                      \
71       }                                                         \
72     else                                                        \
73       return bput##name##_##endian##_slow(f, x);                \
74   }
75
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); }
83
84 #define FF_ALL(type, name, bits, defendian) FF_ALL_X(type, name, bits, defendian)
85
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)
90
91 #undef GET_FUNC
92 #undef PUT_FUNC
93 #undef FF_ENDIAN
94 #undef FF_ALL_X
95 #undef FF_ALL
96
97 /* I/O on uintptr_t (only native endianity) */
98
99 #ifdef CPU_64BIT_POINTERS
100 #define bputa(x,p) bputq(x,p)
101 #define bgeta(x) bgetq(x)
102 #else
103 #define bputa(x,p) bputl(x,p)
104 #define bgeta(x) bgetl(x)
105 #endif
106
107 #endif