mirror of /home/gitosis/repositories/libowfat.git

16 changed files with 358 additions and 1 deletions
@ -0,0 +1,12 @@
|
||||
#include "parse.h" |
||||
|
||||
// This function is supposed to tell the caller if there is more data to
|
||||
// read. However, we have several limits we could run into. We have our
|
||||
// own limit, which we check first, but then, if the bytestream is bound
|
||||
// to an I/O stream we should also try to find out if the I/O stream has
|
||||
// hit EOF.
|
||||
int bs_capacitycheck(struct bytestream* bs,size_t capacity) { |
||||
if (bs->cur>=bs->max) return 0; // if EOF or error, return 0
|
||||
if (bs->max - bs->cur < capacity) return 0; // not EOF but less than that many bytes left
|
||||
return 1; |
||||
} |
@ -0,0 +1,112 @@
|
||||
#include "parse.h" |
||||
|
||||
unsigned char bs_get(struct bytestream* bs) { |
||||
unsigned char r; |
||||
char c; |
||||
if (bs->cur>=bs->max) { // EOF or already error state?
|
||||
bs->max=0; // signal error
|
||||
bs->cur=1; |
||||
return 0; // return 0
|
||||
} |
||||
switch (bs->type) { |
||||
|
||||
case MEMBUF: |
||||
r=bs->u.base[bs->cur]; |
||||
break; |
||||
|
||||
case IOBUF: |
||||
{ |
||||
int ret=buffer_getc(bs->u.b, &c); |
||||
if (ret==1) { |
||||
r=c; |
||||
} else { |
||||
bs->max=0; |
||||
bs->cur=1; |
||||
return 0; |
||||
} |
||||
} |
||||
break; |
||||
|
||||
case BSTREAM: |
||||
r=bs_get(bs->u.bs); |
||||
break; |
||||
|
||||
default: |
||||
r=0; // cannot happen
|
||||
} |
||||
++bs->cur; |
||||
return r; |
||||
} |
||||
|
||||
int bs_err(struct bytestream* bs) { |
||||
return (bs->cur > bs->max); |
||||
} |
||||
|
||||
#ifdef UNITTEST |
||||
#include <assert.h> |
||||
|
||||
int main() { |
||||
struct bytestream bs = BS_FROM_MEMBUF("fnord\nx", 6); |
||||
int i; |
||||
char buf[7]; |
||||
|
||||
/* first test: membuf.
|
||||
* See if we get all the bytes we put in and then error is signaled */ |
||||
for (i=0; i<6; ++i) { |
||||
buf[i] = bs_get(&bs); |
||||
assert(buf[i] == "fnord\n"[i]); |
||||
assert(!bs_err(&bs)); |
||||
} |
||||
buf[6] = bs_get(&bs); |
||||
/* We put an x there in memory.
|
||||
* If the bytestream range check failed, we'll get 'x', otherwise 0. */ |
||||
assert(buf[6] == 0); |
||||
assert(bs_err(&bs)); |
||||
|
||||
/* second test: iobuf with no limit. Otherwise the same. */ |
||||
|
||||
struct buffer b; |
||||
buffer_init_staticcontents(&b, "fnord\nx", 6); // this will let us read 6 bytes
|
||||
bs_init_iobuf(&bs, &b); |
||||
for (i=0; i<6; ++i) { |
||||
buf[i] = bs_get(&bs); |
||||
assert(buf[i] == "fnord\n"[i]); |
||||
assert(!bs_err(&bs)); |
||||
} |
||||
buf[6] = bs_get(&bs); |
||||
/* We put an x there in memory.
|
||||
* If the bytestream range check failed, we'll get 'x', otherwise 0. */ |
||||
assert(buf[6] == 0); |
||||
assert(bs_err(&bs)); |
||||
|
||||
/* third test: iobuf with limit. Otherwise the same. */ |
||||
buffer_init_staticcontents(&b, "fnord\nx", 7); // this will let us read 7 bytes
|
||||
|
||||
bs_init_iobuf_size(&bs, &b, 6); // but we tell bytestream the limit is 6
|
||||
for (i=0; i<6; ++i) { |
||||
buf[i] = bs_get(&bs); |
||||
assert(buf[i] == "fnord\n"[i]); |
||||
assert(!bs_err(&bs)); |
||||
} |
||||
buf[6] = bs_get(&bs); |
||||
/* We put an x there in the backing buffer.
|
||||
* If the bytestream range check failed, we'll get 'x', otherwise 0. */ |
||||
assert(buf[6] == 0); |
||||
assert(bs_err(&bs)); |
||||
|
||||
/* fourth test: iobuf with EOF */ |
||||
buffer_init_staticcontents(&b, "fnord\nx", 6); |
||||
bs_init_iobuf(&bs, &b); // bytestream has no limit but will hit EOF in backing buffer
|
||||
for (i=0; i<6; ++i) { |
||||
buf[i] = bs_get(&bs); |
||||
assert(buf[i] == "fnord\n"[i]); |
||||
assert(!bs_err(&bs)); |
||||
} |
||||
buf[6] = bs_get(&bs); |
||||
/* We did not give the bytestream a limit, but the buffer should
|
||||
* refuse to return more. */ |
||||
assert(buf[6] == 0); |
||||
assert(bs_err(&bs)); |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,15 @@
|
||||
#include "parse.h" |
||||
|
||||
void bs_init_bstream_size(struct bytestream* bs,struct bytestream* other,size_t maxlen) { |
||||
bs->type = BSTREAM; |
||||
// check if we have enough capacity in the parent bytestream
|
||||
if (bs_capacitycheck(other, maxlen)) { |
||||
bs->cur = 0; |
||||
bs->max = maxlen; |
||||
} else { |
||||
// nope, so set the new stream to error state right out of the box
|
||||
bs->cur = 1; |
||||
bs->max = 0; |
||||
} |
||||
bs->u.bs=other; |
||||
} |
@ -0,0 +1,8 @@
|
||||
#include "parse.h" |
||||
|
||||
void bs_init_iobuf(struct bytestream* bs,struct buffer* b) { |
||||
bs->type = IOBUF; |
||||
bs->cur = 0; |
||||
bs->max = (size_t)-1; |
||||
bs->u.b=b; |
||||
} |
@ -0,0 +1,8 @@
|
||||
#include "parse.h" |
||||
|
||||
void bs_init_iobuf_size(struct bytestream* bs,struct buffer* b,size_t maxlen) { |
||||
bs->type = IOBUF; |
||||
bs->cur = 0; |
||||
bs->max = maxlen; |
||||
bs->u.b=b; |
||||
} |
@ -0,0 +1,21 @@
|
||||
#include "parse.h" |
||||
|
||||
void bs_init_membuf(struct bytestream* bs,const unsigned char* membuf,size_t len) { |
||||
bs->type = MEMBUF; |
||||
bs->cur = 0; |
||||
bs->max = len; |
||||
bs->u.base=membuf; |
||||
} |
||||
|
||||
#ifdef UNITTEST |
||||
#include <assert.h> |
||||
int main() { |
||||
static struct bytestream bs; |
||||
bs_init_membuf(&bs, "fnord\n", 6); |
||||
char buf[7]; |
||||
int i; |
||||
for (i=0; i<7; ++i) buf[i]=bs_get(&bs); |
||||
assert(!memcmp(buf,"fnord\n",7)); // we should have gotten everything and then a 0 byte
|
||||
assert(bs_err(&bs)); // that should have set the error flag
|
||||
} |
||||
#endif |
@ -0,0 +1,29 @@
|
||||
#include "buffer.h" |
||||
#include <mmap.h> |
||||
|
||||
static ssize_t op() { |
||||
return 0; |
||||
} |
||||
|
||||
void buffer_init_staticcontents(buffer* b, char* y, size_t len) { |
||||
b->x=y; |
||||
b->p=0; b->a=b->n=len; |
||||
b->fd=-1; |
||||
b->op=op; |
||||
b->deinit=0; |
||||
} |
||||
|
||||
#ifdef UNITTEST |
||||
#include <assert.h> |
||||
|
||||
int main() { |
||||
buffer b; |
||||
buffer_init_staticcontents(&b, "fnord", 5); |
||||
char tmp[6]; |
||||
assert(buffer_get(&b, tmp, 6) == 5); |
||||
assert(!memcmp(tmp,"fnord",5)); |
||||
buffer_init_staticcontents(&b, tmp, sizeof tmp); |
||||
buffer_puts(&b, "foo\n"); |
||||
assert(!memcmp(tmp, "foo\n", 4)); |
||||
} |
||||
#endif |
@ -0,0 +1,7 @@
|
||||
#include "buffer.h" |
||||
#include <mmap.h> |
||||
|
||||
void buffer_init_staticcontents_free(buffer* b, char* y, size_t len) { |
||||
buffer_init_staticcontents(b, y, len); |
||||
b->deinit=buffer_free; |
||||
} |
@ -0,0 +1,17 @@
|
||||
#include "parse.h" |
||||
|
||||
uint16_t prs_u16(struct bytestream* bs) { |
||||
return bs_get(bs) | (bs_get(bs) << 8); |
||||
} |
||||
|
||||
#ifdef UNITTEST |
||||
#include <assert.h> |
||||
|
||||
int main() { |
||||
struct bytestream bs = BS_FROM_MEMBUF("\x34\x12",2); |
||||
assert(prs_u16(&bs) == 0x1234); |
||||
assert(bs_err(&bs) == 0); |
||||
assert(prs_u16(&bs) == 0); |
||||
assert(bs_err(&bs)); |
||||
} |
||||
#endif |
@ -0,0 +1,17 @@
|
||||
#include "parse.h" |
||||
|
||||
uint16_t prs_u16_big(struct bytestream* bs) { |
||||
return (bs_get(bs) << 8) | bs_get(bs); |
||||
} |
||||
|
||||
#ifdef UNITTEST |
||||
#include <assert.h> |
||||
|
||||
int main() { |
||||
struct bytestream bs = BS_FROM_MEMBUF("\x12\x34",2); |
||||
assert(prs_u16_big(&bs) == 0x1234); |
||||
assert(bs_err(&bs) == 0); |
||||
assert(prs_u16_big(&bs) == 0); |
||||
assert(bs_err(&bs)); |
||||
} |
||||
#endif |
@ -0,0 +1,17 @@
|
||||
#include "parse.h" |
||||
|
||||
uint32_t prs_u32(struct bytestream* bs) { |
||||
return bs_get(bs) | (bs_get(bs) << 8) | (bs_get(bs) << 16) | (bs_get(bs) << 24); |
||||
} |
||||
|
||||
#ifdef UNITTEST |
||||
#include <assert.h> |
||||
|
||||
int main() { |
||||
struct bytestream bs = BS_FROM_MEMBUF("\x78\x56\x34\x12",4); |
||||
assert(prs_u32(&bs) == 0x12345678); |
||||
assert(bs_err(&bs) == 0); |
||||
assert(prs_u32(&bs) == 0); |
||||
assert(bs_err(&bs)); |
||||
} |
||||
#endif |
@ -0,0 +1,17 @@
|
||||
#include "parse.h" |
||||
|
||||
uint32_t prs_u32_big(struct bytestream* bs) { |
||||
return (bs_get(bs) << 24) | (bs_get(bs) << 16) | (bs_get(bs) << 8) | bs_get(bs); |
||||
} |
||||
|
||||
#ifdef UNITTEST |
||||
#include <assert.h> |
||||
|
||||
int main() { |
||||
struct bytestream bs = BS_FROM_MEMBUF("\x12\x34\x56\x78",4); |
||||
assert(prs_u32_big(&bs) == 0x12345678); |
||||
assert(bs_err(&bs) == 0); |
||||
assert(prs_u32_big(&bs) == 0); |
||||
assert(bs_err(&bs)); |
||||
} |
||||
#endif |
@ -0,0 +1,21 @@
|
||||
#include "parse.h" |
||||
|
||||
uint64_t prs_u64(struct bytestream* bs) { |
||||
unsigned int i; |
||||
uint64_t x = bs_get(bs); |
||||
for (i=1; i<8; ++i) |
||||
x |= ((uint64_t)bs_get(bs) << (i*8)); |
||||
return x; |
||||
} |
||||
|
||||
#ifdef UNITTEST |
||||
#include <assert.h> |
||||
|
||||
int main() { |
||||
struct bytestream bs = BS_FROM_MEMBUF("\x78\x56\x34\x12\xef\xbe\xad\xde",8); |
||||
assert(prs_u64(&bs) == 0xdeadbeef12345678); |
||||
assert(bs_err(&bs) == 0); |
||||
assert(prs_u64(&bs) == 0); |
||||
assert(bs_err(&bs)); |
||||
} |
||||
#endif |
@ -0,0 +1,21 @@
|
||||
#include "parse.h" |
||||
|
||||
uint64_t prs_u64_big(struct bytestream* bs) { |
||||
unsigned int i; |
||||
uint64_t x = bs_get(bs); |
||||
for (i=1; i<8; ++i) |
||||
x = (x << 8) | bs_get(bs); |
||||
return x; |
||||
} |
||||
|
||||
#ifdef UNITTEST |
||||
#include <assert.h> |
||||
|
||||
int main() { |
||||
struct bytestream bs = BS_FROM_MEMBUF("\xde\xad\xbe\xef\x12\x34\x56\x78",8); |
||||
assert(prs_u64_big(&bs) == 0xdeadbeef12345678); |
||||
assert(bs_err(&bs) == 0); |
||||
assert(prs_u64_big(&bs) == 0); |
||||
assert(bs_err(&bs)); |
||||
} |
||||
#endif |
Loading…
Reference in new issue