Rizin
unix-like reverse engineering framework and cli tools
readbits.h
Go to the documentation of this file.
1 /* This file is part of libmspack.
2  * (C) 2003-2010 Stuart Caie.
3  *
4  * libmspack is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6  *
7  * For further details, see the file COPYING.LIB distributed with libmspack
8  */
9 
10 #ifndef MSPACK_READBITS_H
11 #define MSPACK_READBITS_H 1
12 
13 /* this header defines macros that read data streams by
14  * the individual bits
15  *
16  * INIT_BITS initialises bitstream state in state structure
17  * STORE_BITS stores bitstream state in state structure
18  * RESTORE_BITS restores bitstream state from state structure
19  * ENSURE_BITS(n) ensure there are at least N bits in the bit buffer
20  * READ_BITS(var,n) takes N bits from the buffer and puts them in var
21  * PEEK_BITS(n) extracts without removing N bits from the bit buffer
22  * REMOVE_BITS(n) removes N bits from the bit buffer
23  *
24  * READ_BITS simply calls ENSURE_BITS, PEEK_BITS and REMOVE_BITS,
25  * which means it's limited to reading the number of bits you can
26  * ensure at any one time. It also fails if asked to read zero bits.
27  * If you need to read zero bits, or more bits than can be ensured in
28  * one go, use READ_MANY_BITS instead.
29  *
30  * These macros have variable names baked into them, so to use them
31  * you have to define some macros:
32  * - BITS_TYPE: the type name of your state structure
33  * - BITS_VAR: the variable that points to your state structure
34  * - define BITS_ORDER_MSB if bits are read from the MSB, or
35  * define BITS_ORDER_LSB if bits are read from the LSB
36  * - READ_BYTES: some code that reads more data into the bit buffer,
37  * it should use READ_IF_NEEDED (calls read_input if the byte buffer
38  * is empty), then INJECT_BITS(data,n) to put data from the byte
39  * buffer into the bit buffer.
40  *
41  * You also need to define some variables and structure members:
42  * - unsigned char *i_ptr; // current position in the byte buffer
43  * - unsigned char *i_end; // end of the byte buffer
44  * - unsigned int bit_buffer; // the bit buffer itself
45  * - unsigned int bits_left; // number of bits remaining
46  *
47  * If you use read_input() and READ_IF_NEEDED, they also expect these
48  * structure members:
49  * - struct mspack_system *sys; // to access sys->read()
50  * - unsigned int error; // to record/return read errors
51  * - unsigned char input_end; // to mark reaching the EOF
52  * - unsigned char *inbuf; // the input byte buffer
53  * - unsigned int inbuf_size; // the size of the input byte buffer
54  *
55  * Your READ_BYTES implementation should read data from *i_ptr and
56  * put them in the bit buffer. READ_IF_NEEDED will call read_input()
57  * if i_ptr reaches i_end, and will fill up inbuf and set i_ptr to
58  * the start of inbuf and i_end to the end of inbuf.
59  *
60  * If you're reading in MSB order, the routines work by using the area
61  * beyond the MSB and the LSB of the bit buffer as a free source of
62  * zeroes when shifting. This avoids having to mask any bits. So we
63  * have to know the bit width of the bit buffer variable. We use
64  * <limits.h> and CHAR_BIT to find the size of the bit buffer in bits.
65  *
66  * If you are reading in LSB order, bits need to be masked. Normally
67  * this is done by computing the mask: N bits are masked by the value
68  * (1<<N)-1). However, you can define BITS_LSB_TABLE to use a lookup
69  * table instead of computing this. This adds two new macros,
70  * PEEK_BITS_T and READ_BITS_T which work the same way as PEEK_BITS
71  * and READ_BITS, except they use this lookup table. This is useful if
72  * you need to look up a number of bits that are only known at
73  * runtime, so the bit mask can't be turned into a constant by the
74  * compiler.
75 
76  * The bit buffer datatype should be at least 32 bits wide: it must be
77  * possible to ENSURE_BITS(17), so it must be possible to add 16 new bits
78  * to the bit buffer when the bit buffer already has 1 to 15 bits left.
79  */
80 
81 #ifndef BITS_VAR
82 # error "define BITS_VAR as the state structure poiner variable name"
83 #endif
84 #ifndef BITS_TYPE
85 # error "define BITS_TYPE as the state structure type"
86 #endif
87 #if defined(BITS_ORDER_MSB) && defined(BITS_ORDER_LSB)
88 # error "you must define either BITS_ORDER_MSB or BITS_ORDER_LSB"
89 #else
90 # if !(defined(BITS_ORDER_MSB) || defined(BITS_ORDER_LSB))
91 # error "you must define BITS_ORDER_MSB or BITS_ORDER_LSB"
92 # endif
93 #endif
94 
95 #if HAVE_LIMITS_H
96 # include <limits.h>
97 #endif
98 #ifndef CHAR_BIT
99 # define CHAR_BIT (8)
100 #endif
101 #define BITBUF_WIDTH (sizeof(bit_buffer) * CHAR_BIT)
102 
103 #define INIT_BITS do { \
104  BITS_VAR->i_ptr = &BITS_VAR->inbuf[0]; \
105  BITS_VAR->i_end = &BITS_VAR->inbuf[0]; \
106  BITS_VAR->bit_buffer = 0; \
107  BITS_VAR->bits_left = 0; \
108  BITS_VAR->input_end = 0; \
109 } while (0)
110 
111 #define STORE_BITS do { \
112  BITS_VAR->i_ptr = i_ptr; \
113  BITS_VAR->i_end = i_end; \
114  BITS_VAR->bit_buffer = bit_buffer; \
115  BITS_VAR->bits_left = bits_left; \
116 } while (0)
117 
118 #define RESTORE_BITS do { \
119  i_ptr = BITS_VAR->i_ptr; \
120  i_end = BITS_VAR->i_end; \
121  bit_buffer = BITS_VAR->bit_buffer; \
122  bits_left = BITS_VAR->bits_left; \
123 } while (0)
124 
125 #define ENSURE_BITS(nbits) do { \
126  while (bits_left < (nbits)) READ_BYTES; \
127 } while (0)
128 
129 #define READ_BITS(val, nbits) do { \
130  ENSURE_BITS(nbits); \
131  (val) = PEEK_BITS(nbits); \
132  REMOVE_BITS(nbits); \
133 } while (0)
134 
135 #define READ_MANY_BITS(val, bits) do { \
136  unsigned char needed = (bits), bitrun; \
137  (val) = 0; \
138  while (needed > 0) { \
139  if (bits_left <= (BITBUF_WIDTH - 16)) READ_BYTES; \
140  bitrun = (bits_left < needed) ? bits_left : needed; \
141  (val) = ((val) << bitrun) | PEEK_BITS(bitrun); \
142  REMOVE_BITS(bitrun); \
143  needed -= bitrun; \
144  } \
145 } while (0)
146 
147 #ifdef BITS_ORDER_MSB
148 # define PEEK_BITS(nbits) (bit_buffer >> (BITBUF_WIDTH - (nbits)))
149 # define REMOVE_BITS(nbits) ((bit_buffer <<= (nbits)), (bits_left -= (nbits)))
150 # define INJECT_BITS(bitdata,nbits) ((bit_buffer |= \
151  (bitdata) << (BITBUF_WIDTH - (nbits) - bits_left)), (bits_left += (nbits)))
152 #else /* BITS_ORDER_LSB */
153 # define PEEK_BITS(nbits) (bit_buffer & ((1 << (nbits))-1))
154 # define REMOVE_BITS(nbits) ((bit_buffer >>= (nbits)), (bits_left -= (nbits)))
155 # define INJECT_BITS(bitdata,nbits) ((bit_buffer |= \
156  (bitdata) << bits_left), (bits_left += (nbits)))
157 #endif
158 
159 #ifdef BITS_LSB_TABLE
160 /* lsb_bit_mask[n] = (1 << n) - 1 */
161 static const unsigned short lsb_bit_mask[17] = {
162  0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
163  0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
164 };
165 # define PEEK_BITS_T(nbits) (bit_buffer & lsb_bit_mask[(nbits)])
166 # define READ_BITS_T(val, nbits) do { \
167  ENSURE_BITS(nbits); \
168  (val) = PEEK_BITS_T(nbits); \
169  REMOVE_BITS(nbits); \
170 } while (0)
171 #endif
172 
173 #ifndef BITS_NO_READ_INPUT
174 # define READ_IF_NEEDED do { \
175  if (i_ptr >= i_end) { \
176  if (read_input(BITS_VAR)) \
177  return BITS_VAR->error; \
178  i_ptr = BITS_VAR->i_ptr; \
179  i_end = BITS_VAR->i_end; \
180  } \
181 } while (0)
182 
183 static int read_input(BITS_TYPE *p) {
184  int read = p->sys->read(p->input, &p->inbuf[0], (int)p->inbuf_size);
185  if (read < 0) return p->error = MSPACK_ERR_READ;
186 
187  /* we might overrun the input stream by asking for bits we don't use,
188  * so fake 2 more bytes at the end of input */
189  if (read == 0) {
190  if (p->input_end) {
191  D(("out of input bytes"))
192  return p->error = MSPACK_ERR_READ;
193  }
194  else {
195  read = 2;
196  p->inbuf[0] = p->inbuf[1] = 0;
197  p->input_end = 1;
198  }
199  }
200 
201  /* update i_ptr and i_end */
202  p->i_ptr = &p->inbuf[0];
203  p->i_end = &p->inbuf[read];
204  return MSPACK_ERR_OK;
205 }
206 #endif
207 #endif
#define D
Definition: block.c:38
#define BITS_TYPE
Definition: lzxd.c:83
#define MSPACK_ERR_OK
Definition: mspack.h:485
#define MSPACK_ERR_READ
Definition: mspack.h:491
static int read_input(BITS_TYPE *p)
Definition: readbits.h:183
void * p
Definition: libc.cpp:67
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115