Wrote bitwise reader; needs tests
This commit is contained in:
parent
5ee7865458
commit
7adae0da7c
4 changed files with 67 additions and 5 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef LIB_ALLOCATOR__H__
|
#ifndef HAMMER_ALLOCATOR__H__
|
||||||
#define LIB_ALLOCATOR__H__
|
#define HAMMER_ALLOCATOR__H__
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
typedef struct arena* arena_t; // hidden implementation
|
typedef struct arena* arena_t; // hidden implementation
|
||||||
|
|
|
||||||
49
src/bitreader.c
Normal file
49
src/bitreader.c
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "internal.h"
|
||||||
|
#include "hammer.h"
|
||||||
|
|
||||||
|
#define LSB(range) (0:range)
|
||||||
|
#define MSB(range) (1:range)
|
||||||
|
#define LDB(range,i) (((i)>>LSB(range))&((1<<(MSB(range)-LSB(range)+1))-1))
|
||||||
|
|
||||||
|
long long read_bits(parse_state_t* state, int count) {
|
||||||
|
long long out = 0;
|
||||||
|
int offset = 0;
|
||||||
|
while (count) {
|
||||||
|
int segment, segment_len;
|
||||||
|
// Read a segment...
|
||||||
|
if (state->endianness & BIT_BIG_ENDIAN) {
|
||||||
|
if (count >= state->bit_offset) {
|
||||||
|
segment_len = state->bit_offset;
|
||||||
|
state->bit_offset = 8;
|
||||||
|
segment = state->input[state->index] & ((1 << segment_len) - 1);
|
||||||
|
state->index++;
|
||||||
|
} else {
|
||||||
|
segment_len = count;
|
||||||
|
state->bit_offset -= count;
|
||||||
|
segment = (state->input[state->index] >> state->bit_offset) & ((1 << segment_len) - 1);
|
||||||
|
}
|
||||||
|
} else { // BIT_LITTLE_ENDIAN
|
||||||
|
if (count + state->bit_offset >= 8) {
|
||||||
|
segment_len = 8 - state->bit_offset;
|
||||||
|
segment = (state->input[state->index] >> state->bit_offset);
|
||||||
|
state->index++;
|
||||||
|
state->bit_offset = 0;
|
||||||
|
} else {
|
||||||
|
segment_len = count;
|
||||||
|
segment = (state->input[state->index] >> state->bit_offset) & ((1 << segment_len) - 1);
|
||||||
|
state->bit_offset += segment_len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// have a valid segment; time to assemble the byte
|
||||||
|
if (state->endianness & BYTE_BIG_ENDIAN) {
|
||||||
|
out = out << segment_len | segment;
|
||||||
|
} else { // BYTE_LITTLE_ENDIAN
|
||||||
|
out |= segment << offset;
|
||||||
|
offset += segment_len;
|
||||||
|
}
|
||||||
|
count -= segment_len;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
12
src/hammer.h
12
src/hammer.h
|
|
@ -15,6 +15,8 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef HAMMER_HAMMER__H
|
||||||
|
#define HAMMER_HAMMER__H
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
@ -33,11 +35,16 @@
|
||||||
* at which it's been applied are memoized.
|
* at which it's been applied are memoized.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
#define BYTE_BIG_ENDIAN 0x1
|
||||||
|
#define BIT_BIG_ENDIAN 0x2
|
||||||
|
|
||||||
typedef struct parse_state {
|
typedef struct parse_state {
|
||||||
const uint8_t *input;
|
const uint8_t *input;
|
||||||
|
GHashTable *cache;
|
||||||
size_t index;
|
size_t index;
|
||||||
size_t length;
|
size_t length;
|
||||||
GHashTable *cache;
|
char bit_offset;
|
||||||
|
char endianness;
|
||||||
} parse_state_t;
|
} parse_state_t;
|
||||||
|
|
||||||
typedef struct parse_result {
|
typedef struct parse_result {
|
||||||
|
|
@ -81,5 +88,4 @@ parser_t* epsilon_p();
|
||||||
parser_t* and(parser_t* p);
|
parser_t* and(parser_t* p);
|
||||||
parser_t* not(parser_t* p);
|
parser_t* not(parser_t* p);
|
||||||
|
|
||||||
|
#endif // #ifndef HAMMER_HAMMER__H
|
||||||
|
|
||||||
|
|
|
||||||
7
src/internal.h
Normal file
7
src/internal.h
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef HAMMER_INTERNAL__H
|
||||||
|
#define HAMMER_INTERNAL__H
|
||||||
|
#include "hammer.h"
|
||||||
|
|
||||||
|
long long read_bits(parse_state_t* state, int count);
|
||||||
|
|
||||||
|
#endif // #ifndef HAMMER_INTERNAL__H
|
||||||
Loading…
Add table
Add a link
Reference in a new issue