diff --git a/config.mk b/config.mk index 03dc08a..4c0b1be 100644 --- a/config.mk +++ b/config.mk @@ -4,6 +4,9 @@ CFLAGS = -g -O0 XML2_CPPFLAGS = -I/opt/local/include/libxml2 XML2_LDFLAGS = -lxml2 +ZLIB_CPPFLAGS = +ZLIB_LDFLAGS = -lz + CUNIT_CPPFLAGS = -I/usr/local/include CUNIT_LDFLAGS = -L/usr/local/lib -lcunit diff --git a/lib/Makefile b/lib/Makefile index a10c20f..6c1e2b9 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,8 +1,8 @@ include ../config.mk -CPPFLAGS = $(XML2_CPPFLAGS) -LDFLAGS = $(XML2_LDFLAGS) +CPPFLAGS = $(XML2_CPPFLAGS) $(ZLIB_CPPFLAGS) +LDFLAGS = $(XML2_LDFLAGS) $(ZLIB_LDFLAGS) OBJS = \ pc_dimensional.o \ diff --git a/lib/cunit/Makefile b/lib/cunit/Makefile index bda1062..f4770b3 100644 --- a/lib/cunit/Makefile +++ b/lib/cunit/Makefile @@ -3,8 +3,8 @@ include ../../config.mk LIBPC = ../$(LIBPC_A) -CPPFLAGS = $(XML2_CPPFLAGS) $(CUNIT_CPPFLAGS) -I.. -LDFLAGS = $(XML2_LDFLAGS) $(CUNIT_LDFLAGS) +CPPFLAGS = $(XML2_CPPFLAGS) $(CUNIT_CPPFLAGS) $(ZLIB_CPPFLAGS) -I.. +LDFLAGS = $(XML2_LDFLAGS) $(CUNIT_LDFLAGS) $(ZLIB_LDFLAGS) EXE = cu_tester diff --git a/lib/cunit/cu_pc_patch.c b/lib/cunit/cu_pc_patch.c index 359ead9..fa03ab9 100644 --- a/lib/cunit/cu_pc_patch.c +++ b/lib/cunit/cu_pc_patch.c @@ -429,7 +429,7 @@ test_sigbits_encoding() CU_ASSERT_EQUAL(ebytes32[2], 624388039); /* packed uint32 */ bytes = pc_bytes_sigbits_decode(ebytes, PC_INT32, nelems); pcfree(ebytes32); - bytes32 = (uint16_t*)bytes; + bytes32 = (uint32_t*)bytes; CU_ASSERT_EQUAL(bytes32[0], 103241); CU_ASSERT_EQUAL(bytes32[1], 103251); CU_ASSERT_EQUAL(bytes32[2], 103261); @@ -437,6 +437,21 @@ test_sigbits_encoding() CU_ASSERT_EQUAL(bytes32[4], 103281); CU_ASSERT_EQUAL(bytes32[5], 103291); pcfree(bytes32); + + /* + uint8_t * + pc_bytes_zlib_encode(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems) + uint8_t * + pc_bytes_zlib_decode(const uint8_t *bytes, uint32_t interpretation) + */ + bytes = "abcaabcaabcbabcc"; + ebytes = pc_bytes_zlib_encode(bytes, PC_INT8, strlen(bytes)); + memcpy(&i, ebytes+4, 4); + CU_ASSERT_EQUAL(i, strlen(bytes)); /* original length value */ + bytes = pc_bytes_zlib_decode(ebytes, PC_INT8); + CU_ASSERT_EQUAL(bytes[0], 'a'); + CU_ASSERT_EQUAL(bytes[2], 'c'); + CU_ASSERT_EQUAL(bytes[5], 'b'); } /* REGISTER ***********************************************************/ diff --git a/lib/pc_api_internal.h b/lib/pc_api_internal.h index 94b7f35..3219617 100644 --- a/lib/pc_api_internal.h +++ b/lib/pc_api_internal.h @@ -100,10 +100,11 @@ uint8_t pc_sigbits_count_8 (const uint8_t *bytes8, uint32_t nelems, uint32_t *n uint16_t pc_sigbits_count_16(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits); uint32_t pc_sigbits_count_32(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits); uint64_t pc_sigbits_count_64(const uint8_t *bytes8, uint32_t nelems, uint32_t *nsigbits); - uint8_t* pc_bytes_sigbits_encode(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems, size_t *bytes_sigbits_size); - uint8_t* pc_bytes_sigbits_decode(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems); +uint8_t* pc_bytes_zlib_decode(const uint8_t *bytes, uint32_t interpretation); +uint8_t* pc_bytes_zlib_encode(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems); + #endif /* _PC_API_INTERNAL_H */ \ No newline at end of file diff --git a/lib/pc_dimensional.c b/lib/pc_dimensional.c index 2ad5c1d..6a93a50 100644 --- a/lib/pc_dimensional.c +++ b/lib/pc_dimensional.c @@ -17,7 +17,9 @@ ***********************************************************************/ #include +#include #include "pc_api_internal.h" +#include "zlib.h" /** @@ -747,3 +749,98 @@ pc_bytes_sigbits_decode(const uint8_t *bytes, uint32_t interpretation, uint32_t pcerror("Uh Oh"); return NULL; } + +static voidpf +pc_zlib_alloc(voidpf opaque, uInt nitems, uInt sz) +{ + return pcalloc(sz*nitems); +} + +static void +pc_zlib_free(voidpf opaque, voidpf ptr) +{ + pcfree(ptr); +} + + +/* TO DO look for Z_STREAM_END on the write */ + +/** +* Returns compressed byte array with +* size of compressed portion +* size of original data +* <.....> compresssed bytes +*/ +uint8_t * +pc_bytes_zlib_encode(const uint8_t *bytes, uint32_t interpretation, uint32_t nelems) +{ + size_t size = (INTERPRETATION_SIZES[interpretation] * nelems); + z_stream strm; + int ret; + size_t have; + size_t bufsize = 4*size; + uint8_t *buf = pcalloc(bufsize); + uint8_t *bytesout; + + /* Use our own allocators */ + strm.zalloc = pc_zlib_alloc; + strm.zfree = pc_zlib_free; + strm.opaque = Z_NULL; + ret = deflateInit(&strm, 9); + /* Set up input buffer */ + strm.avail_in = size; + strm.next_in = (uint8_t*)bytes; + /* Set up output buffer */ + strm.avail_out = bufsize; + strm.next_out = buf; + /* Compress */ + ret = deflate(&strm, Z_FINISH); + assert(ret != Z_STREAM_ERROR); + have = strm.total_out; + bytesout = pcalloc(have + 2 * 4); + memcpy(bytesout, &have, 4); + memcpy(bytesout+4, &size, 4); + memcpy(bytesout+8, buf, have); + pcfree(buf); + deflateEnd(&strm); + return bytesout; +} + +/** +* Returns uncompressed byte array from input with +* size of compressed portion +* size of original data +* <.....> compresssed bytes +*/ +uint8_t * +pc_bytes_zlib_decode(const uint8_t *bytes, uint32_t interpretation) +{ + z_stream strm; + uint32_t comp_size, orig_size; + size_t bufsize; + uint8_t *buf; + int ret; + + memcpy(&comp_size, bytes, 4); + memcpy(&orig_size, bytes+4, 4); + + /* Set up output memory */ + buf = pcalloc(orig_size); + + /* Use our own allocators */ + strm.zalloc = pc_zlib_alloc; + strm.zfree = pc_zlib_free; + strm.opaque = Z_NULL; + ret = inflateInit(&strm); + /* Set up input buffer */ + strm.avail_in = comp_size; + strm.next_in = (uint8_t*)(bytes+8); + + strm.avail_out = orig_size; + strm.next_out = buf; + ret = inflate(&strm, Z_FINISH); + assert(ret != Z_STREAM_ERROR); + inflateEnd(&strm); + return buf; +} + diff --git a/lib/pc_util.c b/lib/pc_util.c index d3edae7..5b671be 100644 --- a/lib/pc_util.c +++ b/lib/pc_util.c @@ -208,4 +208,55 @@ uncompressed_bytes_flip_endian(const uint8_t *bytebuf, const PCSCHEMA *schema, u } return buf; -} \ No newline at end of file +} + +typedef struct +{ + uint8_t *buf; + uint8_t *ptr; + size_t sz; +} bytebuffer_t; + +static bytebuffer_t * +bytebuffer_new(void) +{ + bytebuffer_t *bb = pcalloc(sizeof(bytebuffer_t)); + bb->sz = 1024; + bb->buf = pcalloc(bb->sz*sizeof(uint8_t)); + bb->ptr = bb->buf; +} + +static void +bytebuffer_destroy(bytebuffer_t *bb) +{ + pcfree(bb->buf); + pcfree(bb); +} + +static void +bytebuffer_memcpy(bytebuffer_t *bb, void *ptr, size_t sz) +{ + size_t cursz = bb->ptr - bb->buf; + if ( (bb->sz - cursz) < sz ) + { + bb->sz *= 2; + bb->buf = pcrealloc(bb->buf, bb->sz); + bb->ptr = bb->buf + cursz; + } + memcpy(bb->ptr, ptr, sz); + bb->ptr += sz; +} + +static size_t +bytebuffer_size(bytebuffer_t *bb) +{ + return (size_t)(bb->ptr - bb->buf); +} + +static void * +bytebuffer_copy(bytebuffer_t *bb) +{ + char *buf = pcalloc(bytebuffer_size(bb)); + memcpy(buf, bb->buf, bytebuffer_size(bb)); + return (void *)buf; +}