From 0558244645611f314f47e0fa427f7323ce253eaf Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Mon, 7 Sep 2020 12:57:04 +0200 Subject: remove external libraries from main branch --- src/lib/binn.cc | 3372 ------------------------------------------------------- 1 file changed, 3372 deletions(-) delete mode 100644 src/lib/binn.cc (limited to 'src/lib/binn.cc') diff --git a/src/lib/binn.cc b/src/lib/binn.cc deleted file mode 100644 index b7e4839..0000000 --- a/src/lib/binn.cc +++ /dev/null @@ -1,3372 +0,0 @@ -#include -#include -#include -#include -#include -#include "lib/binn.h" - -#ifdef MULTIPASS_TRACE_MALLOC -#include "lib/mpmalloc.h" -#else -#define mpmalloc malloc -#define mprealloc realloc -#define mpfree free -#endif - -#define UNUSED(x) (void)(x) -#define round(dbl) dbl >= 0.0 ? (int)(dbl + 0.5) : ((dbl - (double)(int)dbl) <= -0.5 ? (int)dbl : (int)(dbl - 0.5)) - -// magic number: 0x1F 0xb1 0x22 0x1F => 0x1FB1221F or 0x1F22B11F -// because the BINN_STORAGE_NOBYTES (binary 000) may not have so many sub-types (BINN_STORAGE_HAS_MORE = 0x10) -#define BINN_MAGIC 0x1F22B11F - -#define MAX_BINN_HEADER 9 // [1:type][4:size][4:count] -#define MIN_BINN_SIZE 3 // [1:type][1:size][1:count] -#define CHUNK_SIZE 256 // 1024 - -#define BINN_STRUCT 1 -#define BINN_BUFFER 2 - -void* (*malloc_fn)(size_t len) = 0; -void* (*realloc_fn)(void *ptr, size_t len) = 0; -void (*free_fn)(void *ptr) = 0; - -/***************************************************************************/ - -#if defined(__alpha__) || defined(__hppa__) || defined(__mips__) || defined(__powerpc__) || defined(__sparc__) -#define BINN_ONLY_ALIGNED_ACCESS -#elif ( defined(__arm__) || defined(__aarch64__) ) && !defined(__ARM_FEATURE_UNALIGNED) -#define BINN_ONLY_ALIGNED_ACCESS -#endif - -#if defined(_WIN32) -#define BIG_ENDIAN 0x1000 -#define LITTLE_ENDIAN 0x0001 -#define BYTE_ORDER LITTLE_ENDIAN -#elif defined(__APPLE__) -/* macros already defined */ -#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) -#include -#elif defined(_AIX) -#include -#else -#include -#endif - -#ifndef BYTE_ORDER -#error "BYTE_ORDER not defined" -#endif -#ifndef BIG_ENDIAN -#error "BIG_ENDIAN not defined" -#endif -#ifndef LITTLE_ENDIAN -#error "LITTLE_ENDIAN not defined" -#endif -#if BIG_ENDIAN == LITTLE_ENDIAN -#error "BIG_ENDIAN == LITTLE_ENDIAN" -#endif -#if BYTE_ORDER!=BIG_ENDIAN && BYTE_ORDER!=LITTLE_ENDIAN -#error "BYTE_ORDER not supported" -#endif - -typedef unsigned short int u16; -typedef unsigned int u32; -typedef unsigned long long int u64; - -BINN_PRIVATE void copy_be16(u16 *pdest, u16 *psource) { -#if BYTE_ORDER == LITTLE_ENDIAN - unsigned char *source = (unsigned char *) psource; - unsigned char *dest = (unsigned char *) pdest; - dest[0] = source[1]; - dest[1] = source[0]; -#else // if BYTE_ORDER == BIG_ENDIAN -#ifdef BINN_ONLY_ALIGNED_ACCESS - if (psource % 2 == 0){ // address aligned to 16 bit - *pdest = *psource; - } else { - unsigned char *source = (unsigned char *) psource; - unsigned char *dest = (unsigned char *) pdest; - dest[0] = source[0]; // indexes are the same - dest[1] = source[1]; - } -#else - *pdest = *psource; -#endif -#endif -} - -BINN_PRIVATE void copy_be32(u32 *pdest, u32 *psource) { -#if BYTE_ORDER == LITTLE_ENDIAN - unsigned char *source = (unsigned char *) psource; - unsigned char *dest = (unsigned char *) pdest; - dest[0] = source[3]; - dest[1] = source[2]; - dest[2] = source[1]; - dest[3] = source[0]; -#else // if BYTE_ORDER == BIG_ENDIAN -#ifdef BINN_ONLY_ALIGNED_ACCESS - if (psource % 4 == 0){ // address aligned to 32 bit - *pdest = *psource; - } else { - unsigned char *source = (unsigned char *) psource; - unsigned char *dest = (unsigned char *) pdest; - dest[0] = source[0]; // indexes are the same - dest[1] = source[1]; - dest[2] = source[2]; - dest[3] = source[3]; - } -#else - *pdest = *psource; -#endif -#endif -} - -BINN_PRIVATE void copy_be64(u64 *pdest, u64 *psource) { -#if BYTE_ORDER == LITTLE_ENDIAN - unsigned char *source = (unsigned char *) psource; - unsigned char *dest = (unsigned char *) pdest; - int i; - for (i=0; i < 8; i++) { - dest[i] = source[7-i]; - } -#else // if BYTE_ORDER == BIG_ENDIAN -#ifdef BINN_ONLY_ALIGNED_ACCESS - if (psource % 8 == 0){ // address aligned to 64 bit - *pdest = *psource; - } else { - unsigned char *source = (unsigned char *) psource; - unsigned char *dest = (unsigned char *) pdest; - int i; - for (i=0; i < 8; i++) { - dest[i] = source[i]; // indexes are the same - } - } -#else - *pdest = *psource; -#endif -#endif -} - -/***************************************************************************/ - -#ifndef WIN32 -#define stricmp strcasecmp -#define strnicmp strncasecmp -#endif - -/***************************************************************************/ - -void APIENTRY binn_set_alloc_functions(void* (*new_malloc)(size_t), void* (*new_realloc)(void*,size_t), void (*new_free)(void*)) { - - malloc_fn = new_malloc; - realloc_fn = new_realloc; - free_fn = new_free; - -} - -/***************************************************************************/ - -BINN_PRIVATE void check_alloc_functions() { - - if (malloc_fn == 0) malloc_fn = &mpmalloc; - if (realloc_fn == 0) realloc_fn = &mprealloc; - if (free_fn == 0) free_fn = &mpfree; - -} - -/***************************************************************************/ - -BINN_PRIVATE void * binn_malloc(int size) { - check_alloc_functions(); - return malloc_fn(size); -} - -/***************************************************************************/ - -BINN_PRIVATE void * binn_memdup(void *src, int size) { - void *dest; - - if (src == NULL || size <= 0) return NULL; - dest = binn_malloc(size); - if (dest == NULL) return NULL; - memcpy(dest, src, size); - return dest; - -} - -/***************************************************************************/ - -BINN_PRIVATE size_t strlen2(char *str) { - - if (str == NULL) return 0; - return strlen(str); - -} - -/***************************************************************************/ - -int APIENTRY binn_create_type(int storage_type, int data_type_index) { - if (data_type_index < 0) return -1; - if ((storage_type < BINN_STORAGE_MIN) || (storage_type > BINN_STORAGE_MAX)) return -1; - if (data_type_index < 16) - return storage_type | data_type_index; - else if (data_type_index < 4096) { - storage_type |= BINN_STORAGE_HAS_MORE; - storage_type <<= 8; - data_type_index >>= 4; - return storage_type | data_type_index; - } else - return -1; -} - -/***************************************************************************/ - -BOOL APIENTRY binn_get_type_info(int long_type, int *pstorage_type, int *pextra_type) { - int storage_type, extra_type; - BOOL retval=TRUE; - -again: - - if (long_type < 0) { - goto loc_invalid; - } else if (long_type <= 0xff) { - storage_type = long_type & BINN_STORAGE_MASK; - extra_type = long_type & BINN_TYPE_MASK; - } else if (long_type <= 0xffff) { - storage_type = long_type & BINN_STORAGE_MASK16; - storage_type >>= 8; - extra_type = long_type & BINN_TYPE_MASK16; - extra_type >>= 4; - } else if (long_type & BINN_STORAGE_VIRTUAL) { - //storage_type = BINN_STORAGE_VIRTUAL; - //extra_type = xxx; - long_type &= 0xffff; - goto again; - } else { -loc_invalid: - storage_type = -1; - extra_type = -1; - retval = FALSE; - } - - if (pstorage_type) *pstorage_type = storage_type; - if (pextra_type) *pextra_type = extra_type; - - return retval; - -} - -/***************************************************************************/ - -BOOL APIENTRY binn_create(binn *item, int type, int size, void *pointer) { - BOOL retval=FALSE; - - switch (type) { - case BINN_LIST: - case BINN_MAP: - case BINN_OBJECT: - break; - default: - goto loc_exit; - } - - if ((item == NULL) || (size < 0)) goto loc_exit; - if (size < MIN_BINN_SIZE) { - if (pointer) goto loc_exit; - else size = 0; - } - - memset(item, 0, sizeof(binn)); - - if (pointer) { - item->pre_allocated = TRUE; - item->pbuf = pointer; - item->alloc_size = size; - } else { - item->pre_allocated = FALSE; - if (size == 0) size = CHUNK_SIZE; - pointer = binn_malloc(size); - if (pointer == 0) return INVALID_BINN; - item->pbuf = pointer; - item->alloc_size = size; - } - - item->header = BINN_MAGIC; - //item->allocated = FALSE; -- already zeroed - item->writable = TRUE; - item->used_size = MAX_BINN_HEADER; // save space for the header - item->type = type; - //item->count = 0; -- already zeroed - item->dirty = TRUE; // the header is not written to the buffer - - retval = TRUE; - -loc_exit: - return retval; - -} - -/***************************************************************************/ - -binn * APIENTRY binn_new(int type, int size, void *pointer) { - binn *item; - - item = (binn*) binn_malloc(sizeof(binn)); - - if (binn_create(item, type, size, pointer) == FALSE) { - free_fn(item); - return NULL; - } - - item->allocated = TRUE; - return item; - -} - -/*************************************************************************************/ - -BOOL APIENTRY binn_create_list(binn *list) { - - return binn_create(list, BINN_LIST, 0, NULL); - -} - -/*************************************************************************************/ - -BOOL APIENTRY binn_create_map(binn *map) { - - return binn_create(map, BINN_MAP, 0, NULL); - -} - -/*************************************************************************************/ - -BOOL APIENTRY binn_create_object(binn *object) { - - return binn_create(object, BINN_OBJECT, 0, NULL); - -} - -/***************************************************************************/ - -binn * APIENTRY binn_list() { - return binn_new(BINN_LIST, 0, 0); -} - -/***************************************************************************/ - -binn * APIENTRY binn_map() { - return binn_new(BINN_MAP, 0, 0); -} - -/***************************************************************************/ - -binn * APIENTRY binn_object() { - return binn_new(BINN_OBJECT, 0, 0); -} - -/*************************************************************************************/ - -BOOL APIENTRY binn_load(void *data, binn *value) { - - if ((data == NULL) || (value == NULL)) return FALSE; - memset(value, 0, sizeof(binn)); - value->header = BINN_MAGIC; - //value->allocated = FALSE; -- already zeroed - //value->writable = FALSE; - - if (binn_is_valid(data, &value->type, &value->count, &value->size) == FALSE) return FALSE; - value->ptr = data; - return TRUE; - -} - -/*************************************************************************************/ - -binn * APIENTRY binn_open(void *data) { - binn *item; - - item = (binn*) binn_malloc(sizeof(binn)); - - if (binn_load(data, item) == FALSE) { - free_fn(item); - return NULL; - } - - item->allocated = TRUE; - return item; - -} - -/***************************************************************************/ - -BINN_PRIVATE int binn_get_ptr_type(void *ptr) { - - if (ptr == NULL) return 0; - - switch (*(unsigned int *)ptr) { - case BINN_MAGIC: - return BINN_STRUCT; - default: - return BINN_BUFFER; - } - -} - -/***************************************************************************/ - -BOOL APIENTRY binn_is_struct(void *ptr) { - - if (ptr == NULL) return FALSE; - - if ((*(unsigned int *)ptr) == BINN_MAGIC) { - return TRUE; - } else { - return FALSE; - } - -} - -/***************************************************************************/ - -BINN_PRIVATE int CalcAllocation(int needed_size, int alloc_size) { - int calc_size; - - calc_size = alloc_size; - while (calc_size < needed_size) { - calc_size <<= 1; // same as *= 2 - //calc_size += CHUNK_SIZE; -- this is slower than the above line, because there are more reallocations - } - return calc_size; - -} - -/***************************************************************************/ - -BINN_PRIVATE BOOL CheckAllocation(binn *item, int add_size) { - int alloc_size; - void *ptr; - - if (item->used_size + add_size > item->alloc_size) { - if (item->pre_allocated) return FALSE; - alloc_size = CalcAllocation(item->used_size + add_size, item->alloc_size); - ptr = realloc_fn(item->pbuf, alloc_size); - if (ptr == NULL) return FALSE; - item->pbuf = ptr; - item->alloc_size = alloc_size; - } - - return TRUE; - -} - -/***************************************************************************/ - -#if BYTE_ORDER == BIG_ENDIAN - -BINN_PRIVATE int get_storage_size(int storage_type) { - - switch (storage_type) { - case BINN_STORAGE_NOBYTES: - return 0; - case BINN_STORAGE_BYTE: - return 1; - case BINN_STORAGE_WORD: - return 2; - case BINN_STORAGE_DWORD: - return 4; - case BINN_STORAGE_QWORD: - return 8; - default: - return 0; - } - -} - -#endif - -/***************************************************************************/ - -BINN_PRIVATE unsigned char * AdvanceDataPos(unsigned char *p, unsigned char *plimit) { - unsigned char byte; - int storage_type, DataSize; - - if (p > plimit) return 0; - - byte = *p; p++; - storage_type = byte & BINN_STORAGE_MASK; - if (byte & BINN_STORAGE_HAS_MORE) p++; - - switch (storage_type) { - case BINN_STORAGE_NOBYTES: - //p += 0; - break; - case BINN_STORAGE_BYTE: - p ++; - break; - case BINN_STORAGE_WORD: - p += 2; - break; - case BINN_STORAGE_DWORD: - p += 4; - break; - case BINN_STORAGE_QWORD: - p += 8; - break; - case BINN_STORAGE_BLOB: - if (p + sizeof(int) - 1 > plimit) return 0; - copy_be32((u32*)&DataSize, (u32*)p); - p += 4 + DataSize; - break; - case BINN_STORAGE_CONTAINER: - if (p > plimit) return 0; - DataSize = *((unsigned char*)p); - if (DataSize & 0x80) { - if (p + sizeof(int) - 1 > plimit) return 0; - copy_be32((u32*)&DataSize, (u32*)p); - DataSize &= 0x7FFFFFFF; - } - DataSize--; // remove the type byte already added before - p += DataSize; - break; - case BINN_STORAGE_STRING: - if (p > plimit) return 0; - DataSize = *((unsigned char*)p); - if (DataSize & 0x80) { - if (p + sizeof(int) - 1 > plimit) return 0; - copy_be32((u32*)&DataSize, (u32*)p); - DataSize &= 0x7FFFFFFF; - p+=4; - } else { - p++; - } - p += DataSize; - p++; // null terminator. - break; - default: - return 0; - } - - if (p > plimit) return 0; - - return p; - -} - -/***************************************************************************/ - -BINN_PRIVATE unsigned char * SearchForID(unsigned char *p, int header_size, int size, int numitems, int id) { - unsigned char *plimit, *base; - int i, int32; - - base = p; - plimit = p + size - 1; - p += header_size; - - // search for the ID in all the arguments. - for (i = 0; i < numitems; i++) { - copy_be32((u32*)&int32, (u32*)p); - p += 4; - if (p > plimit) break; - // Compare if the IDs are equal. - if (int32 == id) return p; - // xxx - p = AdvanceDataPos(p, plimit); - if ((p == 0) || (p < base)) break; - } - - return NULL; - -} - -/***************************************************************************/ - -BINN_PRIVATE unsigned char * SearchForKey(unsigned char *p, int header_size, int size, int numitems, char *key) { - unsigned char len, *plimit, *base; - int i, keylen; - - base = p; - plimit = p + size - 1; - p += header_size; - - keylen = strlen(key); - - // search for the key in all the arguments. - for (i = 0; i < numitems; i++) { - len = *((unsigned char *)p); - p++; - if (p > plimit) break; - // Compare if the strings are equal. - if (len > 0) { - if (strnicmp((char*)p, key, len) == 0) { // note that there is no null terminator here - if (keylen == len) { - p += len; - return p; - } - } - p += len; - if (p > plimit) break; - } else if (len == keylen) { // in the case of empty string: "" - return p; - } - // xxx - p = AdvanceDataPos(p, plimit); - if ((p == 0) || (p < base)) break; - } - - return NULL; - -} - -/***************************************************************************/ - -BINN_PRIVATE BOOL AddValue(binn *item, int type, void *pvalue, int size); - -/***************************************************************************/ - -BINN_PRIVATE BOOL binn_list_add_raw(binn *item, int type, void *pvalue, int size) { - - if ((item == NULL) || (item->type != BINN_LIST) || (item->writable == FALSE)) return FALSE; - - //if (CheckAllocation(item, 4) == FALSE) return FALSE; // 4 bytes used for data_store and data_format. - - if (AddValue(item, type, pvalue, size) == FALSE) return FALSE; - - item->count++; - - return TRUE; - -} - -/***************************************************************************/ - -BINN_PRIVATE BOOL binn_object_set_raw(binn *item, char *key, int type, void *pvalue, int size) { - unsigned char *p, len; - int int32; - - if ((item == NULL) || (item->type != BINN_OBJECT) || (item->writable == FALSE)) return FALSE; - - if (key == NULL) return FALSE; - int32 = strlen(key); - if (int32 > 255) return FALSE; - - // is the key already in it? - p = SearchForKey((unsigned char*)item->pbuf, MAX_BINN_HEADER, item->used_size, item->count, key); - if (p) return FALSE; - - // start adding it - - if (CheckAllocation(item, 1 + int32) == FALSE) return FALSE; // bytes used for the key size and the key itself. - - p = ((unsigned char *) item->pbuf) + item->used_size; - len = int32; - *p = len; - p++; - memcpy(p, key, int32); - int32++; // now contains the strlen + 1 byte for the len - item->used_size += int32; - - if (AddValue(item, type, pvalue, size) == FALSE) { - item->used_size -= int32; - return FALSE; - } - - item->count++; - - return TRUE; - -} - -/***************************************************************************/ - -BINN_PRIVATE BOOL binn_map_set_raw(binn *item, int id, int type, void *pvalue, int size) { - unsigned char *p; - - if ((item == NULL) || (item->type != BINN_MAP) || (item->writable == FALSE)) return FALSE; - - // is the ID already in it? - p = SearchForID((unsigned char*)item->pbuf, MAX_BINN_HEADER, item->used_size, item->count, id); - if (p) return FALSE; - - // start adding it - - if (CheckAllocation(item, 4) == FALSE) return FALSE; // 4 bytes used for the id. - - p = ((unsigned char *) item->pbuf) + item->used_size; - copy_be32((u32*)p, (u32*)&id); - item->used_size += 4; - - if (AddValue(item, type, pvalue, size) == FALSE) { - item->used_size -= 4; - return FALSE; - } - - item->count++; - - return TRUE; - -} - -/***************************************************************************/ - -BINN_PRIVATE void * compress_int(int *pstorage_type, int *ptype, void *psource) { - int storage_type, storage_type2, type, type2=0; - int64 vint; - uint64 vuint; - char *pvalue; -#if BYTE_ORDER == BIG_ENDIAN - int size1, size2; -#endif - - storage_type = *pstorage_type; - if (storage_type == BINN_STORAGE_BYTE) return psource; - - type = *ptype; - - switch (type) { - case BINN_INT64: - vint = *(int64*)psource; - goto loc_signed; - case BINN_INT32: - vint = *(int*)psource; - goto loc_signed; - case BINN_INT16: - vint = *(short*)psource; - goto loc_signed; - case BINN_UINT64: - vuint = *(uint64*)psource; - goto loc_positive; - case BINN_UINT32: - vuint = *(unsigned int*)psource; - goto loc_positive; - case BINN_UINT16: - vuint = *(unsigned short*)psource; - goto loc_positive; - } - -loc_signed: - - if (vint >= 0) { - vuint = vint; - goto loc_positive; - } - -//loc_negative: - - if (vint >= INT8_MIN) { - type2 = BINN_INT8; - } else - if (vint >= INT16_MIN) { - type2 = BINN_INT16; - } else - if (vint >= INT32_MIN) { - type2 = BINN_INT32; - } - goto loc_exit; - -loc_positive: - - if (vuint <= UINT8_MAX) { - type2 = BINN_UINT8; - } else - if (vuint <= UINT16_MAX) { - type2 = BINN_UINT16; - } else - if (vuint <= UINT32_MAX) { - type2 = BINN_UINT32; - } - -loc_exit: - - pvalue = (char *) psource; - - if ((type2) && (type2 != type)) { - *ptype = type2; - storage_type2 = binn_get_write_storage(type2); - *pstorage_type = storage_type2; -#if BYTE_ORDER == BIG_ENDIAN - size1 = get_storage_size(storage_type); - size2 = get_storage_size(storage_type2); - pvalue += (size1 - size2); -#endif - } - - return pvalue; - -} - -/***************************************************************************/ - -BINN_PRIVATE int type_family(int type); - -BINN_PRIVATE BOOL AddValue(binn *item, int type, void *pvalue, int size) { - int int32, ArgSize, storage_type, extra_type; - unsigned char *p; - - binn_get_type_info(type, &storage_type, &extra_type); - - if (pvalue == NULL) { - switch (storage_type) { - case BINN_STORAGE_NOBYTES: - break; - case BINN_STORAGE_BLOB: - case BINN_STORAGE_STRING: - if (size == 0) break; // the 2 above are allowed to have 0 length - default: - return FALSE; - } - } - - if ((type_family(type) == BINN_FAMILY_INT) && (item->disable_int_compression == FALSE)) - pvalue = compress_int(&storage_type, &type, pvalue); - - switch (storage_type) { - case BINN_STORAGE_NOBYTES: - size = 0; - ArgSize = size; - break; - case BINN_STORAGE_BYTE: - size = 1; - ArgSize = size; - break; - case BINN_STORAGE_WORD: - size = 2; - ArgSize = size; - break; - case BINN_STORAGE_DWORD: - size = 4; - ArgSize = size; - break; - case BINN_STORAGE_QWORD: - size = 8; - ArgSize = size; - break; - case BINN_STORAGE_BLOB: - if (size < 0) return FALSE; - //if (size == 0) ... - ArgSize = size + 4; - break; - case BINN_STORAGE_STRING: - if (size < 0) return FALSE; - if (size == 0) size = strlen2( (char *) pvalue); - ArgSize = size + 5; // at least this size - break; - case BINN_STORAGE_CONTAINER: - if (size <= 0) return FALSE; - ArgSize = size; - break; - default: - return FALSE; - } - - ArgSize += 2; // at least 2 bytes used for data_type. - if (CheckAllocation(item, ArgSize) == FALSE) return FALSE; - - // Gets the pointer to the next place in buffer - p = ((unsigned char *) item->pbuf) + item->used_size; - - // If the data is not a container, store the data type - if (storage_type != BINN_STORAGE_CONTAINER) { - if (type > 255) { - u16 type16 = type; - copy_be16((u16*)p, (u16*)&type16); - p += 2; - item->used_size += 2; - } else { - *p = type; - p++; - item->used_size++; - } - } - - switch (storage_type) { - case BINN_STORAGE_NOBYTES: - // Nothing to do. - break; - case BINN_STORAGE_BYTE: - *((char *) p) = *((char *) pvalue); - item->used_size += 1; - break; - case BINN_STORAGE_WORD: - copy_be16((u16*)p, (u16*)pvalue); - item->used_size += 2; - break; - case BINN_STORAGE_DWORD: - copy_be32((u32*)p, (u32*)pvalue); - item->used_size += 4; - break; - case BINN_STORAGE_QWORD: - copy_be64((u64*)p, (u64*)pvalue); - item->used_size += 8; - break; - case BINN_STORAGE_BLOB: - copy_be32((u32*)p, (u32*)&size); - p += 4; - memcpy(p, pvalue, size); - item->used_size += 4 + size; - break; - case BINN_STORAGE_STRING: - if (size > 127) { - int32 = size | 0x80000000; - copy_be32((u32*)p, (u32*)&int32); - p += 4; - item->used_size += 4; - } else { - *((unsigned char *) p) = size; - p++; - item->used_size++; - } - memcpy(p, pvalue, size); - p += size; - *((char *) p) = (char) 0; - size++; // null terminator - item->used_size += size; - break; - case BINN_STORAGE_CONTAINER: - memcpy(p, pvalue, size); - item->used_size += size; - break; - } - - item->dirty = TRUE; - - return TRUE; -} - -/***************************************************************************/ - -BINN_PRIVATE BOOL binn_save_header(binn *item) { - unsigned char byte, *p; - int int32, size; - - if (item == NULL) return FALSE; - -#ifndef BINN_DISABLE_SMALL_HEADER - - p = ((unsigned char *) item->pbuf) + MAX_BINN_HEADER; - size = item->used_size - MAX_BINN_HEADER + 3; // at least 3 bytes for the header - - // write the count - if (item->count > 127) { - p -= 4; - size += 3; - int32 = item->count | 0x80000000; - copy_be32((u32*)p, (u32*)&int32); - } else { - p--; - *p = (unsigned char) item->count; - } - - // write the size - if (size > 127) { - p -= 4; - size += 3; - int32 = size | 0x80000000; - copy_be32((u32*)p, (u32*)&int32); - } else { - p--; - *p = (unsigned char) size; - } - - // write the type. - p--; - *p = (unsigned char) item->type; - - // set the values - item->ptr = p; - item->size = size; - - UNUSED(byte); - -#else - - p = (unsigned char *) item->pbuf; - - // write the type. - byte = item->type; - *p = byte; p++; - // write the size - int32 = item->used_size | 0x80000000; - copy_be32((u32*)p, (u32*)&int32); - p+=4; - // write the count - int32 = item->count | 0x80000000; - copy_be32((u32*)p, (u32*)&int32); - - item->ptr = item->pbuf; - item->size = item->used_size; - -#endif - - item->dirty = FALSE; - - return TRUE; - -} - -/***************************************************************************/ - -void APIENTRY binn_free(binn *item) { - - if (item == NULL) return; - - if ((item->writable) && (item->pre_allocated == FALSE)) { - free_fn(item->pbuf); - } - - if (item->freefn) item->freefn(item->ptr); - - if (item->allocated) { - free_fn(item); - } else { - memset(item, 0, sizeof(binn)); - item->header = BINN_MAGIC; - } - -} - -/***************************************************************************/ -// free the binn structure but keeps the binn buffer allocated, returning a pointer to it. use the free function to release the buffer later -void * APIENTRY binn_release(binn *item) { - void *data; - - if (item == NULL) return NULL; - - data = binn_ptr(item); - - if (data > item->pbuf) { - memmove(item->pbuf, data, item->size); - data = item->pbuf; - } - - if (item->allocated) { - free_fn(item); - } else { - memset(item, 0, sizeof(binn)); - item->header = BINN_MAGIC; - } - - return data; - -} - -/***************************************************************************/ - -BINN_PRIVATE BOOL IsValidBinnHeader(void *pbuf, int *ptype, int *pcount, int *psize, int *pheadersize) { - unsigned char byte, *p, *plimit=0; - int int32, type, size, count; - - if (pbuf == NULL) return FALSE; - - p = (unsigned char *) pbuf; - - if (psize && *psize > 0) { - plimit = p + *psize - 1; - } - - // get the type - byte = *p; p++; - if ((byte & BINN_STORAGE_MASK) != BINN_STORAGE_CONTAINER) return FALSE; - if (byte & BINN_STORAGE_HAS_MORE) return FALSE; - type = byte; - - switch (type) { - case BINN_LIST: - case BINN_MAP: - case BINN_OBJECT: - break; - default: - return FALSE; - } - - // get the size - if (plimit && p > plimit) return FALSE; - int32 = *((unsigned char*)p); - if (int32 & 0x80) { - if (plimit && p + sizeof(int) - 1 > plimit) return FALSE; - copy_be32((u32*)&int32, (u32*)p); - int32 &= 0x7FFFFFFF; - p+=4; - } else { - p++; - } - size = int32; - - // get the count - if (plimit && p > plimit) return FALSE; - int32 = *((unsigned char*)p); - if (int32 & 0x80) { - if (plimit && p + sizeof(int) - 1 > plimit) return FALSE; - copy_be32((u32*)&int32, (u32*)p); - int32 &= 0x7FFFFFFF; - p+=4; - } else { - p++; - } - count = int32; - -#if 0 - // get the size - copy_be32((u32*)&size, (u32*)p); - size &= 0x7FFFFFFF; - p+=4; - - // get the count - copy_be32((u32*)&count, (u32*)p); - count &= 0x7FFFFFFF; - p+=4; -#endif - - if ((size < MIN_BINN_SIZE) || (count < 0)) return FALSE; - - // return the values - if (ptype) *ptype = type; - if (pcount) *pcount = count; - if (psize && *psize==0) *psize = size; - if (pheadersize) *pheadersize = (int) (p - (unsigned char*)pbuf); - return TRUE; -} - -/***************************************************************************/ - -BINN_PRIVATE int binn_buf_type(void *pbuf) { - int type; - - if (!IsValidBinnHeader(pbuf, &type, NULL, NULL, NULL)) return INVALID_BINN; - - return type; - -} - -/***************************************************************************/ - -BINN_PRIVATE int binn_buf_count(void *pbuf) { - int nitems; - - if (!IsValidBinnHeader(pbuf, NULL, &nitems, NULL, NULL)) return 0; - - return nitems; - -} - -/***************************************************************************/ - -BINN_PRIVATE int binn_buf_size(void *pbuf) { - int size=0; - - if (!IsValidBinnHeader(pbuf, NULL, NULL, &size, NULL)) return 0; - - return size; - -} - -/***************************************************************************/ - -void * APIENTRY binn_ptr(void *ptr) { - binn *item; - - switch (binn_get_ptr_type(ptr)) { - case BINN_STRUCT: - item = (binn*) ptr; - if (item->writable && item->dirty) { - binn_save_header(item); - } - return item->ptr; - case BINN_BUFFER: - return ptr; - default: - return NULL; - } - -} - -/***************************************************************************/ - -int APIENTRY binn_size(void *ptr) { - binn *item; - - switch (binn_get_ptr_type(ptr)) { - case BINN_STRUCT: - item = (binn*) ptr; - if (item->writable && item->dirty) { - binn_save_header(item); - } - return item->size; - case BINN_BUFFER: - return binn_buf_size(ptr); - default: - return 0; - } - -} - -/***************************************************************************/ - -int APIENTRY binn_type(void *ptr) { - binn *item; - - switch (binn_get_ptr_type(ptr)) { - case BINN_STRUCT: - item = (binn*) ptr; - return item->type; - case BINN_BUFFER: - return binn_buf_type(ptr); - default: - return -1; - } - -} - -/***************************************************************************/ - -int APIENTRY binn_count(void *ptr) { - binn *item; - - switch (binn_get_ptr_type(ptr)) { - case BINN_STRUCT: - item = (binn*) ptr; - return item->count; - case BINN_BUFFER: - return binn_buf_count(ptr); - default: - return -1; - } - -} - -/***************************************************************************/ - -BOOL APIENTRY binn_is_valid_ex(void *ptr, int *ptype, int *pcount, int *psize) { - int i, type, count, size, header_size; - unsigned char *p, *plimit, *base, len; - void *pbuf; - - pbuf = binn_ptr(ptr); - if (pbuf == NULL) return FALSE; - - // is there an informed size? - if (psize && *psize > 0) { - size = *psize; - } else { - size = 0; - } - - if (!IsValidBinnHeader(pbuf, &type, &count, &size, &header_size)) return FALSE; - - // is there an informed size? - if (psize && *psize > 0) { - // is it the same as the one in the buffer? - if (size != *psize) return FALSE; - } - // is there an informed count? - if (pcount && *pcount > 0) { - // is it the same as the one in the buffer? - if (count != *pcount) return FALSE; - } - // is there an informed type? - if (ptype && *ptype != 0) { - // is it the same as the one in the buffer? - if (type != *ptype) return FALSE; - } - - // it could compare the content size with the size informed on the header - - p = (unsigned char *)pbuf; - base = p; - plimit = p + size; - - p += header_size; - - // process all the arguments. - for (i = 0; i < count; i++) { - switch (type) { - case BINN_OBJECT: - // gets the string size (argument name) - len = *p; - p++; - //if (len == 0) goto Invalid; - // increment the used space - p += len; - break; - case BINN_MAP: - // increment the used space - p += 4; - break; - //case BINN_LIST: - // break; - } - // xxx - p = AdvanceDataPos(p, plimit); - if ((p == 0) || (p < base)) goto Invalid; - } - - if (ptype && *ptype==0) *ptype = type; - if (pcount && *pcount==0) *pcount = count; - if (psize && *psize==0) *psize = size; - return TRUE; - -Invalid: - return FALSE; - -} - -/***************************************************************************/ - -BOOL APIENTRY binn_is_valid(void *ptr, int *ptype, int *pcount, int *psize) { - - if (ptype) *ptype = 0; - if (pcount) *pcount = 0; - if (psize) *psize = 0; - - return binn_is_valid_ex(ptr, ptype, pcount, psize); - -} - -/***************************************************************************/ -/*** INTERNAL FUNCTIONS ****************************************************/ -/***************************************************************************/ - -BINN_PRIVATE BOOL GetValue(unsigned char *p, binn *value) { - unsigned char byte; - int data_type, storage_type; //, extra_type; - int DataSize; - void *p2; - - if (value == NULL) return FALSE; - memset(value, 0, sizeof(binn)); - value->header = BINN_MAGIC; - //value->allocated = FALSE; -- already zeroed - //value->writable = FALSE; - - // saves for use with BINN_STORAGE_CONTAINER - p2 = p; - - // read the data type - byte = *p; p++; - storage_type = byte & BINN_STORAGE_MASK; - if (byte & BINN_STORAGE_HAS_MORE) { - data_type = byte << 8; - byte = *p; p++; - data_type |= byte; - //extra_type = data_type & BINN_TYPE_MASK16; - } else { - data_type = byte; - //extra_type = byte & BINN_TYPE_MASK; - } - - //value->storage_type = storage_type; - value->type = data_type; - - switch (storage_type) { - case BINN_STORAGE_NOBYTES: - break; - case BINN_STORAGE_BYTE: - value->vuint8 = *((unsigned char *) p); - value->ptr = p; //value->ptr = &value->vuint8; - break; - case BINN_STORAGE_WORD: - copy_be16((u16*)&value->vint16, (u16*)p); - value->ptr = &value->vint16; - break; - case BINN_STORAGE_DWORD: - copy_be32((u32*)&value->vint32, (u32*)p); - value->ptr = &value->vint32; - break; - case BINN_STORAGE_QWORD: - copy_be64((u64*)&value->vint64, (u64*)p); - value->ptr = &value->vint64; - break; - case BINN_STORAGE_BLOB: - copy_be32((u32*)&value->size, (u32*)p); - p+=4; - value->ptr = p; - break; - case BINN_STORAGE_CONTAINER: - value->ptr = p2; // <-- it returns the pointer to the container, not the data - if (IsValidBinnHeader(p2, NULL, &value->count, &value->size, NULL) == FALSE) return FALSE; - break; - case BINN_STORAGE_STRING: - DataSize = *((unsigned char*)p); - if (DataSize & 0x80) { - copy_be32((u32*)&DataSize, (u32*)p); - DataSize &= 0x7FFFFFFF; - p+=4; - } else { - p++; - } - value->size = DataSize; - value->ptr = p; - break; - default: - return FALSE; - } - - // convert the returned value, if needed - - switch (value->type) { - case BINN_TRUE: - value->type = BINN_BOOL; - value->vbool = TRUE; - value->ptr = &value->vbool; - break; - case BINN_FALSE: - value->type = BINN_BOOL; - value->vbool = FALSE; - value->ptr = &value->vbool; - break; -#ifdef BINN_EXTENDED - case BINN_SINGLE_STR: - value->type = BINN_SINGLE; - value->vfloat = (float) atof((const char*)value->ptr); // converts from string to double, and then to float - value->ptr = &value->vfloat; - break; - case BINN_DOUBLE_STR: - value->type = BINN_DOUBLE; - value->vdouble = atof((const char*)value->ptr); // converts from string to double - value->ptr = &value->vdouble; - break; -#endif - /* - case BINN_DECIMAL: - case BINN_CURRENCYSTR: - case BINN_DATE: - case BINN_DATETIME: - case BINN_TIME: - */ - } - - return TRUE; - -} - -/***************************************************************************/ - -#if BYTE_ORDER == LITTLE_ENDIAN - -// on little-endian devices we store the value so we can return a pointer to integers. -// it's valid only for single-threaded apps. multi-threaded apps must use the _get_ functions instead. - -binn local_value; - -BINN_PRIVATE void * store_value(binn *value) { - - memcpy(&local_value, value, sizeof(binn)); - - switch (binn_get_read_storage(value->type)) { - case BINN_STORAGE_NOBYTES: - // return a valid pointer - case BINN_STORAGE_WORD: - case BINN_STORAGE_DWORD: - case BINN_STORAGE_QWORD: - return &local_value.vint32; // returns the pointer to the converted value, from big-endian to little-endian - } - - return value->ptr; // returns from the on stack value to be thread-safe (for list, map, object, string and blob) - -} - -#endif - -/***************************************************************************/ -/*** READ FUNCTIONS ********************************************************/ -/***************************************************************************/ - -BOOL APIENTRY binn_object_get_value(void *ptr, char *key, binn *value) { - int type, count, size=0, header_size; - unsigned char *p; - - ptr = binn_ptr(ptr); - if ((ptr == 0) || (key == 0) || (value == 0)) return FALSE; - - // check the header - if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; - - if (type != BINN_OBJECT) return FALSE; - if (count == 0) return FALSE; - - p = (unsigned char *) ptr; - p = SearchForKey(p, header_size, size, count, key); - if (p == FALSE) return FALSE; - - return GetValue(p, value); - -} - -/***************************************************************************/ - -BOOL APIENTRY binn_map_get_value(void* ptr, int id, binn *value) { - int type, count, size=0, header_size; - unsigned char *p; - - ptr = binn_ptr(ptr); - if ((ptr == 0) || (value == 0)) return FALSE; - - // check the header - if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; - - if (type != BINN_MAP) return FALSE; - if (count == 0) return FALSE; - - p = (unsigned char *) ptr; - p = SearchForID(p, header_size, size, count, id); - if (p == FALSE) return FALSE; - - return GetValue(p, value); - -} - -/***************************************************************************/ - -BOOL APIENTRY binn_list_get_value(void* ptr, int pos, binn *value) { - int i, type, count, size=0, header_size; - unsigned char *p, *plimit, *base; - - ptr = binn_ptr(ptr); - if ((ptr == 0) || (value == 0)) return FALSE; - - // check the header - if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; - - if (type != BINN_LIST) return FALSE; - if (count == 0) return FALSE; - if ((pos <= 0) | (pos > count)) return FALSE; - pos--; // convert from base 1 to base 0 - - p = (unsigned char *) ptr; - base = p; - plimit = p + size; - p += header_size; - - for (i = 0; i < pos; i++) { - p = AdvanceDataPos(p, plimit); - if ((p == 0) || (p < base)) return FALSE; - } - - return GetValue(p, value); - -} - -/***************************************************************************/ -/*** READ PAIR BY POSITION *************************************************/ -/***************************************************************************/ - -BINN_PRIVATE BOOL binn_read_pair(int expected_type, void *ptr, int pos, int *pid, char *pkey, binn *value) { - int type, count, size=0, header_size; - int i, int32, id, counter=0; - unsigned char *p, *plimit, *base, *key, len; - - ptr = binn_ptr(ptr); - - // check the header - if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; - - if ((type != expected_type) || (count == 0) || (pos < 1) || (pos > count)) return FALSE; - - p = (unsigned char *) ptr; - base = p; - plimit = p + size - 1; - p += header_size; - - for (i = 0; i < count; i++) { - switch (type) { - case BINN_MAP: - copy_be32((u32*)&int32, (u32*)p); - p += 4; - if (p > plimit) return FALSE; - id = int32; - break; - case BINN_OBJECT: - len = *((unsigned char *)p); p++; - if (p > plimit) return FALSE; - key = p; - p += len; - if (p > plimit) return FALSE; - break; - } - counter++; - if (counter == pos) goto found; - // - p = AdvanceDataPos(p, plimit); - if ((p == 0) || (p < base)) return FALSE; - } - - return FALSE; - -found: - - switch (type) { - case BINN_MAP: - if (pid) *pid = id; - break; - case BINN_OBJECT: - if (pkey) { - memcpy(pkey, key, len); - pkey[len] = 0; - } - break; - } - - return GetValue(p, value); - -} - -/***************************************************************************/ - -BOOL APIENTRY binn_map_get_pair(void *ptr, int pos, int *pid, binn *value) { - - return binn_read_pair(BINN_MAP, ptr, pos, pid, NULL, value); - -} - -/***************************************************************************/ - -BOOL APIENTRY binn_object_get_pair(void *ptr, int pos, char *pkey, binn *value) { - - return binn_read_pair(BINN_OBJECT, ptr, pos, NULL, pkey, value); - -} - -/***************************************************************************/ - -binn * APIENTRY binn_map_pair(void *map, int pos, int *pid) { - binn *value; - - value = (binn *) binn_malloc(sizeof(binn)); - - if (binn_read_pair(BINN_MAP, map, pos, pid, NULL, value) == FALSE) { - free_fn(value); - return NULL; - } - - value->allocated = TRUE; - return value; - -} - -/***************************************************************************/ - -binn * APIENTRY binn_object_pair(void *obj, int pos, char *pkey) { - binn *value; - - value = (binn *) binn_malloc(sizeof(binn)); - - if (binn_read_pair(BINN_OBJECT, obj, pos, NULL, pkey, value) == FALSE) { - free_fn(value); - return NULL; - } - - value->allocated = TRUE; - return value; - -} - -/***************************************************************************/ -/***************************************************************************/ - -void * APIENTRY binn_map_read_pair(void *ptr, int pos, int *pid, int *ptype, int *psize) { - binn value; - - if (binn_map_get_pair(ptr, pos, pid, &value) == FALSE) return NULL; - if (ptype) *ptype = value.type; - if (psize) *psize = value.size; -#if BYTE_ORDER == LITTLE_ENDIAN - return store_value(&value); -#else - return value.ptr; -#endif - -} - -/***************************************************************************/ - -void * APIENTRY binn_object_read_pair(void *ptr, int pos, char *pkey, int *ptype, int *psize) { - binn value; - - if (binn_object_get_pair(ptr, pos, pkey, &value) == FALSE) return NULL; - if (ptype) *ptype = value.type; - if (psize) *psize = value.size; -#if BYTE_ORDER == LITTLE_ENDIAN - return store_value(&value); -#else - return value.ptr; -#endif - -} - -/***************************************************************************/ -/*** SEQUENTIAL READ FUNCTIONS *********************************************/ -/***************************************************************************/ - -BOOL APIENTRY binn_iter_init(binn_iter *iter, void *ptr, int expected_type) { - int type, count, size=0, header_size; - - ptr = binn_ptr(ptr); - if ((ptr == 0) || (iter == 0)) return FALSE; - memset(iter, 0, sizeof(binn_iter)); - - // check the header - if (IsValidBinnHeader(ptr, &type, &count, &size, &header_size) == FALSE) return FALSE; - - if (type != expected_type) return FALSE; - //if (count == 0) return FALSE; -- should not be used - - iter->plimit = (unsigned char *)ptr + size - 1; - iter->pnext = (unsigned char *)ptr + header_size; - iter->count = count; - iter->current = 0; - iter->type = type; - - return TRUE; -} - -/***************************************************************************/ - -BOOL APIENTRY binn_list_next(binn_iter *iter, binn *value) { - unsigned char *pnow; - - if ((iter == 0) || (iter->pnext == 0) || (iter->pnext > iter->plimit) || (iter->current > iter->count) || (iter->type != BINN_LIST)) return FALSE; - - iter->current++; - if (iter->current > iter->count) return FALSE; - - pnow = iter->pnext; - iter->pnext = AdvanceDataPos(pnow, iter->plimit); - if (iter->pnext != 0 && iter->pnext < pnow) return FALSE; - - return GetValue(pnow, value); - -} - -/***************************************************************************/ - -BINN_PRIVATE BOOL binn_read_next_pair(int expected_type, binn_iter *iter, int *pid, char *pkey, binn *value) { - int int32, id; - unsigned char *p, *key; - unsigned short len; - - if ((iter == 0) || (iter->pnext == 0) || (iter->pnext > iter->plimit) || (iter->current > iter->count) || (iter->type != expected_type)) return FALSE; - - iter->current++; - if (iter->current > iter->count) return FALSE; - - p = iter->pnext; - - switch (expected_type) { - case BINN_MAP: - copy_be32((u32*)&int32, (u32*)p); - p += 4; - if (p > iter->plimit) return FALSE; - id = int32; - if (pid) *pid = id; - break; - case BINN_OBJECT: - len = *((unsigned char *)p); p++; - key = p; - p += len; - if (p > iter->plimit) return FALSE; - if (pkey) { - memcpy(pkey, key, len); - pkey[len] = 0; - } - break; - } - - iter->pnext = AdvanceDataPos(p, iter->plimit); - if (iter->pnext != 0 && iter->pnext < p) return FALSE; - - return GetValue(p, value); - -} - -/***************************************************************************/ - -BOOL APIENTRY binn_map_next(binn_iter *iter, int *pid, binn *value) { - - return binn_read_next_pair(BINN_MAP, iter, pid, NULL, value); - -} - -/***************************************************************************/ - -BOOL APIENTRY binn_object_next(binn_iter *iter, char *pkey, binn *value) { - - return binn_read_next_pair(BINN_OBJECT, iter, NULL, pkey, value); - -} - -/***************************************************************************/ -/***************************************************************************/ - -binn * APIENTRY binn_list_next_value(binn_iter *iter) { - binn *value; - - value = (binn *) binn_malloc(sizeof(binn)); - - if (binn_list_next(iter, value) == FALSE) { - free_fn(value); - return NULL; - } - - value->allocated = TRUE; - return value; - -} - -/***************************************************************************/ - -binn * APIENTRY binn_map_next_value(binn_iter *iter, int *pid) { - binn *value; - - value = (binn *) binn_malloc(sizeof(binn)); - - if (binn_map_next(iter, pid, value) == FALSE) { - free_fn(value); - return NULL; - } - - value->allocated = TRUE; - return value; - -} - -/***************************************************************************/ - -binn * APIENTRY binn_object_next_value(binn_iter *iter, char *pkey) { - binn *value; - - value = (binn *) binn_malloc(sizeof(binn)); - - if (binn_object_next(iter, pkey, value) == FALSE) { - free_fn(value); - return NULL; - } - - value->allocated = TRUE; - return value; - -} - -/***************************************************************************/ -/***************************************************************************/ - -void * APIENTRY binn_list_read_next(binn_iter *iter, int *ptype, int *psize) { - binn value; - - if (binn_list_next(iter, &value) == FALSE) return NULL; - if (ptype) *ptype = value.type; - if (psize) *psize = value.size; -#if BYTE_ORDER == LITTLE_ENDIAN - return store_value(&value); -#else - return value.ptr; -#endif - -} - -/***************************************************************************/ - -void * APIENTRY binn_map_read_next(binn_iter *iter, int *pid, int *ptype, int *psize) { - binn value; - - if (binn_map_next(iter, pid, &value) == FALSE) return NULL; - if (ptype) *ptype = value.type; - if (psize) *psize = value.size; -#if BYTE_ORDER == LITTLE_ENDIAN - return store_value(&value); -#else - return value.ptr; -#endif - -} - -/***************************************************************************/ - -void * APIENTRY binn_object_read_next(binn_iter *iter, char *pkey, int *ptype, int *psize) { - binn value; - - if (binn_object_next(iter, pkey, &value) == FALSE) return NULL; - if (ptype) *ptype = value.type; - if (psize) *psize = value.size; -#if BYTE_ORDER == LITTLE_ENDIAN - return store_value(&value); -#else - return value.ptr; -#endif - -} - -/*************************************************************************************/ -/****** EXTENDED INTERFACE ***********************************************************/ -/****** none of the functions above call the functions below *************************/ -/*************************************************************************************/ - -int APIENTRY binn_get_write_storage(int type) { - int storage_type; - - switch (type) { - case BINN_SINGLE_STR: - case BINN_DOUBLE_STR: - return BINN_STORAGE_STRING; - - case BINN_BOOL: - return BINN_STORAGE_NOBYTES; - - default: - binn_get_type_info(type, &storage_type, NULL); - return storage_type; - } - -} - -/*************************************************************************************/ - -int APIENTRY binn_get_read_storage(int type) { - int storage_type; - - switch (type) { -#ifdef BINN_EXTENDED - case BINN_SINGLE_STR: - return BINN_STORAGE_DWORD; - case BINN_DOUBLE_STR: - return BINN_STORAGE_QWORD; -#endif - case BINN_BOOL: - case BINN_TRUE: - case BINN_FALSE: - return BINN_STORAGE_DWORD; - default: - binn_get_type_info(type, &storage_type, NULL); - return storage_type; - } - -} - -/*************************************************************************************/ - -BINN_PRIVATE BOOL GetWriteConvertedData(int *ptype, void **ppvalue, int *psize) { - int type; - float f1; - double d1; - char pstr[128]; - - UNUSED(pstr); - UNUSED(d1); - UNUSED(f1); - - type = *ptype; - - if (*ppvalue == NULL) { - switch (type) { - case BINN_NULL: - case BINN_TRUE: - case BINN_FALSE: - break; - case BINN_STRING: - case BINN_BLOB: - if (*psize == 0) break; - default: - return FALSE; - } - } - - switch (type) { -#ifdef BINN_EXTENDED - case BINN_SINGLE: - f1 = **(float**)ppvalue; - d1 = f1; // convert from float (32bits) to double (64bits) - type = BINN_SINGLE_STR; - goto conv_double; - case BINN_DOUBLE: - d1 = **(double**)ppvalue; - type = BINN_DOUBLE_STR; -conv_double: - // the '%.17e' is more precise than the '%g' - snprintf(pstr, 127, "%.17e", d1); - *ppvalue = pstr; - *ptype = type; - break; -#endif - case BINN_DECIMAL: - case BINN_CURRENCYSTR: - /* - if (binn_malloc_extptr(128) == NULL) return FALSE; - snprintf(sptr, 127, "%E", **ppvalue); - *ppvalue = sptr; - */ - return TRUE; //! temporary - break; - - case BINN_DATE: - case BINN_DATETIME: - case BINN_TIME: - return TRUE; //! temporary - break; - - case BINN_BOOL: - if (**((BOOL**)ppvalue) == FALSE) { - type = BINN_FALSE; - } else { - type = BINN_TRUE; - } - *ptype = type; - break; - - } - - return TRUE; - -} - -/*************************************************************************************/ - -BINN_PRIVATE int type_family(int type) { - - switch (type) { - case BINN_LIST: - case BINN_MAP: - case BINN_OBJECT: - return BINN_FAMILY_BINN; - - case BINN_INT8: - case BINN_INT16: - case BINN_INT32: - case BINN_INT64: - case BINN_UINT8: - case BINN_UINT16: - case BINN_UINT32: - case BINN_UINT64: - return BINN_FAMILY_INT; - - case BINN_FLOAT32: - case BINN_FLOAT64: - //case BINN_SINGLE: - case BINN_SINGLE_STR: - //case BINN_DOUBLE: - case BINN_DOUBLE_STR: - return BINN_FAMILY_FLOAT; - - case BINN_STRING: - case BINN_HTML: - case BINN_CSS: - case BINN_XML: - case BINN_JSON: - case BINN_JAVASCRIPT: - return BINN_FAMILY_STRING; - - case BINN_BLOB: - case BINN_JPEG: - case BINN_GIF: - case BINN_PNG: - case BINN_BMP: - return BINN_FAMILY_BLOB; - - case BINN_DECIMAL: - case BINN_CURRENCY: - case BINN_DATE: - case BINN_TIME: - case BINN_DATETIME: - return BINN_FAMILY_STRING; - - case BINN_BOOL: - return BINN_FAMILY_BOOL; - - case BINN_NULL: - return BINN_FAMILY_NULL; - - default: - // if it wasn't found - return BINN_FAMILY_NONE; - } - -} - -/*************************************************************************************/ - -BINN_PRIVATE int int_type(int type) { - - switch (type) { - case BINN_INT8: - case BINN_INT16: - case BINN_INT32: - case BINN_INT64: - return BINN_SIGNED_INT; - - case BINN_UINT8: - case BINN_UINT16: - case BINN_UINT32: - case BINN_UINT64: - return BINN_UNSIGNED_INT; - - default: - return 0; - } - -} - -/*************************************************************************************/ - -BINN_PRIVATE BOOL copy_raw_value(void *psource, void *pdest, int data_store) { - - switch (data_store) { - case BINN_STORAGE_NOBYTES: - break; - case BINN_STORAGE_BYTE: - *((char *) pdest) = *(char *)psource; - break; - case BINN_STORAGE_WORD: - *((short *) pdest) = *(short *)psource; - break; - case BINN_STORAGE_DWORD: - *((int *) pdest) = *(int *)psource; - break; - case BINN_STORAGE_QWORD: - *((uint64 *) pdest) = *(uint64 *)psource; - break; - case BINN_STORAGE_BLOB: - case BINN_STORAGE_STRING: - case BINN_STORAGE_CONTAINER: - *((char **) pdest) = (char *)psource; - break; - default: - return FALSE; - } - - return TRUE; - -} - -/*************************************************************************************/ - -BINN_PRIVATE BOOL copy_int_value(void *psource, void *pdest, int source_type, int dest_type) { - uint64 vuint64; int64 vint64; - - switch (source_type) { - case BINN_INT8: - vint64 = *(signed char *)psource; - break; - case BINN_INT16: - vint64 = *(short *)psource; - break; - case BINN_INT32: - vint64 = *(int *)psource; - break; - case BINN_INT64: - vint64 = *(int64 *)psource; - break; - - case BINN_UINT8: - vuint64 = *(unsigned char *)psource; - break; - case BINN_UINT16: - vuint64 = *(unsigned short *)psource; - break; - case BINN_UINT32: - vuint64 = *(unsigned int *)psource; - break; - case BINN_UINT64: - vuint64 = *(uint64 *)psource; - break; - - default: - return FALSE; - } - - - // copy from int64 to uint64, if possible - - if ((int_type(source_type) == BINN_UNSIGNED_INT) && (int_type(dest_type) == BINN_SIGNED_INT)) { - if (vuint64 > INT64_MAX) return FALSE; - vint64 = vuint64; - } else if ((int_type(source_type) == BINN_SIGNED_INT) && (int_type(dest_type) == BINN_UNSIGNED_INT)) { - if (vint64 < 0) return FALSE; - vuint64 = vint64; - } - - - switch (dest_type) { - case BINN_INT8: - if ((vint64 < INT8_MIN) || (vint64 > INT8_MAX)) return FALSE; - *(signed char *)pdest = (signed char) vint64; - break; - case BINN_INT16: - if ((vint64 < INT16_MIN) || (vint64 > INT16_MAX)) return FALSE; - *(short *)pdest = (short) vint64; - break; - case BINN_INT32: - if ((vint64 < INT32_MIN) || (vint64 > INT32_MAX)) return FALSE; - *(int *)pdest = (int) vint64; - break; - case BINN_INT64: - *(int64 *)pdest = vint64; - break; - - case BINN_UINT8: - if (vuint64 > UINT8_MAX) return FALSE; - *(unsigned char *)pdest = (unsigned char) vuint64; - break; - case BINN_UINT16: - if (vuint64 > UINT16_MAX) return FALSE; - *(unsigned short *)pdest = (unsigned short) vuint64; - break; - case BINN_UINT32: - if (vuint64 > UINT32_MAX) return FALSE; - *(unsigned int *)pdest = (unsigned int) vuint64; - break; - case BINN_UINT64: - *(uint64 *)pdest = vuint64; - break; - - default: - return FALSE; - } - - return TRUE; - -} - -/*************************************************************************************/ - -BINN_PRIVATE BOOL copy_float_value(void *psource, void *pdest, int source_type, int dest_type) { - - switch (source_type) { - case BINN_FLOAT32: - *(double *)pdest = *(float *)psource; - break; - case BINN_FLOAT64: - *(float *)pdest = (float) *(double *)psource; - break; - default: - return FALSE; - } - - return TRUE; - -} - -/*************************************************************************************/ - -BINN_PRIVATE void zero_value(void *pvalue, int type) { - //int size=0; - - switch (binn_get_read_storage(type)) { - case BINN_STORAGE_NOBYTES: - break; - case BINN_STORAGE_BYTE: - *((char *) pvalue) = 0; - //size=1; - break; - case BINN_STORAGE_WORD: - *((short *) pvalue) = 0; - //size=2; - break; - case BINN_STORAGE_DWORD: - *((int *) pvalue) = 0; - //size=4; - break; - case BINN_STORAGE_QWORD: - *((uint64 *) pvalue) = 0; - //size=8; - break; - case BINN_STORAGE_BLOB: - case BINN_STORAGE_STRING: - case BINN_STORAGE_CONTAINER: - *(char **)pvalue = NULL; - break; - } - - //if (size>0) memset(pvalue, 0, size); - -} - -/*************************************************************************************/ - -BINN_PRIVATE BOOL copy_value(void *psource, void *pdest, int source_type, int dest_type, int data_store) { - - if (type_family(source_type) != type_family(dest_type)) return FALSE; - - if ((type_family(source_type) == BINN_FAMILY_INT) && (source_type != dest_type)) { - return copy_int_value(psource, pdest, source_type, dest_type); - } else if ((type_family(source_type) == BINN_FAMILY_FLOAT) && (source_type != dest_type)) { - return copy_float_value(psource, pdest, source_type, dest_type); - } else { - return copy_raw_value(psource, pdest, data_store); - } - -} - -/*************************************************************************************/ -/*** WRITE FUNCTIONS *****************************************************************/ -/*************************************************************************************/ - -BOOL APIENTRY binn_list_add(binn *list, int type, void *pvalue, int size) { - - if (GetWriteConvertedData(&type, &pvalue, &size) == FALSE) return FALSE; - - return binn_list_add_raw(list, type, pvalue, size); - -} - -/*************************************************************************************/ - -BOOL APIENTRY binn_map_set(binn *map, int id, int type, void *pvalue, int size) { - - if (GetWriteConvertedData(&type, &pvalue, &size) == FALSE) return FALSE; - - return binn_map_set_raw(map, id, type, pvalue, size); - -} - -/*************************************************************************************/ - -BOOL APIENTRY binn_object_set(binn *obj, char *key, int type, void *pvalue, int size) { - - if (GetWriteConvertedData(&type, &pvalue, &size) == FALSE) return FALSE; - - return binn_object_set_raw(obj, key, type, pvalue, size); - -} - -/*************************************************************************************/ - -// this function is used by the wrappers -BOOL APIENTRY binn_add_value(binn *item, int binn_type, int id, char *name, int type, void *pvalue, int size) { - - switch (binn_type) { - case BINN_LIST: - return binn_list_add(item, type, pvalue, size); - case BINN_MAP: - return binn_map_set(item, id, type, pvalue, size); - case BINN_OBJECT: - return binn_object_set(item, name, type, pvalue, size); - default: - return FALSE; - } - -} - -/*************************************************************************************/ -/*************************************************************************************/ - -BOOL APIENTRY binn_list_add_new(binn *list, binn *value) { - BOOL retval; - - retval = binn_list_add_value(list, value); - if (value) free_fn(value); - return retval; - -} - -/*************************************************************************************/ - -BOOL APIENTRY binn_map_set_new(binn *map, int id, binn *value) { - BOOL retval; - - retval = binn_map_set_value(map, id, value); - if (value) free_fn(value); - return retval; - -} - -/*************************************************************************************/ - -BOOL APIENTRY binn_object_set_new(binn *obj, char *key, binn *value) { - BOOL retval; - - retval = binn_object_set_value(obj, key, value); - if (value) free_fn(value); - return retval; - -} - -/*************************************************************************************/ -/*** READ FUNCTIONS ******************************************************************/ -/*************************************************************************************/ - -binn * APIENTRY binn_list_value(void *ptr, int pos) { - binn *value; - - value = (binn *) binn_malloc(sizeof(binn)); - - if (binn_list_get_value(ptr, pos, value) == FALSE) { - free_fn(value); - return NULL; - } - - value->allocated = TRUE; - return value; - -} - -/*************************************************************************************/ - -binn * APIENTRY binn_map_value(void *ptr, int id) { - binn *value; - - value = (binn *) binn_malloc(sizeof(binn)); - - if (binn_map_get_value(ptr, id, value) == FALSE) { - free_fn(value); - return NULL; - } - - value->allocated = TRUE; - return value; - -} - -/*************************************************************************************/ - -binn * APIENTRY binn_object_value(void *ptr, char *key) { - binn *value; - - value = (binn *) binn_malloc(sizeof(binn)); - - if (binn_object_get_value(ptr, key, value) == FALSE) { - free_fn(value); - return NULL; - } - - value->allocated = TRUE; - return value; - -} - -/***************************************************************************/ -/***************************************************************************/ - -void * APIENTRY binn_list_read(void *list, int pos, int *ptype, int *psize) { - binn value; - - if (binn_list_get_value(list, pos, &value) == FALSE) return NULL; - if (ptype) *ptype = value.type; - if (psize) *psize = value.size; -#if BYTE_ORDER == LITTLE_ENDIAN - return store_value(&value); -#else - return value.ptr; -#endif - -} - -/***************************************************************************/ - -void * APIENTRY binn_map_read(void *map, int id, int *ptype, int *psize) { - binn value; - - if (binn_map_get_value(map, id, &value) == FALSE) return NULL; - if (ptype) *ptype = value.type; - if (psize) *psize = value.size; -#if BYTE_ORDER == LITTLE_ENDIAN - return store_value(&value); -#else - return value.ptr; -#endif - -} - -/***************************************************************************/ - -void * APIENTRY binn_object_read(void *obj, char *key, int *ptype, int *psize) { - binn value; - - if (binn_object_get_value(obj, key, &value) == FALSE) return NULL; - if (ptype) *ptype = value.type; - if (psize) *psize = value.size; -#if BYTE_ORDER == LITTLE_ENDIAN - return store_value(&value); -#else - return value.ptr; -#endif - -} - -/***************************************************************************/ -/***************************************************************************/ - -BOOL APIENTRY binn_list_get(void *ptr, int pos, int type, void *pvalue, int *psize) { - binn value; - int storage_type; - - storage_type = binn_get_read_storage(type); - if ((storage_type != BINN_STORAGE_NOBYTES) && (pvalue == NULL)) return FALSE; - - zero_value(pvalue, type); - - if (binn_list_get_value(ptr, pos, &value) == FALSE) return FALSE; - - if (copy_value(value.ptr, pvalue, value.type, type, storage_type) == FALSE) return FALSE; - - if (psize) *psize = value.size; - - return TRUE; - -} - -/***************************************************************************/ - -BOOL APIENTRY binn_map_get(void *ptr, int id, int type, void *pvalue, int *psize) { - binn value; - int storage_type; - - storage_type = binn_get_read_storage(type); - if ((storage_type != BINN_STORAGE_NOBYTES) && (pvalue == NULL)) return FALSE; - - zero_value(pvalue, type); - - if (binn_map_get_value(ptr, id, &value) == FALSE) return FALSE; - - if (copy_value(value.ptr, pvalue, value.type, type, storage_type) == FALSE) return FALSE; - - if (psize) *psize = value.size; - - return TRUE; - -} - -/***************************************************************************/ - -// if (binn_object_get(obj, "multiplier", BINN_INT32, &multiplier, NULL) == FALSE) xxx; - -BOOL APIENTRY binn_object_get(void *ptr, char *key, int type, void *pvalue, int *psize) { - binn value; - int storage_type; - - storage_type = binn_get_read_storage(type); - if ((storage_type != BINN_STORAGE_NOBYTES) && (pvalue == NULL)) return FALSE; - - zero_value(pvalue, type); - - if (binn_object_get_value(ptr, key, &value) == FALSE) return FALSE; - - if (copy_value(value.ptr, pvalue, value.type, type, storage_type) == FALSE) return FALSE; - - if (psize) *psize = value.size; - - return TRUE; - -} - -/***************************************************************************/ -/***************************************************************************/ - -// these functions below may not be implemented as inline functions, because -// they use a lot of space, even for the variable. so they will be exported. - -// but what about using as static? -// is there any problem with wrappers? can these wrappers implement these functions using the header? -// if as static, will they be present even on modules that don't use the functions? - -signed char APIENTRY binn_list_int8(void *list, int pos) { - signed char value; - - binn_list_get(list, pos, BINN_INT8, &value, NULL); - - return value; -} - -short APIENTRY binn_list_int16(void *list, int pos) { - short value; - - binn_list_get(list, pos, BINN_INT16, &value, NULL); - - return value; -} - -int APIENTRY binn_list_int32(void *list, int pos) { - int value; - - binn_list_get(list, pos, BINN_INT32, &value, NULL); - - return value; -} - -int64 APIENTRY binn_list_int64(void *list, int pos) { - int64 value; - - binn_list_get(list, pos, BINN_INT64, &value, NULL); - - return value; -} - -unsigned char APIENTRY binn_list_uint8(void *list, int pos) { - unsigned char value; - - binn_list_get(list, pos, BINN_UINT8, &value, NULL); - - return value; -} - -unsigned short APIENTRY binn_list_uint16(void *list, int pos) { - unsigned short value; - - binn_list_get(list, pos, BINN_UINT16, &value, NULL); - - return value; -} - -unsigned int APIENTRY binn_list_uint32(void *list, int pos) { - unsigned int value; - - binn_list_get(list, pos, BINN_UINT32, &value, NULL); - - return value; -} - -uint64 APIENTRY binn_list_uint64(void *list, int pos) { - uint64 value; - - binn_list_get(list, pos, BINN_UINT64, &value, NULL); - - return value; -} - -float APIENTRY binn_list_float(void *list, int pos) { - float value; - - binn_list_get(list, pos, BINN_FLOAT32, &value, NULL); - - return value; -} - -double APIENTRY binn_list_double(void *list, int pos) { - double value; - - binn_list_get(list, pos, BINN_FLOAT64, &value, NULL); - - return value; -} - -BOOL APIENTRY binn_list_bool(void *list, int pos) { - BOOL value; - - binn_list_get(list, pos, BINN_BOOL, &value, NULL); - - return value; -} - -BOOL APIENTRY binn_list_null(void *list, int pos) { - - return binn_list_get(list, pos, BINN_NULL, NULL, NULL); - -} - -char * APIENTRY binn_list_str(void *list, int pos) { - char *value; - - binn_list_get(list, pos, BINN_STRING, &value, NULL); - - return value; -} - -void * APIENTRY binn_list_blob(void *list, int pos, int *psize) { - void *value; - - binn_list_get(list, pos, BINN_BLOB, &value, psize); - - return value; -} - -void * APIENTRY binn_list_list(void *list, int pos) { - void *value; - - binn_list_get(list, pos, BINN_LIST, &value, NULL); - - return value; -} - -void * APIENTRY binn_list_map(void *list, int pos) { - void *value; - - binn_list_get(list, pos, BINN_MAP, &value, NULL); - - return value; -} - -void * APIENTRY binn_list_object(void *list, int pos) { - void *value; - - binn_list_get(list, pos, BINN_OBJECT, &value, NULL); - - return value; -} - -/***************************************************************************/ - -signed char APIENTRY binn_map_int8(void *map, int id) { - signed char value; - - binn_map_get(map, id, BINN_INT8, &value, NULL); - - return value; -} - -short APIENTRY binn_map_int16(void *map, int id) { - short value; - - binn_map_get(map, id, BINN_INT16, &value, NULL); - - return value; -} - -int APIENTRY binn_map_int32(void *map, int id) { - int value; - - binn_map_get(map, id, BINN_INT32, &value, NULL); - - return value; -} - -int64 APIENTRY binn_map_int64(void *map, int id) { - int64 value; - - binn_map_get(map, id, BINN_INT64, &value, NULL); - - return value; -} - -unsigned char APIENTRY binn_map_uint8(void *map, int id) { - unsigned char value; - - binn_map_get(map, id, BINN_UINT8, &value, NULL); - - return value; -} - -unsigned short APIENTRY binn_map_uint16(void *map, int id) { - unsigned short value; - - binn_map_get(map, id, BINN_UINT16, &value, NULL); - - return value; -} - -unsigned int APIENTRY binn_map_uint32(void *map, int id) { - unsigned int value; - - binn_map_get(map, id, BINN_UINT32, &value, NULL); - - return value; -} - -uint64 APIENTRY binn_map_uint64(void *map, int id) { - uint64 value; - - binn_map_get(map, id, BINN_UINT64, &value, NULL); - - return value; -} - -float APIENTRY binn_map_float(void *map, int id) { - float value; - - binn_map_get(map, id, BINN_FLOAT32, &value, NULL); - - return value; -} - -double APIENTRY binn_map_double(void *map, int id) { - double value; - - binn_map_get(map, id, BINN_FLOAT64, &value, NULL); - - return value; -} - -BOOL APIENTRY binn_map_bool(void *map, int id) { - BOOL value; - - binn_map_get(map, id, BINN_BOOL, &value, NULL); - - return value; -} - -BOOL APIENTRY binn_map_null(void *map, int id) { - - return binn_map_get(map, id, BINN_NULL, NULL, NULL); - -} - -char * APIENTRY binn_map_str(void *map, int id) { - char *value; - - binn_map_get(map, id, BINN_STRING, &value, NULL); - - return value; -} - -void * APIENTRY binn_map_blob(void *map, int id, int *psize) { - void *value; - - binn_map_get(map, id, BINN_BLOB, &value, psize); - - return value; -} - -void * APIENTRY binn_map_list(void *map, int id) { - void *value; - - binn_map_get(map, id, BINN_LIST, &value, NULL); - - return value; -} - -void * APIENTRY binn_map_map(void *map, int id) { - void *value; - - binn_map_get(map, id, BINN_MAP, &value, NULL); - - return value; -} - -void * APIENTRY binn_map_object(void *map, int id) { - void *value; - - binn_map_get(map, id, BINN_OBJECT, &value, NULL); - - return value; -} - -/***************************************************************************/ - -signed char APIENTRY binn_object_int8(void *obj, char *key) { - signed char value; - - binn_object_get(obj, key, BINN_INT8, &value, NULL); - - return value; -} - -short APIENTRY binn_object_int16(void *obj, char *key) { - short value; - - binn_object_get(obj, key, BINN_INT16, &value, NULL); - - return value; -} - -int APIENTRY binn_object_int32(void *obj, char *key) { - int value; - - binn_object_get(obj, key, BINN_INT32, &value, NULL); - - return value; -} - -int64 APIENTRY binn_object_int64(void *obj, char *key) { - int64 value; - - binn_object_get(obj, key, BINN_INT64, &value, NULL); - - return value; -} - -unsigned char APIENTRY binn_object_uint8(void *obj, char *key) { - unsigned char value; - - binn_object_get(obj, key, BINN_UINT8, &value, NULL); - - return value; -} - -unsigned short APIENTRY binn_object_uint16(void *obj, char *key) { - unsigned short value; - - binn_object_get(obj, key, BINN_UINT16, &value, NULL); - - return value; -} - -unsigned int APIENTRY binn_object_uint32(void *obj, char *key) { - unsigned int value; - - binn_object_get(obj, key, BINN_UINT32, &value, NULL); - - return value; -} - -uint64 APIENTRY binn_object_uint64(void *obj, char *key) { - uint64 value; - - binn_object_get(obj, key, BINN_UINT64, &value, NULL); - - return value; -} - -float APIENTRY binn_object_float(void *obj, char *key) { - float value; - - binn_object_get(obj, key, BINN_FLOAT32, &value, NULL); - - return value; -} - -double APIENTRY binn_object_double(void *obj, char *key) { - double value; - - binn_object_get(obj, key, BINN_FLOAT64, &value, NULL); - - return value; -} - -BOOL APIENTRY binn_object_bool(void *obj, char *key) { - BOOL value; - - binn_object_get(obj, key, BINN_BOOL, &value, NULL); - - return value; -} - -BOOL APIENTRY binn_object_null(void *obj, char *key) { - - return binn_object_get(obj, key, BINN_NULL, NULL, NULL); - -} - -char * APIENTRY binn_object_str(void *obj, char *key) { - char *value; - - binn_object_get(obj, key, BINN_STRING, &value, NULL); - - return value; -} - -void * APIENTRY binn_object_blob(void *obj, char *key, int *psize) { - void *value; - - binn_object_get(obj, key, BINN_BLOB, &value, psize); - - return value; -} - -void * APIENTRY binn_object_list(void *obj, char *key) { - void *value; - - binn_object_get(obj, key, BINN_LIST, &value, NULL); - - return value; -} - -void * APIENTRY binn_object_map(void *obj, char *key) { - void *value; - - binn_object_get(obj, key, BINN_MAP, &value, NULL); - - return value; -} - -void * APIENTRY binn_object_object(void *obj, char *key) { - void *value; - - binn_object_get(obj, key, BINN_OBJECT, &value, NULL); - - return value; -} - -/*************************************************************************************/ -/*************************************************************************************/ - -BINN_PRIVATE binn * binn_alloc_item() { - binn *item; - item = (binn *) binn_malloc(sizeof(binn)); - if (item) { - memset(item, 0, sizeof(binn)); - item->header = BINN_MAGIC; - item->allocated = TRUE; - //item->writable = FALSE; -- already zeroed - } - return item; -} - -/*************************************************************************************/ - -binn * APIENTRY binn_value(int type, void *pvalue, int size, binn_mem_free freefn) { - int storage_type; - binn *item = binn_alloc_item(); - if (item) { - item->type = type; - binn_get_type_info(type, &storage_type, NULL); - switch (storage_type) { - case BINN_STORAGE_NOBYTES: - break; - case BINN_STORAGE_STRING: - if (size == 0) size = strlen((char*)pvalue) + 1; - case BINN_STORAGE_BLOB: - case BINN_STORAGE_CONTAINER: - if (freefn == BINN_TRANSIENT) { - item->ptr = binn_memdup(pvalue, size); - if (item->ptr == NULL) { - free_fn(item); - return NULL; - } - item->freefn = free_fn; - if (storage_type == BINN_STORAGE_STRING) size--; - } else { - item->ptr = pvalue; - item->freefn = freefn; - } - item->size = size; - break; - default: - item->ptr = &item->vint32; - copy_raw_value(pvalue, item->ptr, storage_type); - } - } - return item; -} - -/*************************************************************************************/ - -BOOL APIENTRY binn_set_string(binn *item, char *str, binn_mem_free pfree) { - - if (item == NULL || str == NULL) return FALSE; - - if (pfree == BINN_TRANSIENT) { - item->ptr = binn_memdup(str, strlen(str) + 1); - if (item->ptr == NULL) return FALSE; - item->freefn = free_fn; - } else { - item->ptr = str; - item->freefn = pfree; - } - - item->type = BINN_STRING; - return TRUE; - -} - -/*************************************************************************************/ - -BOOL APIENTRY binn_set_blob(binn *item, void *ptr, int size, binn_mem_free pfree) { - - if (item == NULL || ptr == NULL) return FALSE; - - if (pfree == BINN_TRANSIENT) { - item->ptr = binn_memdup(ptr, size); - if (item->ptr == NULL) return FALSE; - item->freefn = free_fn; - } else { - item->ptr = ptr; - item->freefn = pfree; - } - - item->type = BINN_BLOB; - item->size = size; - return TRUE; - -} - -/*************************************************************************************/ -/*** READ CONVERTED VALUE ************************************************************/ -/*************************************************************************************/ - -#ifdef _MSC_VER -#define atoi64 _atoi64 -#else -int64 atoi64(char *str) { - int64 retval; - int is_negative=0; - - if (*str == '-') { - is_negative = 1; - str++; - } - retval = 0; - for (; *str; str++) { - retval = 10 * retval + (*str - '0'); - } - if (is_negative) retval *= -1; - return retval; -} -#endif - -/*****************************************************************************/ - -BINN_PRIVATE BOOL is_integer(char *p) { - BOOL retval; - - if (p == NULL) return FALSE; - if (*p == '-') p++; - if (*p == 0) return FALSE; - - retval = TRUE; - - for (; *p; p++) { - if ( (*p < '0') || (*p > '9') ) { - retval = FALSE; - } - } - - return retval; -} - -/*****************************************************************************/ - -BINN_PRIVATE BOOL is_float(char *p) { - BOOL retval, number_found=FALSE; - - if (p == NULL) return FALSE; - if (*p == '-') p++; - if (*p == 0) return FALSE; - - retval = TRUE; - - for (; *p; p++) { - if ((*p == '.') || (*p == ',')) { - if (!number_found) retval = FALSE; - } else if ( (*p >= '0') && (*p <= '9') ) { - number_found = TRUE; - } else { - return FALSE; - } - } - - return retval; -} - -/*************************************************************************************/ - -BINN_PRIVATE BOOL is_bool_str(char *str, BOOL *pbool) { - int64 vint; - double vdouble; - - if (str == NULL || pbool == NULL) return FALSE; - - if (stricmp(str, "true") == 0) goto loc_true; - if (stricmp(str, "yes") == 0) goto loc_true; - if (stricmp(str, "on") == 0) goto loc_true; - //if (stricmp(str, "1") == 0) goto loc_true; - - if (stricmp(str, "false") == 0) goto loc_false; - if (stricmp(str, "no") == 0) goto loc_false; - if (stricmp(str, "off") == 0) goto loc_false; - //if (stricmp(str, "0") == 0) goto loc_false; - - if (is_integer(str)) { - vint = atoi64(str); - *pbool = (vint != 0) ? TRUE : FALSE; - return TRUE; - } else if (is_float(str)) { - vdouble = atof(str); - *pbool = (vdouble != 0) ? TRUE : FALSE; - return TRUE; - } - - return FALSE; - -loc_true: - *pbool = TRUE; - return TRUE; - -loc_false: - *pbool = FALSE; - return TRUE; - -} - -/*************************************************************************************/ - -BOOL APIENTRY binn_get_int32(binn *value, int *pint) { - - if (value == NULL || pint == NULL) return FALSE; - - if (type_family(value->type) == BINN_FAMILY_INT) { - return copy_int_value(value->ptr, pint, value->type, BINN_INT32); - } - - switch (value->type) { - case BINN_FLOAT: - if ((value->vfloat < INT32_MIN) || (value->vfloat > INT32_MAX)) return FALSE; - *pint = round(value->vfloat); - break; - case BINN_DOUBLE: - if ((value->vdouble < INT32_MIN) || (value->vdouble > INT32_MAX)) return FALSE; - *pint = round(value->vdouble); - break; - case BINN_STRING: - if (is_integer((char*)value->ptr)) - *pint = atoi((char*)value->ptr); - else if (is_float((char*)value->ptr)) - *pint = round(atof((char*)value->ptr)); - else - return FALSE; - break; - case BINN_BOOL: - *pint = value->vbool; - break; - default: - return FALSE; - } - - return TRUE; -} - -/*************************************************************************************/ - -BOOL APIENTRY binn_get_int64(binn *value, int64 *pint) { - - if (value == NULL || pint == NULL) return FALSE; - - if (type_family(value->type) == BINN_FAMILY_INT) { - return copy_int_value(value->ptr, pint, value->type, BINN_INT64); - } - - switch (value->type) { - case BINN_FLOAT: - if ((value->vfloat < INT64_MIN) || (value->vfloat > INT64_MAX)) return FALSE; - *pint = round(value->vfloat); - break; - case BINN_DOUBLE: - if ((value->vdouble < INT64_MIN) || (value->vdouble > INT64_MAX)) return FALSE; - *pint = round(value->vdouble); - break; - case BINN_STRING: - if (is_integer((char*)value->ptr)) - *pint = atoi64((char*)value->ptr); - else if (is_float((char*)value->ptr)) - *pint = round(atof((char*)value->ptr)); - else - return FALSE; - break; - case BINN_BOOL: - *pint = value->vbool; - break; - default: - return FALSE; - } - - return TRUE; -} - -/*************************************************************************************/ - -BOOL APIENTRY binn_get_double(binn *value, double *pfloat) { - int64 vint; - - if (value == NULL || pfloat == NULL) return FALSE; - - if (type_family(value->type) == BINN_FAMILY_INT) { - if (copy_int_value(value->ptr, &vint, value->type, BINN_INT64) == FALSE) return FALSE; - *pfloat = (double) vint; - return TRUE; - } - - switch (value->type) { - case BINN_FLOAT: - *pfloat = value->vfloat; - break; - case BINN_DOUBLE: - *pfloat = value->vdouble; - break; - case BINN_STRING: - if (is_integer((char*)value->ptr)) - *pfloat = (double) atoi64((char*)value->ptr); - else if (is_float((char*)value->ptr)) - *pfloat = atof((char*)value->ptr); - else - return FALSE; - break; - case BINN_BOOL: - *pfloat = value->vbool; - break; - default: - return FALSE; - } - - return TRUE; -} - -/*************************************************************************************/ - -BOOL APIENTRY binn_get_bool(binn *value, BOOL *pbool) { - int64 vint; - - if (value == NULL || pbool == NULL) return FALSE; - - if (type_family(value->type) == BINN_FAMILY_INT) { - if (copy_int_value(value->ptr, &vint, value->type, BINN_INT64) == FALSE) return FALSE; - *pbool = (vint != 0) ? TRUE : FALSE; - return TRUE; - } - - switch (value->type) { - case BINN_BOOL: - *pbool = value->vbool; - break; - case BINN_FLOAT: - *pbool = (value->vfloat != 0) ? TRUE : FALSE; - break; - case BINN_DOUBLE: - *pbool = (value->vdouble != 0) ? TRUE : FALSE; - break; - case BINN_STRING: - return is_bool_str((char*)value->ptr, pbool); - default: - return FALSE; - } - - return TRUE; -} - -/*************************************************************************************/ - -char * APIENTRY binn_get_str(binn *value) { - int64 vint; - char buf[128]; - - if (value == NULL) return NULL; - - if (type_family(value->type) == BINN_FAMILY_INT) { - if (copy_int_value(value->ptr, &vint, value->type, BINN_INT64) == FALSE) return NULL; - sprintf(buf, "%" INT64_FORMAT, vint); - goto loc_convert_value; - } - - switch (value->type) { - case BINN_FLOAT: - value->vdouble = value->vfloat; - case BINN_DOUBLE: - sprintf(buf, "%g", value->vdouble); - goto loc_convert_value; - case BINN_STRING: - return (char*) value->ptr; - case BINN_BOOL: - if (value->vbool) - strcpy(buf, "true"); - else - strcpy(buf, "false"); - goto loc_convert_value; - } - - return NULL; - -loc_convert_value: - - //value->vint64 = 0; - value->ptr = strdup(buf); - if (value->ptr == NULL) return NULL; - value->freefn = free; - value->type = BINN_STRING; - return (char*) value->ptr; - -} - -/*************************************************************************************/ -/*** GENERAL FUNCTIONS ***************************************************************/ -/*************************************************************************************/ - -BOOL APIENTRY binn_is_container(binn *item) { - - if (item == NULL) return FALSE; - - switch (item->type) { - case BINN_LIST: - case BINN_MAP: - case BINN_OBJECT: - return TRUE; - default: - return FALSE; - } - -} - -/*************************************************************************************/ -- cgit v1.2.3