code: added cwpack dep

isolation_bkp/dynres
Vladyslav Hrytsenko 2021-01-17 13:05:29 +02:00
parent 610cadb145
commit 3dabfc965e
13 changed files with 1452 additions and 10 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
build
.vscode
.ds_store
GPATH
GRTAGS

View File

@ -12,6 +12,9 @@ add_executable(eco2d-server
header/world/world.h
header/world/blocks.h
header/world/blocks_info.h
../../vendors/cwpack/cwpack.c
../../vendors/cwpack/cwpack.h
)
include_directories(eco2d-server header)

View File

@ -1,4 +1,4 @@
#pragma once
#include "system.h"
void generate_minimap(int32_t seed, int32_t world_size);
void generate_minimap(int32_t seed, uint16_t, uint16_t);

View File

@ -7,7 +7,7 @@
#define WORLD_ERROR_INVALID_DIMENSIONS -0x0003
#define WORLD_ERROR_INVALID_BUFFER -0x0004
int32_t world_init(int32_t seed, uint32_t width, uint32_t height);
int32_t world_init(int32_t seed, uint16_t chunk_width, uint16_t chunk_height, uint16_t chunk_amountx, uint16_t chunk_amounty);
int32_t world_destroy(void);
uint32_t world_buf(uint8_t const **ptr, uint32_t *width);

View File

@ -34,6 +34,7 @@ int main(int argc, char** argv) {
zpl_opts_print_help(&opts);
return -1;
}
int32_t seed = zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED);
int32_t chunk_size = zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
int32_t chunk_amount = zpl_opts_integer(&opts, "chunk-amount", DEFAULT_CHUNK_AMOUNT);
@ -47,12 +48,12 @@ int main(int argc, char** argv) {
}
if (zpl_opts_has_arg(&opts, "preview-map")) {
generate_minimap(seed, world_size);
generate_minimap(seed, chunk_size, chunk_amount);
return 0;
}
zpl_printf("[INFO] Generating world of size: %d x %d\n", world_size, world_size);
IF(world_init(seed, world_size, world_size));
IF(world_init(seed, chunk_size, chunk_size, chunk_amount, chunk_amount));
zpl_printf("[INFO] Initializing network...\n");
IF(network_init());
@ -68,3 +69,5 @@ int main(int argc, char** argv) {
return 0;
}
#include "packets/pkt_01_welcome.c"

View File

@ -4,16 +4,20 @@
#include "world/blocks.h"
#include "utils/options.h"
void generate_minimap(int32_t seed, int32_t world_size) {
world_init(seed, world_size, world_size);
void generate_minimap(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
world_init(seed, chunk_size, chunk_size, chunk_amount, chunk_amount);
uint8_t const *world;
uint32_t world_size = chunk_size * chunk_amount;
uint32_t len = world_buf(&world, NULL);
for (int i=0; i<len; i++) {
if (i > 0 && i % world_size == 0) {
putc('\n', stdout);
}
putc(blocks_get_symbol(world[i]), stdout);
}
putc('\n', stdout);
world_destroy();
}

View File

@ -7,25 +7,30 @@ typedef struct {
uint32_t size;
uint32_t width;
uint32_t height;
uint16_t chunk_width;
uint16_t chunk_height;
uint16_t chunk_amountx;
uint16_t chunk_amounty;
} world_data;
static world_data world = {0};
int32_t world_gen();
int32_t world_init(int32_t seed, uint32_t width, uint32_t height) {
int32_t world_init(int32_t seed, uint16_t chunk_width, uint16_t chunk_height, uint16_t chunk_amountx, uint16_t chunk_amounty) {
if (world.data) {
world_destroy();
}
world.seed = seed;
world.width = width;
world.height = height;
world.size = width*height;
world.width = chunk_width * chunk_amountx;
world.height = chunk_height * chunk_amounty;
world.size = world.width*world.height;
world.data = zpl_malloc(sizeof(uint8_t)*world.size);
if (!world.data) {
return WORLD_ERROR_OUTOFMEM;
}
return world_gen();
}
@ -44,3 +49,22 @@ uint32_t world_buf(uint8_t const **ptr, uint32_t *width) {
}
#include "world_gen.c"
// 11111111111111111111111111111111111111111111111111222222222222222222222222222222222222222222222333333333333333333333333333333333333333
// world 3x3
// chunk 3x3
// 111 111 111
// 222 222 222
// 333 333 333
// 111 111 111
// 222 222 222
// 333 333 333
// 111 111 111
// 222 222 222
// 333 333 333

View File

View File

@ -0,0 +1,22 @@
// #include "packet.h"
// PACKET_GENERATE_ENCODE(1, 2, )
#include "cwpack/cwpack.h"
#define PKT_01_WELCOME_ID 1
#define PKT_01_WELCOME_ARGS 2
size_t PKT_01_welcome_encode(uint32_t chunk_size, uint32_t chunk_amount) {
char buffer[20] = {0};
cw_pack_context pc = {0};
cw_pack_context_init(&pc, buffer, 20, 0);
cw_pack_array_size(&pc, 1 + PKT_01_WELCOME_ARGS);
cw_pack_signed(&pc, PKT_01_WELCOME_ID);
cw_pack_unsigned(&pc, chunk_size);
cw_pack_unsigned(&pc, chunk_amount);
return pc.current - pc.start; /* length */
}

740
code/vendors/cwpack/cwpack.c vendored 100644
View File

@ -0,0 +1,740 @@
/* CWPack - cwpack.c */
/*
The MIT License (MIT)
Copyright (c) 2017 Claes Wihlborg
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
#include <math.h>
#include "cwpack.h"
#include "cwpack_internals.h"
/************************* C S Y S T E M L I B R A R Y ****************/
#ifdef FORCE_NO_LIBRARY
static void *memcpy(void *dst, const void *src, size_t n)
{
unsigned int i;
uint8_t *d=(uint8_t*)dst, *s=(uint8_t*)src;
for (i=0; i<n; i++)
{
*d++ = *s++;
}
return dst;
}
#endif
/************************* B Y T E O R D E R ****************************/
static int test_byte_order(void)
{
#ifdef COMPILE_FOR_BIG_ENDIAN
const char *endianness = "1234";
if (*(uint32_t*)endianness != 0x31323334UL)
return CWP_RC_WRONG_BYTE_ORDER;
#else
#ifdef COMPILE_FOR_LITTLE_ENDIAN
const char *endianness = "1234";
if (*(uint32_t*)endianness != 0x34333231UL)
return CWP_RC_WRONG_BYTE_ORDER;
#endif
#endif
return CWP_RC_OK;
}
/******************************* P A C K **********************************/
int cw_pack_context_init (cw_pack_context* pack_context, void* data, unsigned long length, pack_overflow_handler hpo)
{
pack_context->start = pack_context->current = (uint8_t*)data;
pack_context->end = pack_context->start + length;
pack_context->be_compatible = false;
pack_context->err_no = 0;
pack_context->handle_pack_overflow = hpo;
pack_context->handle_flush = NULL;
pack_context->return_code = test_byte_order();
return pack_context->return_code;
}
void cw_pack_set_compatibility (cw_pack_context* pack_context, bool be_compatible)
{
pack_context->be_compatible = be_compatible;
}
void cw_pack_set_flush_handler (cw_pack_context* pack_context, pack_flush_handler handle_flush)
{
pack_context->handle_flush = handle_flush;
}
/* Packing routines -------------------------------------------------------------------------------- */
void cw_pack_unsigned(cw_pack_context* pack_context, uint64_t i)
{
if (pack_context->return_code)
return;
if (i < 128)
tryMove0(i);
if (i < 256)
tryMove1(0xcc, i);
if (i < 0x10000L)
{
tryMove2(0xcd, i);
}
if (i < 0x100000000LL)
tryMove4(0xce, i);
tryMove8(0xcf,i);
}
void cw_pack_signed(cw_pack_context* pack_context, int64_t i)
{
if (pack_context->return_code)
return;
if (i >127)
{
if (i < 256)
tryMove1(0xcc, i);
if (i < 0x10000L)
tryMove2(0xcd, i);
if (i < 0x100000000LL)
tryMove4(0xce, i);
tryMove8(0xcf,i);
}
if (i >= -32)
tryMove0(i);
if (i >= -128)
tryMove1(0xd0, i);
if (i >= -32768)
tryMove2(0xd1,i);
if (i >= (int64_t)0xffffffff80000000LL)
tryMove4(0xd2,i);
tryMove8(0xd3,i);
}
void cw_pack_float(cw_pack_context* pack_context, float f)
{
if (pack_context->return_code)
return;
uint32_t tmp = *((uint32_t*)&f);
tryMove4(0xca,tmp);
}
void cw_pack_double(cw_pack_context* pack_context, double d)
{
if (pack_context->return_code)
return;
uint64_t tmp = *((uint64_t*)&d);
tryMove8(0xcb,tmp);
}
void cw_pack_nil(cw_pack_context* pack_context)
{
if (pack_context->return_code)
return;
tryMove0(0xc0);
}
void cw_pack_true (cw_pack_context* pack_context)
{
if (pack_context->return_code)
return;
tryMove0(0xc3);
}
void cw_pack_false (cw_pack_context* pack_context)
{
if (pack_context->return_code)
return;
tryMove0(0xc2);
}
void cw_pack_boolean(cw_pack_context* pack_context, bool b)
{
if (pack_context->return_code)
return;
tryMove0(b? 0xc3: 0xc2);
}
void cw_pack_array_size(cw_pack_context* pack_context, uint32_t n)
{
if (pack_context->return_code)
return;
if (n < 16)
tryMove0(0x90 | n);
if (n < 65536)
tryMove2(0xdc, n);
tryMove4(0xdd, n);
}
void cw_pack_map_size(cw_pack_context* pack_context, uint32_t n)
{
if (pack_context->return_code)
return;
if (n < 16)
tryMove0(0x80 | n);
if (n < 65536)
tryMove2(0xde, n);
tryMove4(0xdf, n);
}
void cw_pack_str(cw_pack_context* pack_context, const char* v, uint32_t l)
{
if (pack_context->return_code)
return;
uint8_t *p;
if (l < 32) // Fixstr
{
cw_pack_reserve_space(l+1);
*p = (uint8_t)(0xa0 + l);
memcpy(p+1,v,l);
return;
}
if (l < 256 && !pack_context->be_compatible) // Str 8
{
cw_pack_reserve_space(l+2);
*p++ = (uint8_t)(0xd9);
*p = (uint8_t)(l);
memcpy(p+1,v,l);
return;
}
if (l < 65536) // Str 16
{
cw_pack_reserve_space(l+3)
*p++ = (uint8_t)0xda;
cw_store16(l);
memcpy(p+2,v,l);
return;
}
// Str 32
cw_pack_reserve_space(l+5)
*p++ = (uint8_t)0xdb;
cw_store32(l);
memcpy(p+4,v,l);
return;
}
void cw_pack_bin(cw_pack_context* pack_context, const void* v, uint32_t l)
{
if (pack_context->return_code)
return;
if (pack_context->be_compatible)
{
cw_pack_str( pack_context, v, l);
return;
}
uint8_t *p;
if (l < 256) // Bin 8
{
cw_pack_reserve_space(l+2);
*p++ = (uint8_t)(0xc4);
*p = (uint8_t)(l);
memcpy(p+1,v,l);
return;
}
if (l < 65536) // Bin 16
{
cw_pack_reserve_space(l+3)
*p++ = (uint8_t)0xc5;
cw_store16(l);
memcpy(p+2,v,l);
return;
}
// Bin 32
cw_pack_reserve_space(l+5)
*p++ = (uint8_t)0xc6;
cw_store32(l);
memcpy(p+4,v,l);
return;
}
void cw_pack_ext (cw_pack_context* pack_context, int8_t type, const void* v, uint32_t l)
{
if (pack_context->return_code)
return;
if (pack_context->be_compatible)
PACK_ERROR(CWP_RC_ILLEGAL_CALL);
uint8_t *p;
switch (l)
{
case 1: // Fixext 1
cw_pack_reserve_space(3);
*p++ = (uint8_t)0xd4;
*p++ = (uint8_t)type;
*p++ = *(uint8_t*)v;
return;
case 2: // Fixext 2
cw_pack_reserve_space(4);
*p++ = (uint8_t)0xd5;
break;
case 4: // Fixext 4
cw_pack_reserve_space(6);
*p++ = (uint8_t)0xd6;
break;
case 8: // Fixext 8
cw_pack_reserve_space(10);
*p++ = (uint8_t)0xd7;
break;
case 16: // Fixext16
cw_pack_reserve_space(18);
*p++ = (uint8_t)0xd8;
break;
default:
if (l < 256) // Ext 8
{
cw_pack_reserve_space(l+3);
*p++ = (uint8_t)0xc7;
*p++ = (uint8_t)(l);
}
else if (l < 65536) // Ext 16
{
cw_pack_reserve_space(l+4)
*p++ = (uint8_t)0xc8;
cw_store16(l);
p += 2;
}
else // Ext 32
{
cw_pack_reserve_space(l+6)
*p++ = (uint8_t)0xc9;
cw_store32(l);
p += 4;
}
}
*p++ = (uint8_t)type;
memcpy(p,v,l);
}
void cw_pack_time (cw_pack_context* pack_context, int64_t sec, uint32_t nsec)
{
if (pack_context->return_code)
return;
if (pack_context->be_compatible)
PACK_ERROR(CWP_RC_ILLEGAL_CALL);
if (nsec >= 1000000000)
PACK_ERROR(CWP_RC_VALUE_ERROR);
uint8_t *p;
if ((uint64_t)sec & 0xfffffffc00000000L) {
// timestamp 96
//serialize(0xc7, 12, -1, nsec, sec)
cw_pack_reserve_space(15);
*p++ = (uint8_t)0xc7;
*p++ = (uint8_t)12;
*p++ = (uint8_t)0xff;
cw_store32(nsec); p += 4;
cw_store64(sec);
}
else {
uint64_t data64 = (((uint64_t)nsec << 34) | (uint64_t)sec);
if (data64 & 0xffffffff00000000L) {
// timestamp 64
//serialize(0xd7, -1, data64)
cw_pack_reserve_space(10);
*p++ = (uint8_t)0xd7;
*p++ = (uint8_t)0xff;
cw_store64(data64);
}
else {
// timestamp 32
uint32_t data32 = (uint32_t)data64;
//serialize(0xd6, -1, data32)
cw_pack_reserve_space(6);
*p++ = (uint8_t)0xd6;
*p++ = (uint8_t)0xff;
cw_store32(data32);
}
}
}
void cw_pack_insert (cw_pack_context* pack_context, const void* v, uint32_t l)
{
uint8_t *p;
cw_pack_reserve_space(l);
memcpy(p,v,l);
}
void cw_pack_flush (cw_pack_context* pack_context)
{
if (pack_context->return_code == CWP_RC_OK)
pack_context->return_code =
pack_context->handle_flush ?
pack_context->handle_flush(pack_context) :
CWP_RC_ILLEGAL_CALL;
}
/******************************* U N P A C K **********************************/
int cw_unpack_context_init (cw_unpack_context* unpack_context, const void* data, unsigned long length, unpack_underflow_handler huu)
{
unpack_context->start = unpack_context->current = (uint8_t*)data;
unpack_context->end = unpack_context->start + length;
unpack_context->return_code = test_byte_order();
unpack_context->err_no = 0;
unpack_context->handle_unpack_underflow = huu;
return unpack_context->return_code;
}
/* Unpacking routines ---------------------------------------------------------- */
void cw_unpack_next (cw_unpack_context* unpack_context)
{
if (unpack_context->return_code)
return;
uint64_t tmpu64;
uint32_t tmpu32;
uint16_t tmpu16;
uint8_t* p;
#define buffer_end_return_code CWP_RC_END_OF_INPUT;
cw_unpack_assert_space(1);
uint8_t c = *p;
#undef buffer_end_return_code
#define buffer_end_return_code CWP_RC_BUFFER_UNDERFLOW;
switch (c)
{
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
getDDItem(CWP_ITEM_POSITIVE_INTEGER, i64, c); return; // positive fixnum
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
getDDItem(CWP_ITEM_MAP, map.size, c & 0x0f); return; // fixmap
case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
getDDItem(CWP_ITEM_ARRAY, array.size, c & 0x0f); return; // fixarray
case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
getDDItem(CWP_ITEM_STR, str.length, c & 0x1f); // fixraw
cw_unpack_assert_blob(str);
case 0xc0: unpack_context->item.type = CWP_ITEM_NIL; return; // nil
case 0xc2: getDDItem(CWP_ITEM_BOOLEAN, boolean, false); return; // false
case 0xc3: getDDItem(CWP_ITEM_BOOLEAN, boolean, true); return; // true
case 0xc4: getDDItem1(CWP_ITEM_BIN, bin.length, uint8_t); // bin 8
cw_unpack_assert_blob(bin);
case 0xc5: getDDItem2(CWP_ITEM_BIN, bin.length, uint16_t); // bin 16
cw_unpack_assert_blob(bin);
case 0xc6: getDDItem4(CWP_ITEM_BIN, bin.length, uint32_t); // bin 32
cw_unpack_assert_blob(bin);
case 0xc7: getDDItem1(CWP_ITEM_EXT, ext.length, uint8_t); // ext 8
cw_unpack_assert_space(1);
unpack_context->item.type = *(int8_t*)p;
if (unpack_context->item.type == CWP_ITEM_TIMESTAMP)
{
if (unpack_context->item.as.ext.length == 12)
{
cw_unpack_assert_space(4);
cw_load32(p);
unpack_context->item.as.time.tv_nsec = tmpu32;
cw_unpack_assert_space(8);
cw_load64(p,tmpu64);
unpack_context->item.as.time.tv_sec = (int64_t)tmpu64;
return;
}
UNPACK_ERROR(CWP_RC_WRONG_TIMESTAMP_LENGTH)
}
cw_unpack_assert_blob(ext);
case 0xc8: getDDItem2(CWP_ITEM_EXT, ext.length, uint16_t); // ext 16
cw_unpack_assert_space(1);
unpack_context->item.type = *(int8_t*)p;
cw_unpack_assert_blob(ext);
case 0xc9: getDDItem4(CWP_ITEM_EXT, ext.length, uint32_t); // ext 32
cw_unpack_assert_space(1);
unpack_context->item.type = *(int8_t*)p;
cw_unpack_assert_blob(ext);
case 0xca: unpack_context->item.type = CWP_ITEM_FLOAT; // float
cw_unpack_assert_space(4);
cw_load32(p);
unpack_context->item.as.real = *(float*)&tmpu32; return;
case 0xcb: getDDItem8(CWP_ITEM_DOUBLE); return; // double
case 0xcc: getDDItem1(CWP_ITEM_POSITIVE_INTEGER, u64, uint8_t); return; // unsigned int 8
case 0xcd: getDDItem2(CWP_ITEM_POSITIVE_INTEGER, u64, uint16_t); return; // unsigned int 16
case 0xce: getDDItem4(CWP_ITEM_POSITIVE_INTEGER, u64, uint32_t); return; // unsigned int 32
case 0xcf: getDDItem8(CWP_ITEM_POSITIVE_INTEGER); return; // unsigned int 64
case 0xd0: getDDItem1(CWP_ITEM_NEGATIVE_INTEGER, i64, int8_t); // signed int 8
if (unpack_context->item.as.i64 >= 0)
unpack_context->item.type = CWP_ITEM_POSITIVE_INTEGER;
return;
case 0xd1: getDDItem2(CWP_ITEM_NEGATIVE_INTEGER, i64, int16_t); // signed int 16
if (unpack_context->item.as.i64 >= 0)
unpack_context->item.type = CWP_ITEM_POSITIVE_INTEGER;
return;
case 0xd2: getDDItem4(CWP_ITEM_NEGATIVE_INTEGER, i64, int32_t); // signed int 32
if (unpack_context->item.as.i64 >= 0)
unpack_context->item.type = CWP_ITEM_POSITIVE_INTEGER;
return;
case 0xd3: getDDItem8(CWP_ITEM_NEGATIVE_INTEGER); // signed int 64
if (unpack_context->item.as.i64 >= 0)
unpack_context->item.type = CWP_ITEM_POSITIVE_INTEGER;
return;
case 0xd4: getDDItemFix(1); // fixext 1
case 0xd5: getDDItemFix(2); // fixext 2
case 0xd6: getDDItemFix(4); // fixext 4
case 0xd7: getDDItemFix(8); // fixext 8
case 0xd8: getDDItemFix(16); // fixext 16
case 0xd9: getDDItem1(CWP_ITEM_STR, str.length, uint8_t); // str 8
cw_unpack_assert_blob(str);
case 0xda: getDDItem2(CWP_ITEM_STR, str.length, uint16_t); // str 16
cw_unpack_assert_blob(str);
case 0xdb: getDDItem4(CWP_ITEM_STR, str.length, uint32_t); // str 32
cw_unpack_assert_blob(str);
case 0xdc: getDDItem2(CWP_ITEM_ARRAY, array.size, uint16_t); return; // array 16
case 0xdd: getDDItem4(CWP_ITEM_ARRAY, array.size, uint32_t); return; // array 32
case 0xde: getDDItem2(CWP_ITEM_MAP, map.size, uint16_t); return; // map 16
case 0xdf: getDDItem4(CWP_ITEM_MAP, map.size, uint32_t); return; // map 32
case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
getDDItem(CWP_ITEM_NEGATIVE_INTEGER, i64, (int8_t)c); return; // negative fixnum
default:
UNPACK_ERROR(CWP_RC_MALFORMED_INPUT)
}
return;
}
#define cw_skip_bytes(n) \
cw_unpack_assert_space((n)); \
break;
void cw_skip_items (cw_unpack_context* unpack_context, long item_count)
{
if (unpack_context->return_code)
return;
uint32_t tmpu32;
uint16_t tmpu16;
uint8_t* p;
while (item_count-- > 0)
{
#undef buffer_end_return_code
#define buffer_end_return_code CWP_RC_END_OF_INPUT;
cw_unpack_assert_space(1);
uint8_t c = *p;
#undef buffer_end_return_code
#define buffer_end_return_code CWP_RC_BUFFER_UNDERFLOW;
switch (c)
{
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
// unsigned fixint
case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff:
// signed fixint
case 0xc0: // nil
case 0xc2: // false
case 0xc3: break; // true
case 0xcc: // unsigned int 8
case 0xd0: cw_skip_bytes(1); // signed int 8
case 0xcd: // unsigned int 16
case 0xd1: // signed int 16
case 0xd4: cw_skip_bytes(2); // fixext 1
case 0xd5: cw_skip_bytes(3); // fixext 2
case 0xca: // float
case 0xce: // unsigned int 32
case 0xd2: cw_skip_bytes(4); // signed int 32
case 0xd6: cw_skip_bytes(5); // fixext 4
case 0xcb: // double
case 0xcf: // unsigned int 64
case 0xd3: cw_skip_bytes(8); // signed int 64
case 0xd7: cw_skip_bytes(9); // fixext 8
case 0xd8: cw_skip_bytes(17); // fixext 16
case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
cw_skip_bytes(c & 0x1f); // fixstr
case 0xd9: // str 8
case 0xc4: // bin 8
cw_unpack_assert_space(1);
tmpu32 = *p;
cw_skip_bytes(tmpu32);
case 0xda: // str 16
case 0xc5: // bin 16
cw_unpack_assert_space(2);
cw_load16(p);
cw_skip_bytes(tmpu16);
case 0xdb: // str 32
case 0xc6: // bin 32
cw_unpack_assert_space(4);
cw_load32(p);
cw_skip_bytes(tmpu32);
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
item_count += 2*(c & 15); // FixMap
break;
case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97:
case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
item_count += c & 15; // FixArray
break;
case 0xdc: // array 16
cw_unpack_assert_space(2);
cw_load16(p);
item_count += tmpu16;
break;
case 0xde: // map 16
cw_unpack_assert_space(2);
cw_load16(p);
item_count += 2*tmpu16;
break;
case 0xdd: // array 32
cw_unpack_assert_space(4);
cw_load32(p);
item_count += tmpu32;
break;
case 0xdf: // map 32
cw_unpack_assert_space(4);
cw_load32(p);
item_count += 2*tmpu32;
break;
case 0xc7: // ext 8
cw_unpack_assert_space(1);
tmpu32 = *p;
cw_skip_bytes(tmpu32 +1);
case 0xc8: // ext 16
cw_unpack_assert_space(2);
cw_load16(p);
cw_skip_bytes(tmpu16 +1);
case 0xc9: // ext 32
cw_unpack_assert_space(4);
cw_load32(p);
cw_skip_bytes(tmpu32 +1);
default: // illegal
UNPACK_ERROR(CWP_RC_MALFORMED_INPUT)
}
}
}
/* end cwpack.c */

180
code/vendors/cwpack/cwpack.h vendored 100644
View File

@ -0,0 +1,180 @@
/* CWPack - cwpack.h */
/*
The MIT License (MIT)
Copyright (c) 2017 Claes Wihlborg
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef CWPack_H__
#define CWPack_H__
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
/******************************* Return Codes *****************************/
#define CWP_RC_OK 0
#define CWP_RC_END_OF_INPUT -1
#define CWP_RC_BUFFER_OVERFLOW -2
#define CWP_RC_BUFFER_UNDERFLOW -3
#define CWP_RC_MALFORMED_INPUT -4
#define CWP_RC_WRONG_BYTE_ORDER -5
#define CWP_RC_ERROR_IN_HANDLER -6
#define CWP_RC_ILLEGAL_CALL -7
#define CWP_RC_MALLOC_ERROR -8
#define CWP_RC_STOPPED -9
#define CWP_RC_TYPE_ERROR -10
#define CWP_RC_VALUE_ERROR -11
#define CWP_RC_WRONG_TIMESTAMP_LENGTH -12
/******************************* P A C K **********************************/
struct cw_pack_context;
typedef int (*pack_overflow_handler)(struct cw_pack_context*, unsigned long);
typedef int (*pack_flush_handler)(struct cw_pack_context*);
typedef struct cw_pack_context {
uint8_t* current;
uint8_t* start;
uint8_t* end;
bool be_compatible;
int return_code;
int err_no; /* handlers can save error here */
pack_overflow_handler handle_pack_overflow;
pack_flush_handler handle_flush;
} cw_pack_context;
int cw_pack_context_init (cw_pack_context* pack_context, void* data, unsigned long length, pack_overflow_handler hpo);
void cw_pack_set_compatibility (cw_pack_context* pack_context, bool be_compatible);
void cw_pack_set_flush_handler (cw_pack_context* pack_context, pack_flush_handler handle_flush);
void cw_pack_flush (cw_pack_context* pack_context);
void cw_pack_nil (cw_pack_context* pack_context);
void cw_pack_true (cw_pack_context* pack_context);
void cw_pack_false (cw_pack_context* pack_context);
void cw_pack_boolean (cw_pack_context* pack_context, bool b);
void cw_pack_signed (cw_pack_context* pack_context, int64_t i);
void cw_pack_unsigned (cw_pack_context* pack_context, uint64_t i);
void cw_pack_float (cw_pack_context* pack_context, float f);
void cw_pack_double (cw_pack_context* pack_context, double d);
/* void cw_pack_real (cw_pack_context* pack_context, double d); moved to cwpack_utils */
void cw_pack_array_size (cw_pack_context* pack_context, uint32_t n);
void cw_pack_map_size (cw_pack_context* pack_context, uint32_t n);
void cw_pack_str (cw_pack_context* pack_context, const char* v, uint32_t l);
void cw_pack_bin (cw_pack_context* pack_context, const void* v, uint32_t l);
void cw_pack_ext (cw_pack_context* pack_context, int8_t type, const void* v, uint32_t l);
void cw_pack_time (cw_pack_context* pack_context, int64_t sec, uint32_t nsec);
void cw_pack_insert (cw_pack_context* pack_context, const void* v, uint32_t l);
/***************************** U N P A C K ********************************/
typedef enum
{
CWP_ITEM_MIN_RESERVED_EXT = -128,
CWP_ITEM_TIMESTAMP = -1,
CWP_ITEM_MAX_RESERVED_EXT = -1,
CWP_ITEM_MIN_USER_EXT = 0,
CWP_ITEM_MAX_USER_EXT = 127,
CWP_ITEM_NIL = 300,
CWP_ITEM_BOOLEAN = 301,
CWP_ITEM_POSITIVE_INTEGER = 302,
CWP_ITEM_NEGATIVE_INTEGER = 303,
CWP_ITEM_FLOAT = 304,
CWP_ITEM_DOUBLE = 305,
CWP_ITEM_STR = 306,
CWP_ITEM_BIN = 307,
CWP_ITEM_ARRAY = 308,
CWP_ITEM_MAP = 309,
CWP_ITEM_EXT = 310,
CWP_NOT_AN_ITEM = 999,
} cwpack_item_types;
typedef struct {
const void* start;
uint32_t length;
} cwpack_blob;
typedef struct {
uint32_t size;
} cwpack_container;
typedef struct {
int64_t tv_sec;
uint32_t tv_nsec;
} cwpack_timespec;
typedef struct {
cwpack_item_types type;
union
{
bool boolean;
uint64_t u64;
int64_t i64;
float real;
double long_real;
cwpack_container array;
cwpack_container map;
cwpack_blob str;
cwpack_blob bin;
cwpack_blob ext;
cwpack_timespec time;
} as;
} cwpack_item;
struct cw_unpack_context;
typedef int (*unpack_underflow_handler)(struct cw_unpack_context*, unsigned long);
typedef struct cw_unpack_context {
cwpack_item item;
uint8_t* start;
uint8_t* current;
uint8_t* end; /* logical end of buffer */
int return_code;
int err_no; /* handlers can save error here */
unpack_underflow_handler handle_unpack_underflow;
} cw_unpack_context;
int cw_unpack_context_init (cw_unpack_context* unpack_context, const void* data, unsigned long length, unpack_underflow_handler huu);
void cw_unpack_next (cw_unpack_context* unpack_context);
void cw_skip_items (cw_unpack_context* unpack_context, long item_count);
#endif /* CWPack_H__ */

View File

@ -0,0 +1,100 @@
/* CWPack - cwpack_config.h */
/*
The MIT License (MIT)
Copyright (c) 2017 Claes Wihlborg
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef cwpack_config_h
#define cwpack_config_h
/************************* A L I G N M E N T ******************************/
/*
* Some processors demand that integer access is to an even memory address.
* In that case define FORCE_ALIGNMENT
*/
/* #define FORCE_ALIGNMENT */
/*
* Some processors demand that 64 bit integer access is aligned.
* In that case define FORCE_ALIGNMENT_64BIT
*/
/* #define FORCE_ALIGNMENT_64BIT */
/************************* C S Y S T E M L I B R A R Y ****************/
/*
* The packer uses "memcpy" to move blobs. If you dont want to load C system library
* for just that, define FORCE_NO_LIBRARY and CWPack will use an internal "memcpy"
*/
/* #define FORCE_NO_LIBRARY */
/************************* B Y T E O R D E R ****************************/
/*
* The pack/unpack routines are written in three versions: for big endian, for
* little endian and insensitive to byte order. As you can get some speed gain
* if the byte order is known, we try that when we can certainly detect it.
* Define COMPILE_FOR_BIG_ENDIAN or COMPILE_FOR_LITTLE_ENDIAN if you know.
*/
#ifndef FORCE_ALIGNMENT
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__)
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define COMPILE_FOR_BIG_ENDIAN
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define COMPILE_FOR_LITTLE_ENDIAN
#endif
#elif defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && defined(__BIG_ENDIAN)
#if __BYTE_ORDER == __BIG_ENDIAN
#define COMPILE_FOR_BIG_ENDIAN
#elif __BYTE_ORDER == __LITTLE_ENDIAN
#define COMPILE_FOR_LITTLE_ENDIAN
#endif
#elif defined(__BIG_ENDIAN__)
#define COMPILE_FOR_BIG_ENDIAN
#elif defined(__LITTLE_ENDIAN__)
#define COMPILE_FOR_LITTLE_ENDIAN
#elif defined(__i386__) || defined(__x86_64__)
#define COMPILE_FOR_LITTLE_ENDIAN
#endif
#endif
//#undef COMPILE_FOR_LITTLE_ENDIAN
#endif /* cwpack_config_h */

View File

@ -0,0 +1,365 @@
/* CWPack - cwpack_defines.h */
/*
The MIT License (MIT)
Copyright (c) 2017 Claes Wihlborg
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef cwpack_defines_h
#define cwpack_defines_h
#include "cwpack_config.h"
#ifndef MOST_LIKELY
#if defined(__GNUC__) || defined(__clang__)
#define MOST_LIKELY(a,b) __builtin_expect((a),(b))
#else
#define MOST_LIKELY(a,b) ((a) == (b))
#endif
#endif
/******************************* P A C K **********************************/
#define PACK_ERROR(error_code) \
{ \
pack_context->return_code = error_code; \
return; \
}
#ifdef COMPILE_FOR_BIG_ENDIAN
#define cw_store16(x) *(uint16_t*)p = (uint16_t)x;
#define cw_store32(x) *(uint32_t*)p = (uint32_t)x;
#ifndef FORCE_ALIGNMENT_64BIT
#define cw_store64(x) *(uint64_t*)p = (uint64_t)x;
#else
#define cw_store64(x) memcpy(p,&x,8);
#endif
#else /* Byte order little endian or undetermined */
#ifdef COMPILE_FOR_LITTLE_ENDIAN
#define cw_store16(d) \
*(uint16_t*)p = (uint16_t)((((d) >> 8) & 0x0ff) | (d) << 8)
#define cw_store32(x) \
*(uint32_t*)p = \
((uint32_t)((((uint32_t)(x)) >> 24) | \
(((uint32_t)(x) & 0x00ff0000) >> 8) | \
(((uint32_t)(x) & 0x0000ff00) << 8) | \
(((uint32_t)(x)) << 24))); \
#ifndef FORCE_ALIGNMENT_64BIT
#define cw_store64(x) \
*(uint64_t*)p = \
((uint64_t)( \
(((((uint64_t)(x)) >> 40) | \
(((uint64_t)(x)) << 24)) & 0x0000ff000000ff00ULL) | \
(((((uint64_t)(x)) >> 24) | \
(((uint64_t)(x)) << 40)) & 0x00ff000000ff0000ULL) | \
(((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
(((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
(((uint64_t)(x)) >> 56) | \
(((uint64_t)(x)) << 56)));
#else
#define cw_store64(z) \
*p = (uint8_t)(z >> 56); \
p[1] = (uint8_t)(z >> 48); \
p[2] = (uint8_t)(z >> 40); \
p[3] = (uint8_t)(z >> 32); \
p[4] = (uint8_t)(z >> 24); \
p[5] = (uint8_t)(z >> 16); \
p[6] = (uint8_t)(z >> 8); \
p[7] = (uint8_t)z;
#endif
#else /* Byte order undetermined */
#define cw_store16(d) \
*p = (uint8_t)(d >> 8); \
p[1] = (uint8_t)d;
#define cw_store32(d) \
*p = (uint8_t)(d >> 24); \
p[1] = (uint8_t)(d >> 16); \
p[2] = (uint8_t)(d >> 8); \
p[3] = (uint8_t)d;
#define cw_store64(z) \
*p = (uint8_t)(z >> 56); \
p[1] = (uint8_t)(z >> 48); \
p[2] = (uint8_t)(z >> 40); \
p[3] = (uint8_t)(z >> 32); \
p[4] = (uint8_t)(z >> 24); \
p[5] = (uint8_t)(z >> 16); \
p[6] = (uint8_t)(z >> 8); \
p[7] = (uint8_t)z;
#endif
#endif
#define cw_pack_new_buffer(more) \
{ \
if (!pack_context->handle_pack_overflow) \
PACK_ERROR(CWP_RC_BUFFER_OVERFLOW) \
int rc = pack_context->handle_pack_overflow (pack_context, (unsigned long)(more)); \
if (rc) \
PACK_ERROR(rc) \
}
#define cw_pack_reserve_space(more) \
{ \
p = pack_context->current; \
uint8_t* nyp = p + more; \
if (nyp > pack_context->end) \
{ \
cw_pack_new_buffer(more) \
p = pack_context->current; \
nyp = p + more; \
} \
pack_context->current = nyp; \
}
#define tryMove0(t) \
{ \
if (pack_context->current == pack_context->end) \
cw_pack_new_buffer(1) \
*pack_context->current++ = (uint8_t)(t); \
return; \
}
#define tryMove1(t,d) \
{ \
uint8_t *p; \
cw_pack_reserve_space(2) \
*p++ = (uint8_t)t; \
*p = (uint8_t)d; \
return; \
}
#define tryMove2(t,d) \
{ \
uint8_t *p; \
cw_pack_reserve_space(3) \
*p++ = (uint8_t)t; \
cw_store16(d); \
return; \
}
#define tryMove4(t,d) \
{ \
uint8_t *p; \
cw_pack_reserve_space(5) \
*p++ = (uint8_t)t; \
cw_store32(d); \
return; \
}
#define tryMove8(t,d) \
{ \
uint8_t *p; \
cw_pack_reserve_space(9) \
*p++ = (uint8_t)t; \
cw_store64(d); \
return; \
}
/******************************* U N P A C K **********************************/
#define UNPACK_ERROR(error_code) \
{ \
unpack_context->item.type = CWP_NOT_AN_ITEM; \
unpack_context->return_code = error_code; \
return; \
}
#ifdef COMPILE_FOR_BIG_ENDIAN
#define cw_load16(ptr) tmpu16 = *(uint16_t*)ptr;
#define cw_load32(ptr) tmpu32 = *(uint32_t*)ptr;
#ifndef FORCE_ALIGNMENT_64BIT
#define cw_load64(ptr,dest) dest = *(uint64_t*)ptr;
#else
#define cw_load64(ptr,dest) memcpy(&dest,ptr,8);
#endif
#else /* Byte order little endian or undetermined */
#ifdef COMPILE_FOR_LITTLE_ENDIAN
#define cw_load16(ptr) \
tmpu16 = *(uint16_t*)ptr; \
tmpu16 = (uint16_t)((tmpu16<<8) | (tmpu16>>8))
#define cw_load32(ptr) \
tmpu32 = *(uint32_t*)ptr; \
tmpu32 = (tmpu32<<24) | ((tmpu32 & 0xff00)<<8) | \
((tmpu32 & 0xff0000)>>8) | (tmpu32>>24)
#ifndef FORCE_ALIGNMENT_64BIT
#define cw_load64(ptr,dest) \
tmpu64 = *((uint64_t*)ptr); \
dest = ( \
(((tmpu64 >> 40) | \
(tmpu64 << 24)) & 0x0000ff000000ff00ULL) | \
(((tmpu64 >> 24) | \
(tmpu64 << 40)) & 0x00ff000000ff0000ULL) | \
((tmpu64 & 0x000000ff00000000ULL) >> 8) | \
((tmpu64 & 0x00000000ff000000ULL) << 8) | \
(tmpu64 >> 56) | \
(tmpu64 << 56) )
#else
#define cw_load64(ptr,dest) \
tmpu64 = ((uint64_t)*ptr++) << 56; \
tmpu64 |= ((uint64_t)*ptr++) << 48; \
tmpu64 |= ((uint64_t)*ptr++) << 40; \
tmpu64 |= ((uint64_t)*ptr++) << 32; \
tmpu64 |= ((uint64_t)*ptr++) << 24; \
tmpu64 |= ((uint64_t)*ptr++) << 16; \
tmpu64 |= ((uint64_t)*ptr++) << 8; \
dest = tmpu64 | (uint64_t)*ptr++;
#endif
#else /* Byte order undetermined */
#define cw_load16(ptr) \
tmpu16 = (uint16_t)((*ptr++) << 8); \
tmpu16 |= (uint16_t)(*ptr++)
#define cw_load32(ptr) \
tmpu32 = (uint32_t)(*ptr++ << 24); \
tmpu32 |= (uint32_t)(*ptr++ << 16); \
tmpu32 |= (uint32_t)(*ptr++ << 8); \
tmpu32 |= (uint32_t)(*ptr++)
#define cw_load64(ptr,dest) \
tmpu64 = ((uint64_t)*ptr++) << 56; \
tmpu64 |= ((uint64_t)*ptr++) << 48; \
tmpu64 |= ((uint64_t)*ptr++) << 40; \
tmpu64 |= ((uint64_t)*ptr++) << 32; \
tmpu64 |= ((uint64_t)*ptr++) << 24; \
tmpu64 |= ((uint64_t)*ptr++) << 16; \
tmpu64 |= ((uint64_t)*ptr++) << 8; \
dest = tmpu64 | (uint64_t)*ptr++;
#endif
#endif
#define cw_unpack_assert_space(more) \
{ \
p = unpack_context->current; \
uint8_t* nyp = p + more; \
if (nyp > unpack_context->end) \
{ \
if (!unpack_context->handle_unpack_underflow) \
UNPACK_ERROR(buffer_end_return_code) \
int rc = unpack_context->handle_unpack_underflow (unpack_context, (unsigned long)(more)); \
if (rc != CWP_RC_OK) \
{ \
if (rc != CWP_RC_END_OF_INPUT) \
UNPACK_ERROR(rc) \
else \
UNPACK_ERROR(buffer_end_return_code) \
} \
p = unpack_context->current; \
nyp = p + more; \
} \
unpack_context->current = nyp; \
}
#define cw_unpack_assert_blob(blob) \
cw_unpack_assert_space(unpack_context->item.as.blob.length); \
unpack_context->item.as.blob.start = p; \
return;
#define getDDItem(typ,var,val) \
unpack_context->item.type = typ; \
unpack_context->item.as.var = val;
#define getDDItem1(typ,var,cast) \
unpack_context->item.type = typ; \
cw_unpack_assert_space(1); \
unpack_context->item.as.var = (cast)*p;
#define getDDItem2(typ,var,cast) \
unpack_context->item.type = typ; \
cw_unpack_assert_space(2); \
cw_load16(p); \
unpack_context->item.as.var = (cast)tmpu16;
#define getDDItem4(typ,var,cast) \
unpack_context->item.type = typ; \
cw_unpack_assert_space(4); \
cw_load32(p); \
unpack_context->item.as.var = (cast)tmpu32;
#define getDDItem8(typ) \
unpack_context->item.type = typ; \
cw_unpack_assert_space(8); \
cw_load64(p,unpack_context->item.as.u64);
#define getDDItemFix(len) \
cw_unpack_assert_space(len+1); \
unpack_context->item.type = *(int8_t*)p++; \
if (unpack_context->item.type == CWP_ITEM_TIMESTAMP) \
{ \
if (len == 4) \
{ \
cw_load32(p); \
unpack_context->item.as.time.tv_sec = (long)tmpu32; \
unpack_context->item.as.time.tv_nsec = 0; \
return; \
} \
if (len == 8) \
{ \
cw_load64(p,tmpu64); \
unpack_context->item.as.time.tv_sec = tmpu64 & 0x00000003ffffffffL; \
unpack_context->item.as.time.tv_nsec = tmpu64 >> 34; \
return; \
} \
UNPACK_ERROR(CWP_RC_WRONG_TIMESTAMP_LENGTH) \
} \
unpack_context->item.as.ext.length = len; \
unpack_context->item.as.ext.start = p; \
return;
#endif /* cwpack_defines_h */