diff --git a/czmod/czmod.c b/czmod/czmod.c deleted file mode 100644 index 2e62022..0000000 --- a/czmod/czmod.c +++ /dev/null @@ -1,425 +0,0 @@ -//===================================================================== -// -// czmod.c - c module to boost z.lua -// -// Created by skywind on 2020/03/11 -// Last Modified: 2020/03/11 16:37:01 -// -//===================================================================== -#include -#include -#include -#include -#include -#include - -#if defined(_WIN32) || defined(_WIN64) || defined(WIN32) || defined(WIN64) -#include -#elif defined(__linux) -// #include -#include -#include -#endif - -#define IB_STRING_SSO 256 - -#include "iposix.c" -#include "imembase.c" - - -//---------------------------------------------------------------------- -// INLINE -//---------------------------------------------------------------------- -#ifndef INLINE -#if defined(__GNUC__) - -#if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) -#define INLINE __inline__ __attribute__((always_inline)) -#else -#define INLINE __inline__ -#endif - -#elif (defined(_MSC_VER) || defined(__WATCOMC__)) -#define INLINE __inline -#else -#define INLINE -#endif -#endif - -#if (!defined(__cplusplus)) && (!defined(inline)) -#define inline INLINE -#endif - - -//--------------------------------------------------------------------- -// internal functions -//--------------------------------------------------------------------- -static const char *get_data_file(void); - - -//--------------------------------------------------------------------- -// get environ -//--------------------------------------------------------------------- -static ib_string* os_getenv(const char *name) -{ - char *p = getenv(name); - if (p == NULL) { - return NULL; - } - ib_string *text = ib_string_new(); - ib_string_assign(text, p); - return text; -} - - -//--------------------------------------------------------------------- -// get data file -//--------------------------------------------------------------------- -static const char *get_data_file(void) -{ - static ib_string *text = NULL; - if (text != NULL) { - return text->ptr; - } - text = os_getenv("_ZL_DATA2"); - if (text) { - return text->ptr; - } - text = os_getenv("HOME"); - if (text == NULL) { - text = os_getenv("USERPROFILE"); - } - if (text == NULL) { - return NULL; - } - ib_string_append(text, "/.zlua"); - return text->ptr; -} - - -//--------------------------------------------------------------------- -// load file content -//--------------------------------------------------------------------- -ib_string *load_content(const char *filename) -{ - FILE *fp = fopen(filename, "r"); - if (fp == NULL) { - return NULL; - } - int fd = fileno(fp); - flock(fd, LOCK_SH); - ib_string *text = ib_string_new(); - size_t block = 65536; - ib_string_resize(text, block); - size_t pos = 0; - while (feof(fp) == 0) { - size_t avail = text->size - pos; - if (avail < block) { - ib_string_resize(text, text->size + block); - avail = text->size - pos; - } - size_t hr = fread(&(text->ptr[pos]), 1, avail, fp); - pos += hr; - } - flock(fd, LOCK_UN); - fclose(fp); - ib_string_resize(text, pos); - return text; -} - - -//--------------------------------------------------------------------- -// path item -//--------------------------------------------------------------------- -typedef struct -{ - ib_string *path; - int rank; - uint32_t timestamp; - uint64_t frecence; -} PathItem; - -static void item_delete(PathItem *item) -{ - if (item) { - if (item->path) { - ib_string_delete(item->path); - item->path = NULL; - } - ikmem_free(item); - } -}; - -PathItem* item_new(const char *path, int rank, uint32_t timestamp) -{ - PathItem* item = (PathItem*)ikmem_malloc(sizeof(PathItem)); - assert(item); - item->path = ib_string_new_from(path); - item->rank = rank; - item->timestamp = timestamp; - item->frecence = 0; - return item; -}; - -ib_array* ib_array_new_items(void) -{ - return ib_array_new((void (*)(void*))item_delete); -} - - -//--------------------------------------------------------------------- -// load data -//--------------------------------------------------------------------- -ib_array* data_load(const char *filename) -{ - ib_string *content = load_content(filename); - if (content == NULL) { - return NULL; - } - else { - ib_array *lines = ib_string_split_c(content, '\n'); - int size = ib_array_size(lines); - int i; - ib_array *items = ib_array_new_items(); - for (i = 0; i < size; i++) { - ib_string *text = (ib_string*)ib_array_index(lines, i); - int p1 = ib_string_find_c(text, '|', 0); - if (p1 >= 0) { - int p2 = ib_string_find_c(text, '|', p1 + 1); - if (p2 >= 0) { - uint32_t timestamp; - int rank; - text->ptr[p1] = 0; - text->ptr[p2] = 0; - rank = (int)atoi(text->ptr + p1 + 1); - timestamp = (uint32_t)strtoul(text->ptr + p2 + 1, NULL, 10); - PathItem *ni = item_new(text->ptr, rank, timestamp); - ib_array_push(items, ni); - } - } - } - ib_array_delete(lines); - return items; - } - return NULL; -} - - -//--------------------------------------------------------------------- -// save data -//--------------------------------------------------------------------- -void data_save(const char *filename, ib_array *items) -{ - ib_string *tmpname = ib_string_new_from(filename); - FILE *fp; - while (1) { - char tmp[100]; - ib_string_assign(tmpname, filename); - sprintf(tmp, ".%u%03u%d", (uint32_t)time(NULL), - (uint32_t)(clock() % 1000), rand() % 10000); - ib_string_append(tmpname, tmp); - if (iposix_path_isdir(tmpname->ptr) < 0) break; - } - fp = fopen(tmpname->ptr, "w"); - if (fp) { - int size = ib_array_size(items); - int i; - for (i = 0; i < size; i++) { - PathItem *item = (PathItem*)ib_array_index(items, i); - fprintf(fp, "%s|%u|%u\n", - item->path->ptr, item->rank, item->timestamp); - } - fclose(fp); - #ifdef _WIN32 - ReplaceFileA(filename, tmpname->ptr, NULL, 2, NULL, NULL); - #else - rename(tmpname->ptr, filename); - #endif - } - ib_string_delete(tmpname); -} - - -//--------------------------------------------------------------------- -// save data -//--------------------------------------------------------------------- -void data_write(const char *filename, ib_array *items) -{ - FILE *fp; - int fd; - fp = fopen(filename, "w+"); - if (fp) { - int size = ib_array_size(items); - int i; - fd = fileno(fp); - flock(fd, LOCK_EX); - for (i = 0; i < size; i++) { - PathItem *item = (PathItem*)ib_array_index(items, i); - fprintf(fp, "%s|%u|%u\n", - item->path->ptr, item->rank, item->timestamp); - } - fflush(fp); - flock(fd, LOCK_UN); - fclose(fp); - } -} - - -//--------------------------------------------------------------------- -// insert data -//--------------------------------------------------------------------- -void data_add(ib_array *items, const char *path) -{ - ib_string *target = ib_string_new_from(path); - int i = 0, size, found = 0; -#if defined(_WIN32) - for (i = 0; i < target->size; i++) { - if (target->ptr[i] == '/') target->ptr[i] = '\\'; - else { - target->ptr[i] = (char)tolower(target->ptr[i]); - } - } -#endif - size = ib_array_size(items); - for (i = 0; i < size; i++) { - PathItem *item = (PathItem*)ib_array_index(items, i); - int equal = 0; - #if defined(_WIN32) - if (item->path->size == target->size) { - char *src = item->path->ptr; - char *dst = target->ptr; - int avail = target->size; - for (; avail > 0; src++, dst++, avail--) { - if (tolower(src[0]) != dst[0]) break; - } - equal = (avail == 0)? 1 : 0; - } - #else - if (ib_string_compare(item->path, target) == 0) { - equal = 1; - } - #endif - if (equal) { - found = 1; - item->rank++; - item->timestamp = (uint32_t)time(NULL); - } - } - if (!found) { - PathItem *ni = item_new(target->ptr, 1, (uint32_t)time(NULL)); - ib_array_push(items, ni); - } - ib_string_delete(target); -} - - -//--------------------------------------------------------------------- -// -//--------------------------------------------------------------------- -void z_insert(const char *newpath) -{ - static char tmpname[PATH_MAX + 10]; - static char text[PATH_MAX + 100]; - const char *data = "/home/skywind/.zlua"; - FILE *fin = fopen(data, "r"); - FILE *fout; -#if 0 - while (1) { - char tmp[100]; - sprintf(tmp, ".%u%03u%d", (uint32_t)time(NULL), - (uint32_t)(clock() % 1000), rand() % 10000); - sprintf(tmpname, "%s%s", data, tmp); - if (iposix_path_isdir(tmpname) < 0) break; - } -#else - sprintf(tmpname, "%s.1", data); -#endif - fout = fopen(tmpname, "w"); - if (fin) { - int found = 0; - while (!feof(fin)) { - uint32_t rank, ts; - text[0] = 0; - fgets(text, PATH_MAX + 100, fin); - char *p1 = strchr(text, '|'); - if (p1 == NULL) continue; - *p1++ = 0; - char *p2 = strchr(p1, '|'); - if (p2 == NULL) continue; - *p2++ = 0; - if (strcmp(text, newpath) == 0) { - found = 1; - sscanf(p1, "%u", &rank); - sscanf(p2, "%u", &ts); - rank++; - ts = (uint32_t)time(NULL); - fprintf(fout, "%s|%u|%u\n", text, rank, ts); - } - else { - fprintf(fout, "%s|%s|%s\n", text, p1, p2); - } - } - if (!found) { - fprintf(fout, "%s|1|%u\n", newpath, (uint32_t)time(NULL)); - } - fclose(fin); - } - else { - fprintf(fout, "%s|1|%u\n", newpath, (uint32_t)time(NULL)); - } - fclose(fout); - rename(tmpname, data); -} - - -//--------------------------------------------------------------------- -// add to database -//--------------------------------------------------------------------- -void z_add(const char *newpath) -{ - const char *data = get_data_file(); - ib_array *items = data_load(data); - if (items == NULL) { - items = ib_array_new_items(); - } - data_add(items, newpath); -#if 0 - data_save(data, items); -#else - data_write(data, items); -#endif - ib_array_delete(items); -} - - -//--------------------------------------------------------------------- -// main entry -//--------------------------------------------------------------------- -int main(int argc, char *argv[]) -{ - if (argc <= 1) { - int i; - printf("begin\n"); - clock_t ts = (uint64_t)clock(); - for (i = 0; i < 1000; i++) { - // z_add("/tmp"); - z_insert("/tmp"); - } - ts = clock() - ts; - ts = (ts * 1000) / CLOCKS_PER_SEC; - printf("finished: %d ms\n", (int)ts); - return 0; - } - if (strcmp(argv[1], "--add") == 0) { - if (argc >= 3) { -#if 1 - z_add(argv[2]); -#else - z_insert(argv[2]); -#endif - } - } - return 0; -} - - diff --git a/czmod/imembase.c b/czmod/imembase.c deleted file mode 100644 index f6b5b28..0000000 --- a/czmod/imembase.c +++ /dev/null @@ -1,2320 +0,0 @@ -/********************************************************************** - * - * imembase.c - basic interface of memory operation - * skywind3000 (at) gmail.com, 2006-2016 - * - **********************************************************************/ - -#include "imembase.h" - -#include -#include -#include -#include - - -#if (defined(__BORLANDC__) || defined(__WATCOMC__)) -#if defined(_WIN32) || defined(WIN32) -#pragma warn -8002 -#pragma warn -8004 -#pragma warn -8008 -#pragma warn -8012 -#pragma warn -8027 -#pragma warn -8057 -#pragma warn -8066 -#endif -#endif - - -/*====================================================================*/ -/* IALLOCATOR */ -/*====================================================================*/ -void *(*__ihook_malloc)(size_t size) = NULL; -void (*__ihook_free)(void *) = NULL; -void *(*__ihook_realloc)(void *, size_t size) = NULL; - - -void* internal_malloc(struct IALLOCATOR *allocator, size_t size) -{ - if (allocator != NULL) { - return allocator->alloc(allocator, size); - } - if (__ihook_malloc != NULL) { - return __ihook_malloc(size); - } - return malloc(size); -} - -void internal_free(struct IALLOCATOR *allocator, void *ptr) -{ - if (allocator != NULL) { - allocator->free(allocator, ptr); - return; - } - if (__ihook_free != NULL) { - __ihook_free(ptr); - return; - } - free(ptr); -} - -void* internal_realloc(struct IALLOCATOR *allocator, void *ptr, size_t size) -{ - if (allocator != NULL) { - return allocator->realloc(allocator, ptr, size); - } - if (__ihook_realloc != NULL) { - return __ihook_realloc(ptr, size); - } - return realloc(ptr, size); -} - - -/*====================================================================*/ -/* IKMEM INTERFACE */ -/*====================================================================*/ -#ifndef IKMEM_ALLOCATOR -#define IKMEM_ALLOCATOR NULL -#endif - -struct IALLOCATOR *ikmem_allocator = IKMEM_ALLOCATOR; - - -void* ikmem_malloc(size_t size) -{ - return internal_malloc(ikmem_allocator, size); -} - -void* ikmem_realloc(void *ptr, size_t size) -{ - return internal_realloc(ikmem_allocator, ptr, size); -} - -void ikmem_free(void *ptr) -{ - internal_free(ikmem_allocator, ptr); -} - - -/*====================================================================*/ -/* IVECTOR */ -/*====================================================================*/ -void iv_init(struct IVECTOR *v, struct IALLOCATOR *allocator) -{ - if (v == 0) return; - v->data = 0; - v->size = 0; - v->capacity = 0; - v->allocator = allocator; -} - -void iv_destroy(struct IVECTOR *v) -{ - if (v == NULL) return; - if (v->data) { - internal_free(v->allocator, v->data); - } - v->data = NULL; - v->size = 0; - v->capacity = 0; -} - -int iv_capacity(struct IVECTOR *v, size_t newcap) -{ - if (newcap == v->capacity) - return 0; - if (newcap == 0) { - if (v->capacity > 0) { - internal_free(v->allocator, v->data); - } - v->data = NULL; - v->capacity = 0; - v->size = 0; - } - else { - unsigned char *ptr = (unsigned char*) - internal_malloc(v->allocator, newcap); - if (ptr == NULL) { - return -1; - } - if (v->data) { - size_t minsize = (v->size <= newcap)? v->size : newcap; - if (minsize > 0 && v->data) { - memcpy(ptr, v->data, minsize); - } - internal_free(v->allocator, v->data); - } - v->data = ptr; - v->capacity = newcap; - if (v->size > v->capacity) { - v->size = v->capacity; - } - } - return 0; -} - -int iv_resize(struct IVECTOR *v, size_t newsize) -{ - if (newsize > v->capacity) { - size_t capacity = v->capacity * 2; - if (capacity < newsize) { - capacity = sizeof(char*); - while (capacity < newsize) { - capacity = capacity * 2; - } - } - if (iv_capacity(v, capacity) != 0) { - return -1; - } - } - v->size = newsize; - return 0; -} - -int iv_reserve(struct IVECTOR *v, size_t size) -{ - return iv_capacity(v, (size >= v->size)? size : v->size); -} - -int iv_push(struct IVECTOR *v, const void *data, size_t size) -{ - size_t current = v->size; - if (iv_resize(v, current + size) != 0) - return -1; - if (data != NULL) - memcpy(v->data + current, data, size); - return 0; -} - -size_t iv_pop(struct IVECTOR *v, void *data, size_t size) -{ - size_t current = v->size; - if (size >= current) size = current; - if (data != NULL) - memcpy(data, v->data + current - size, size); - iv_resize(v, current - size); - return size; -} - -int iv_insert(struct IVECTOR *v, size_t pos, const void *data, size_t size) -{ - size_t current = v->size; - if (pos > current) - return -1; - if (iv_resize(v, current + size) != 0) - return -1; - if (pos < current) { - memmove(v->data + pos + size, v->data + pos, current - pos); - } - if (data != NULL) - memcpy(v->data + pos, data, size); - return 0; -} - -int iv_erase(struct IVECTOR *v, size_t pos, size_t size) -{ - size_t current = v->size; - if (pos >= current) return 0; - if (pos + size >= current) size = current - pos; - if (size == 0) return 0; - memmove(v->data + pos, v->data + pos + size, current - pos - size); - if (iv_resize(v, current - size) != 0) - return -1; - return 0; -} - - -/*====================================================================*/ -/* IMEMNODE */ -/*====================================================================*/ -void imnode_init(struct IMEMNODE *mn, ilong nodesize, struct IALLOCATOR *ac) -{ - struct IMEMNODE *mnode = mn; - - assert(mnode != NULL); - mnode->allocator = ac; - - iv_init(&mnode->vprev, ac); - iv_init(&mnode->vnext, ac); - iv_init(&mnode->vnode, ac); - iv_init(&mnode->vdata, ac); - iv_init(&mnode->vmem, ac); - iv_init(&mnode->vmode, ac); - - nodesize = IROUND_UP(nodesize, 8); - - mnode->node_size = nodesize; - mnode->node_free = 0; - mnode->node_used = 0; - mnode->node_max = 0; - mnode->mem_max = 0; - mnode->mem_count = 0; - mnode->list_open = -1; - mnode->list_close = -1; - mnode->total_mem = 0; - mnode->grow_limit = 0; - mnode->extra = NULL; -} - -void imnode_destroy(struct IMEMNODE *mnode) -{ - ilong i; - - assert(mnode != NULL); - if (mnode->mem_count > 0) { - for (i = 0; i < mnode->mem_count && mnode->mmem; i++) { - if (mnode->mmem[i]) { - internal_free(mnode->allocator, mnode->mmem[i]); - } - mnode->mmem[i] = NULL; - } - mnode->mem_count = 0; - mnode->mem_max = 0; - iv_destroy(&mnode->vmem); - mnode->mmem = NULL; - } - - iv_destroy(&mnode->vprev); - iv_destroy(&mnode->vnext); - iv_destroy(&mnode->vnode); - iv_destroy(&mnode->vdata); - iv_destroy(&mnode->vmode); - - mnode->mprev = NULL; - mnode->mnext = NULL; - mnode->mnode = NULL; - mnode->mdata = NULL; - mnode->mmode = NULL; - - mnode->node_free = 0; - mnode->node_used = 0; - mnode->node_max = 0; - mnode->list_open = -1; - mnode->list_close= -1; - mnode->total_mem = 0; -} - -static int imnode_node_resize(struct IMEMNODE *mnode, ilong size) -{ - size_t size1, size2; - - size1 = (size_t)(size * (ilong)sizeof(ilong)); - size2 = (size_t)(size * (ilong)sizeof(void*)); - - if (iv_resize(&mnode->vprev, size1)) return -1; - if (iv_resize(&mnode->vnext, size1)) return -2; - if (iv_resize(&mnode->vnode, size1)) return -3; - if (iv_resize(&mnode->vdata, size2)) return -5; - if (iv_resize(&mnode->vmode, size1)) return -6; - - mnode->mprev = (ilong*)((void*)mnode->vprev.data); - mnode->mnext = (ilong*)((void*)mnode->vnext.data); - mnode->mnode = (ilong*)((void*)mnode->vnode.data); - mnode->mdata =(void**)((void*)mnode->vdata.data); - mnode->mmode = (ilong*)((void*)mnode->vmode.data); - mnode->node_max = size; - - return 0; -} - -static int imnode_mem_add(struct IMEMNODE*mnode, ilong node_count, void**mem) -{ - size_t newsize; - char *mptr; - - if (mnode->mem_count >= mnode->mem_max) { - newsize = (mnode->mem_max <= 0)? 16 : mnode->mem_max * 2; - if (iv_resize(&mnode->vmem, newsize * sizeof(void*))) - return -1; - mnode->mem_max = newsize; - mnode->mmem = (char**)((void*)mnode->vmem.data); - } - newsize = node_count * mnode->node_size + 16; - mptr = (char*)internal_malloc(mnode->allocator, newsize); - if (mptr == NULL) return -2; - - mnode->mmem[mnode->mem_count++] = mptr; - mnode->total_mem += newsize; - mptr = (char*)IROUND_UP(((size_t)mptr), 16); - - if (mem) *mem = mptr; - - return 0; -} - - -static long imnode_grow(struct IMEMNODE *mnode) -{ - ilong size_start = mnode->node_max; - ilong size_endup; - ilong retval, count, i, j; - void *mptr; - char *p; - - count = (mnode->node_max <= 0)? 8 : mnode->node_max; - if (mnode->grow_limit > 0) { - if (count > mnode->grow_limit) count = mnode->grow_limit; - } - if (count > 4096) count = 4096; - size_endup = size_start + count; - - retval = imnode_node_resize(mnode, size_endup); - if (retval) return -10 + (long)retval; - - retval = imnode_mem_add(mnode, count, &mptr); - - if (retval) { - imnode_node_resize(mnode, size_start); - mnode->node_max = size_start; - return -20 + (long)retval; - } - - p = (char*)mptr; - for (i = mnode->node_max - 1, j = 0; j < count; i--, j++) { - IMNODE_NODE(mnode, i) = 0; - IMNODE_MODE(mnode, i) = 0; - IMNODE_DATA(mnode, i) = p; - IMNODE_PREV(mnode, i) = -1; - IMNODE_NEXT(mnode, i) = mnode->list_open; - if (mnode->list_open >= 0) IMNODE_PREV(mnode, mnode->list_open) = i; - mnode->list_open = i; - mnode->node_free++; - p += mnode->node_size; - } - - return 0; -} - - -ilong imnode_new(struct IMEMNODE *mnode) -{ - ilong node, next; - - assert(mnode); - if (mnode->list_open < 0) { - if (imnode_grow(mnode)) return -2; - } - - if (mnode->list_open < 0 || mnode->node_free <= 0) return -3; - - node = mnode->list_open; - next = IMNODE_NEXT(mnode, node); - if (next >= 0) IMNODE_PREV(mnode, next) = -1; - mnode->list_open = next; - - IMNODE_PREV(mnode, node) = -1; - IMNODE_NEXT(mnode, node) = mnode->list_close; - - if (mnode->list_close >= 0) IMNODE_PREV(mnode, mnode->list_close) = node; - mnode->list_close = node; - IMNODE_MODE(mnode, node) = 1; - - mnode->node_free--; - mnode->node_used++; - - return node; -} - -void imnode_del(struct IMEMNODE *mnode, ilong index) -{ - ilong prev, next; - - assert(mnode); - assert((index >= 0) && (index < mnode->node_max)); - assert(IMNODE_MODE(mnode, index) != 0); - - next = IMNODE_NEXT(mnode, index); - prev = IMNODE_PREV(mnode, index); - - if (next >= 0) IMNODE_PREV(mnode, next) = prev; - if (prev >= 0) IMNODE_NEXT(mnode, prev) = next; - else mnode->list_close = next; - - IMNODE_PREV(mnode, index) = -1; - IMNODE_NEXT(mnode, index) = mnode->list_open; - - if (mnode->list_open >= 0) IMNODE_PREV(mnode, mnode->list_open) = index; - mnode->list_open = index; - - IMNODE_MODE(mnode, index) = 0; - mnode->node_free++; - mnode->node_used--; -} - -ilong imnode_head(const struct IMEMNODE *mnode) -{ - return (mnode)? mnode->list_close : -1; -} - -ilong imnode_next(const struct IMEMNODE *mnode, ilong index) -{ - return (mnode)? IMNODE_NEXT(mnode, index) : -1; -} - -ilong imnode_prev(const struct IMEMNODE *mnode, ilong index) -{ - return (mnode)? IMNODE_PREV(mnode, index) : -1; -} - -void *imnode_data(struct IMEMNODE *mnode, ilong index) -{ - return (char*)IMNODE_DATA(mnode, index); -} - -const void* imnode_data_const(const struct IMEMNODE *mnode, ilong index) -{ - return (const char*)IMNODE_DATA(mnode, index); -} - - - - -/*====================================================================*/ -/* IVECTOR / IMEMNODE MANAGEMENT */ -/*====================================================================*/ - -ib_vector *iv_create(void) -{ - ib_vector *vec; - vec = (ib_vector*)ikmem_malloc(sizeof(ib_vector)); - if (vec == NULL) return NULL; - iv_init(vec, ikmem_allocator); - return vec; -} - -void iv_delete(ib_vector *vec) -{ - assert(vec); - iv_destroy(vec); - ikmem_free(vec); -} - -ib_memnode *imnode_create(ilong nodesize, int grow_limit) -{ - ib_memnode *mnode; - mnode = (ib_memnode*)ikmem_malloc(sizeof(ib_memnode)); - if (mnode == NULL) return NULL; - imnode_init(mnode, nodesize, ikmem_allocator); - mnode->grow_limit = grow_limit; - return mnode; -} - -void imnode_delete(ib_memnode *mnode) -{ - assert(mnode); - imnode_destroy(mnode); - ikmem_free(mnode); -} - - -/*--------------------------------------------------------------------*/ -/* Collection - Array */ -/*--------------------------------------------------------------------*/ - -struct ib_array -{ - struct IVECTOR vec; - void (*fn_destroy)(void*); - size_t size; - void **items; -}; - -ib_array *ib_array_new(void (*destroy_func)(void*)) -{ - ib_array *array = (ib_array*)ikmem_malloc(sizeof(ib_array)); - if (array == NULL) return NULL; - iv_init(&array->vec, ikmem_allocator); - array->fn_destroy = destroy_func; - array->size = 0; - return array; -}; - - -void ib_array_delete(ib_array *array) -{ - if (array->fn_destroy) { - size_t n = array->size; - size_t i; - for (i = 0; i < n; i++) { - array->fn_destroy(array->items[i]); - array->items[i] = NULL; - } - } - iv_destroy(&array->vec); - array->size = 0; - array->items = NULL; - ikmem_free(array); -} - -static void ib_array_update(ib_array *array) -{ - array->items = (void**)array->vec.data; -} - -void ib_array_reserve(ib_array *array, size_t new_size) -{ - int hr = iv_obj_reserve(&array->vec, char*, new_size); - if (hr != 0) { - assert(hr == 0); - } - ib_array_update(array); -} - -size_t ib_array_size(const ib_array *array) -{ - return array->size; -} - -void** ib_array_ptr(ib_array *array) -{ - return array->items; -} - -void* ib_array_index(ib_array *array, size_t index) -{ - assert(index < array->size); - return array->items[index]; -} - -const void* ib_array_const_index(const ib_array *array, size_t index) -{ - assert(index < array->size); - return array->items[index]; -} - -void ib_array_push(ib_array *array, void *item) -{ - int hr = iv_obj_push(&array->vec, void*, &item); - if (hr) { - assert(hr == 0); - } - ib_array_update(array); - array->size++; -} - -void ib_array_push_left(ib_array *array, void *item) -{ - int hr = iv_obj_insert(&array->vec, void*, 0, &item); - if (hr) { - assert(hr == 0); - } - ib_array_update(array); - array->size++; -} - -void ib_array_replace(ib_array *array, size_t index, void *item) -{ - assert(index < array->size); - if (array->fn_destroy) { - array->fn_destroy(array->items[index]); - } - array->items[index] = item; -} - -void* ib_array_pop(ib_array *array) -{ - void *item; - int hr; - assert(array->size > 0); - array->size--; - item = array->items[array->size]; - hr = iv_obj_resize(&array->vec, void*, array->size); - ib_array_update(array); - if (hr) { - assert(hr == 0); - } - return item; -} - -void* ib_array_pop_left(ib_array *array) -{ - void *item; - int hr; - assert(array->size > 0); - array->size--; - item = array->items[0]; - hr = iv_obj_erase(&array->vec, void*, 0, 1); - ib_array_update(array); - if (hr) { - assert(hr == 0); - } - return item; -} - -void ib_array_remove(ib_array *array, size_t index) -{ - assert(index < array->size); - if (array->fn_destroy) { - array->fn_destroy(array->items[index]); - } - iv_obj_erase(&array->vec, void*, index, 1); - ib_array_update(array); - array->size--; -} - -void ib_array_insert_before(ib_array *array, size_t index, void *item) -{ - int hr = iv_obj_insert(&array->vec, void*, index, &item); - if (hr) { - assert(hr == 0); - } - ib_array_update(array); - array->size++; -} - -void* ib_array_pop_at(ib_array *array, size_t index) -{ - void *item; - int hr; - assert(array->size > 0); - item = array->items[index]; - hr = iv_obj_erase(&array->vec, void*, index, 1); - if (hr) { - assert(hr == 0); - } - return item; -} - -void ib_array_sort(ib_array *array, - int (*compare)(const void*, const void*)) -{ - if (array->size) { - void **items = array->items; - size_t size = array->size; - size_t i, j; - for (i = 0; i < size - 1; i++) { - for (j = i + 1; j < size; j++) { - if (compare(items[i], items[j]) > 0) { - void *tmp = items[i]; - items[i] = items[j]; - items[j] = tmp; - } - } - } - } -} - -void ib_array_for_each(ib_array *array, void (*iterator)(void *item)) -{ - if (iterator) { - void **items = array->items; - size_t count = array->size; - for (; count > 0; count--, items++) { - iterator(items[0]); - } - } -} - -ilong ib_array_search(const ib_array *array, - int (*compare)(const void*, const void*), - const void *item, - ilong start_pos) -{ - ilong size = (ilong)array->size; - void **items = array->items; - if (start_pos < 0) { - start_pos = 0; - } - for (items = items + start_pos; start_pos < size; start_pos++) { - if (compare(items[0], item) == 0) { - return start_pos; - } - items++; - } - return -1; -} - -ilong ib_array_bsearch(const ib_array *array, - int (*compare)(const void*, const void*), - const void *item) -{ - ilong top, bottom, mid; - void **items = array->items; - if (array->size == 0) return -1; - top = 0; - bottom = (ilong)array->size - 1; - while (1) { - int hr; - mid = (top + bottom) >> 1; - hr = compare(item, items[mid]); - if (hr < 0) bottom = mid; - else if (hr > 0) top = mid; - else return mid; - if (top == bottom) break; - } - return -1; -} - - - -/*====================================================================*/ -/* Binary Search Tree */ -/*====================================================================*/ - -struct ib_node *ib_node_first(struct ib_root *root) -{ - struct ib_node *node = root->node; - if (node == NULL) return NULL; - while (node->left) - node = node->left; - return node; -} - -struct ib_node *ib_node_last(struct ib_root *root) -{ - struct ib_node *node = root->node; - if (node == NULL) return NULL; - while (node->right) - node = node->right; - return node; -} - -struct ib_node *ib_node_next(struct ib_node *node) -{ - if (node == NULL) return NULL; - if (node->right) { - node = node->right; - while (node->left) - node = node->left; - } - else { - while (1) { - struct ib_node *last = node; - node = node->parent; - if (node == NULL) break; - if (node->left == last) break; - } - } - return node; -} - -struct ib_node *ib_node_prev(struct ib_node *node) -{ - if (node == NULL) return NULL; - if (node->left) { - node = node->left; - while (node->right) - node = node->right; - } - else { - while (1) { - struct ib_node *last = node; - node = node->parent; - if (node == NULL) break; - if (node->right == last) break; - } - } - return node; -} - -static inline void -_ib_child_replace(struct ib_node *oldnode, struct ib_node *newnode, - struct ib_node *parent, struct ib_root *root) -{ - if (parent) { - if (parent->left == oldnode) - parent->left = newnode; - else - parent->right = newnode; - } else { - root->node = newnode; - } -} - -static inline struct ib_node * -_ib_node_rotate_left(struct ib_node *node, struct ib_root *root) -{ - struct ib_node *right = node->right; - struct ib_node *parent = node->parent; - node->right = right->left; - ASSERTION(node && right); - if (right->left) - right->left->parent = node; - right->left = node; - right->parent = parent; - _ib_child_replace(node, right, parent, root); - node->parent = right; - return right; -} - -static inline struct ib_node * -_ib_node_rotate_right(struct ib_node *node, struct ib_root *root) -{ - struct ib_node *left = node->left; - struct ib_node *parent = node->parent; - node->left = left->right; - ASSERTION(node && left); - if (left->right) - left->right->parent = node; - left->right = node; - left->parent = parent; - _ib_child_replace(node, left, parent, root); - node->parent = left; - return left; -} - -void ib_node_replace(struct ib_node *victim, struct ib_node *newnode, - struct ib_root *root) -{ - struct ib_node *parent = victim->parent; - _ib_child_replace(victim, newnode, parent, root); - if (victim->left) victim->left->parent = newnode; - if (victim->right) victim->right->parent = newnode; - newnode->left = victim->left; - newnode->right = victim->right; - newnode->parent = victim->parent; - newnode->height = victim->height; -} - - -/*--------------------------------------------------------------------*/ -/* avl - node manipulation */ -/*--------------------------------------------------------------------*/ - -static inline int IB_MAX(int x, int y) -{ -#if 1 - return (x < y)? y : x; /* this is faster with cmov on x86 */ -#else - return x - ((x - y) & ((x - y) >> (sizeof(int) * 8 - 1))); -#endif -} - -static inline void -_ib_node_height_update(struct ib_node *node) -{ - int h0 = IB_LEFT_HEIGHT(node); - int h1 = IB_RIGHT_HEIGHT(node); - node->height = IB_MAX(h0, h1) + 1; -} - -static inline struct ib_node * -_ib_node_fix_l(struct ib_node *node, struct ib_root *root) -{ - struct ib_node *right = node->right; - int rh0, rh1; - ASSERTION(right); - rh0 = IB_LEFT_HEIGHT(right); - rh1 = IB_RIGHT_HEIGHT(right); - if (rh0 > rh1) { - right = _ib_node_rotate_right(right, root); - _ib_node_height_update(right->right); - _ib_node_height_update(right); - /* _ib_node_height_update(node); */ - } - node = _ib_node_rotate_left(node, root); - _ib_node_height_update(node->left); - _ib_node_height_update(node); - return node; -} - -static inline struct ib_node * -_ib_node_fix_r(struct ib_node *node, struct ib_root *root) -{ - struct ib_node *left = node->left; - int rh0, rh1; - ASSERTION(left); - rh0 = IB_LEFT_HEIGHT(left); - rh1 = IB_RIGHT_HEIGHT(left); - if (rh0 < rh1) { - left = _ib_node_rotate_left(left, root); - _ib_node_height_update(left->left); - _ib_node_height_update(left); - /* _ib_node_height_update(node); */ - } - node = _ib_node_rotate_right(node, root); - _ib_node_height_update(node->right); - _ib_node_height_update(node); - return node; -} - -static inline void -_ib_node_rebalance(struct ib_node *node, struct ib_root *root) -{ - while (node) { - int h0 = (int)IB_LEFT_HEIGHT(node); - int h1 = (int)IB_RIGHT_HEIGHT(node); - int diff = h0 - h1; - int height = IB_MAX(h0, h1) + 1; - if (node->height != height) { - node->height = height; - } - else if (diff >= -1 && diff <= 1) { - break; - } - if (diff <= -2) { - node = _ib_node_fix_l(node, root); - } - else if (diff >= 2) { - node = _ib_node_fix_r(node, root); - } - node = node->parent; - } -} - -void ib_node_post_insert(struct ib_node *node, struct ib_root *root) -{ - node->height = 1; - - for (node = node->parent; node; node = node->parent) { - int h0 = (int)IB_LEFT_HEIGHT(node); - int h1 = (int)IB_RIGHT_HEIGHT(node); - int height = IB_MAX(h0, h1) + 1; - int diff = h0 - h1; - if (node->height == height) break; - node->height = height; - if (diff <= -2) { - node = _ib_node_fix_l(node, root); - } - else if (diff >= 2) { - node = _ib_node_fix_r(node, root); - } - } -} - -void ib_node_erase(struct ib_node *node, struct ib_root *root) -{ - struct ib_node *child, *parent; - ASSERTION(node); - if (node->left && node->right) { - struct ib_node *old = node; - struct ib_node *left; - node = node->right; - while ((left = node->left) != NULL) - node = left; - child = node->right; - parent = node->parent; - if (child) { - child->parent = parent; - } - _ib_child_replace(node, child, parent, root); - if (node->parent == old) - parent = node; - node->left = old->left; - node->right = old->right; - node->parent = old->parent; - node->height = old->height; - _ib_child_replace(old, node, old->parent, root); - ASSERTION(old->left); - old->left->parent = node; - if (old->right) { - old->right->parent = node; - } - } - else { - if (node->left == NULL) - child = node->right; - else - child = node->left; - parent = node->parent; - _ib_child_replace(node, child, parent, root); - if (child) { - child->parent = parent; - } - } - if (parent) { - _ib_node_rebalance(parent, root); - } -} - - -/* avl nodes destroy: fast tear down the whole tree */ -struct ib_node* ib_node_tear(struct ib_root *root, struct ib_node **next) -{ - struct ib_node *node = *next; - struct ib_node *parent; - if (node == NULL) { - if (root->node == NULL) - return NULL; - node = root->node; - } - /* sink down to the leaf */ - while (1) { - if (node->left) node = node->left; - else if (node->right) node = node->right; - else break; - } - /* tear down one leaf */ - parent = node->parent; - if (parent == NULL) { - *next = NULL; - root->node = NULL; - return node; - } - if (parent->left == node) { - parent->left = NULL; - } else { - parent->right = NULL; - } - node->height = 0; - *next = parent; - return node; -} - - - -/*--------------------------------------------------------------------*/ -/* avltree - friendly interface */ -/*--------------------------------------------------------------------*/ - -void ib_tree_init(struct ib_tree *tree, - int (*compare)(const void*, const void*), size_t size, size_t offset) -{ - tree->root.node = NULL; - tree->offset = offset; - tree->size = size; - tree->count = 0; - tree->compare = compare; -} - - -void *ib_tree_first(struct ib_tree *tree) -{ - struct ib_node *node = ib_node_first(&tree->root); - if (!node) return NULL; - return IB_NODE2DATA(node, tree->offset); -} - -void *ib_tree_last(struct ib_tree *tree) -{ - struct ib_node *node = ib_node_last(&tree->root); - if (!node) return NULL; - return IB_NODE2DATA(node, tree->offset); -} - -void *ib_tree_next(struct ib_tree *tree, void *data) -{ - struct ib_node *nn; - if (!data) return NULL; - nn = IB_DATA2NODE(data, tree->offset); - nn = ib_node_next(nn); - if (!nn) return NULL; - return IB_NODE2DATA(nn, tree->offset); -} - -void *ib_tree_prev(struct ib_tree *tree, void *data) -{ - struct ib_node *nn; - if (!data) return NULL; - nn = IB_DATA2NODE(data, tree->offset); - nn = ib_node_prev(nn); - if (!nn) return NULL; - return IB_NODE2DATA(nn, tree->offset); -} - - -/* require a temporary user structure (data) which contains the key */ -void *ib_tree_find(struct ib_tree *tree, const void *data) -{ - struct ib_node *n = tree->root.node; - int (*compare)(const void*, const void*) = tree->compare; - int offset = (int)(tree->offset); - while (n) { - void *nd = IB_NODE2DATA(n, offset); - int hr = compare(data, nd); - if (hr == 0) { - return nd; - } - else if (hr < 0) { - n = n->left; - } - else { - n = n->right; - } - } - return NULL; -} - -void *ib_tree_nearest(struct ib_tree *tree, const void *data) -{ - struct ib_node *n = tree->root.node; - struct ib_node *p = NULL; - int (*compare)(const void*, const void*) = tree->compare; - int offset = (int)(tree->offset); - while (n) { - void *nd = IB_NODE2DATA(n, offset); - int hr = compare(data, nd); - p = n; - if (n == 0) return nd; - else if (hr < 0) { - n = n->left; - } - else { - n = n->right; - } - } - return (p)? IB_NODE2DATA(p, offset) : NULL; -} - - -/* returns NULL for success, otherwise returns conflict node with same key */ -void *ib_tree_add(struct ib_tree *tree, void *data) -{ - struct ib_node **link = &tree->root.node; - struct ib_node *parent = NULL; - struct ib_node *node = IB_DATA2NODE(data, tree->offset); - int (*compare)(const void*, const void*) = tree->compare; - int offset = (int)(tree->offset); - while (link[0]) { - void *pd; - int hr; - parent = link[0]; - pd = IB_NODE2DATA(parent, offset); - hr = compare(data, pd); - if (hr == 0) { - return pd; - } - else if (hr < 0) { - link = &(parent->left); - } - else { - link = &(parent->right); - } - } - ib_node_link(node, parent, link); - ib_node_post_insert(node, &tree->root); - tree->count++; - return NULL; -} - - -void ib_tree_remove(struct ib_tree *tree, void *data) -{ - struct ib_node *node = IB_DATA2NODE(data, tree->offset); - if (!ib_node_empty(node)) { - ib_node_erase(node, &tree->root); - node->parent = node; - tree->count--; - } -} - - -void ib_tree_replace(struct ib_tree *tree, void *victim, void *newdata) -{ - struct ib_node *vicnode = IB_DATA2NODE(victim, tree->offset); - struct ib_node *newnode = IB_DATA2NODE(newdata, tree->offset); - ib_node_replace(vicnode, newnode, &tree->root); - vicnode->parent = vicnode; -} - - -void ib_tree_clear(struct ib_tree *tree, void (*destroy)(void *data)) -{ - while (1) { - void *data; - if (tree->root.node == NULL) break; - data = IB_NODE2DATA(tree->root.node, tree->offset); - ib_tree_remove(tree, data); - if (destroy) destroy(data); - } -} - - -/*--------------------------------------------------------------------*/ -/* fastbin - fixed size object allocator */ -/*--------------------------------------------------------------------*/ - -void ib_fastbin_init(struct ib_fastbin *fb, size_t obj_size) -{ - const size_t align = sizeof(void*); - size_t need; - fb->start = NULL; - fb->endup = NULL; - fb->next = NULL; - fb->pages = NULL; - fb->obj_size = (obj_size + align - 1) & (~(align - 1)); - need = fb->obj_size * 32 + sizeof(void*) + 16; - fb->page_size = (align <= 2)? 8 : 32; - while (fb->page_size < need) { - fb->page_size *= 2; - } - fb->maximum = (align <= 2)? fb->page_size : 0x10000; -} - -void ib_fastbin_destroy(struct ib_fastbin *fb) -{ - while (fb->pages) { - void *page = fb->pages; - void *next = IB_NEXT(page); - fb->pages = next; - ikmem_free(page); - } - fb->start = NULL; - fb->endup = NULL; - fb->next = NULL; - fb->pages = NULL; -} - -void* ib_fastbin_new(struct ib_fastbin *fb) -{ - size_t obj_size = fb->obj_size; - void *obj; - obj = fb->next; - if (obj) { - fb->next = IB_NEXT(fb->next); - return obj; - } - if (fb->start + obj_size > fb->endup) { - char *page = (char*)ikmem_malloc(fb->page_size); - size_t lineptr = (size_t)page; - ASSERTION(page); - IB_NEXT(page) = fb->pages; - fb->pages = page; - lineptr = (lineptr + sizeof(void*) + 15) & (~15); - fb->start = (char*)lineptr; - fb->endup = (char*)page + fb->page_size; - if (fb->page_size < fb->maximum) { - fb->page_size *= 2; - } - } - obj = fb->start; - fb->start += obj_size; - ASSERTION(fb->start <= fb->endup); - return obj; -} - -void ib_fastbin_del(struct ib_fastbin *fb, void *ptr) -{ - IB_NEXT(ptr) = fb->next; - fb->next = ptr; -} - - -/*--------------------------------------------------------------------*/ -/* string */ -/*--------------------------------------------------------------------*/ - -ib_string* ib_string_new(void) -{ - struct ib_string* str = (ib_string*)ikmem_malloc(sizeof(ib_string)); - assert(str); - str->ptr = str->sso; - str->size = 0; - str->capacity = IB_STRING_SSO; - str->ptr[0] = 0; - return str; -} - - -void ib_string_delete(ib_string *str) -{ - assert(str); - if (str) { - if (str->ptr && str->ptr != str->sso) - ikmem_free(str->ptr); - str->ptr = NULL; - str->size = str->capacity = 0; - } - ikmem_free(str); -} - -ib_string* ib_string_new_size(const char *text, int size) -{ - struct ib_string *str = ib_string_new(); - size = (size > 0)? size : 0; - if (size > 0 && text) { - ib_string_resize(str, size); - memcpy(str->ptr, text, size); - } - return str; -} - -ib_string* ib_string_new_from(const char *text) -{ - return ib_string_new_size(text, (text)? ((int)strlen(text)) : 0); -} - -static void _ib_string_set_capacity(ib_string *str, int capacity) -{ - assert(str); - assert(capacity >= 0); - if (capacity <= IB_STRING_SSO) { - capacity = IB_STRING_SSO; - if (str->ptr != str->sso) { - if (str->size > 0) { - int csize = (str->size < capacity) ? str->size : capacity; - memcpy(str->sso, str->ptr, csize); - } - ikmem_free(str->ptr); - str->ptr = str->sso; - str->capacity = IB_STRING_SSO; - } - } - else { - char *ptr = (char*)ikmem_malloc(capacity + 2); - int csize = (capacity < str->size) ? capacity : str->size; - assert(ptr); - if (csize > 0) { - memcpy(ptr, str->ptr, csize); - } - if (str->ptr != str->sso) - ikmem_free(str->ptr); - str->ptr = ptr; - str->capacity = capacity; - } - if (str->size > str->capacity) - str->size = str->capacity; - str->ptr[str->size] = 0; -} - -ib_string* ib_string_resize(ib_string *str, int newsize) -{ - assert(str && newsize >= 0); - if (newsize > str->capacity) { - int capacity = str->capacity * 2; - if (capacity < newsize) { - while (capacity < newsize) { - capacity = capacity * 2; - } - } - _ib_string_set_capacity(str, capacity); - } - str->size = newsize; - str->ptr[str->size] = 0; - return str; -} - -ib_string* ib_string_reserve(ib_string *str, int newsize) -{ - int size = (newsize >= str->size)? newsize : str->size; - _ib_string_set_capacity(str, size); - return str; -} - -ib_string* ib_string_insert(ib_string *str, int pos, - const void *data, int size) -{ - int current = str->size; - if (pos < 0 || pos > str->size) - return NULL; - ib_string_resize(str, str->size + size); - if (pos < current) { - memmove(str->ptr + pos + size, str->ptr + pos, current - pos); - } - if (data) { - memcpy(str->ptr + pos, data, size); - } - return str; -} - -ib_string* ib_string_insert_c(ib_string *str, int pos, char c) -{ - int current = str->size; - if (pos < 0 || pos > str->size) - return NULL; - ib_string_resize(str, str->size + 1); - if (pos < current) { - memmove(str->ptr + pos + 1, str->ptr + pos, current - pos); - } - str->ptr[pos] = c; - return str; -} - -ib_string* ib_string_erase(ib_string *str, int pos, int size) -{ - int current = str->size; - if (pos >= current) return 0; - if (pos + size >= current) size = current - pos; - if (size == 0) return 0; - memmove(str->ptr + pos, str->ptr + pos + size, current - pos - size); - return ib_string_resize(str, current - size); -} - -int ib_string_compare(const struct ib_string *a, const struct ib_string *b) -{ - int minsize = (a->size < b->size)? a->size : b->size; - int hr = memcmp(a->ptr, b->ptr, minsize); - if (hr < 0) return -1; - else if (hr > 0) return 1; - if (a->size < b->size) return -1; - else if (a->size > b->size) return 1; - return 0; -} - - -ib_string* ib_string_assign(ib_string *str, const char *src) -{ - return ib_string_assign_size(str, src, (int)strlen(src)); -} - -ib_string* ib_string_assign_size(ib_string *str, const char *src, int size) -{ - assert(size >= 0); - ib_string_resize(str, size); - if (src) { - memcpy(str->ptr, src, size); - } - return str; -} - - -ib_string* ib_string_append(ib_string *str, const char *src) -{ - return ib_string_append_size(str, src, (int)strlen(src)); -} - - -ib_string* ib_string_append_size(ib_string *str, const char *src, int size) -{ - return ib_string_insert(str, str->size, src, size); -} - -ib_string* ib_string_append_c(ib_string *str, char c) -{ - ib_string_resize(str, str->size + 1); - str->ptr[str->size - 1] = c; - return str; -} - -ib_string* ib_string_prepend(ib_string *str, const char *src) -{ - return ib_string_prepend_size(str, src, (int)strlen(src)); -} - -ib_string* ib_string_prepend_size(ib_string *str, const char *src, int size) -{ - return ib_string_insert(str, 0, src, size); -} - -ib_string* ib_string_prepend_c(ib_string *str, char c) -{ - int current = str->size; - ib_string_resize(str, current + 1); - if (current > 0) { - memmove(str->ptr + 1, str->ptr, current); - } - str->ptr[0] = c; - return str; -} - -ib_string* ib_string_rewrite(ib_string *str, int pos, const char *src) -{ - return ib_string_rewrite_size(str, pos, src, (int)strlen(src)); -} - -ib_string* ib_string_rewrite_size(ib_string *str, int pos, - const char *src, int size) -{ - if (pos < 0) size += pos, pos = 0; - if (pos + size >= str->size) size = str->size - pos; - if (size <= 0) return str; - if (src) { - memcpy(str->ptr + pos, src, size); - } - return str; -} - - -int ib_string_find(const ib_string *str, const char *src, int len, int start) -{ - char *text = str->ptr; - int pos = (start < 0)? 0 : start; - int length = (len >= 0)? len : ((int)strlen(src)); - int endup = str->size - length; - char ch; - if (length <= 0) return pos; - for (ch = src[0]; pos <= endup; pos++) { - if (text[pos] == ch) { - if (memcmp(text + pos, src, length) == 0) - return pos; - } - } - return -1; -} - -int ib_string_find_c(const ib_string *str, char ch, int start) -{ - const char *text = str->ptr; - int pos = (start < 0)? 0 : start; - int endup = str->size; - for (; pos < endup; pos++) { - if (text[pos] == ch) return pos; - } - return -1; -} - -ib_array* ib_string_split(const ib_string *str, const char *sep, int len) -{ - if (len == 0) { - return NULL; - } - else { - ib_array *array = ib_array_new((void (*)(void*))ib_string_delete); - int start = 0; - len = (len >= 0)? len : ((int)strlen(sep)); - while (1) { - int pos = ib_string_find(str, sep, len, start); - if (pos < 0) { - ib_string *newstr = ib_string_new(); - ib_string_assign_size(newstr, str->ptr + start, - str->size - start); - ib_array_push(array, newstr); - break; - } - else { - ib_string* newstr = ib_string_new(); - ib_string_assign_size(newstr, str->ptr + start, pos - start); - start = pos + len; - ib_array_push(array, newstr); - } - } - return array; - } -} - -ib_array* ib_string_split_c(const ib_string *str, char sep) -{ - if (str == NULL) { - return NULL; - } - else { - ib_array *array = ib_array_new((void (*)(void*))ib_string_delete); - int start = 0; - while (1) { - int pos = ib_string_find_c(str, sep, start); - if (pos < 0) { - ib_string *newstr = ib_string_new(); - ib_string_assign_size(newstr, str->ptr + start, - str->size - start); - ib_array_push(array, newstr); - break; - } - else { - ib_string *newstr = ib_string_new(); - ib_string_assign_size(newstr, str->ptr + start, pos - start); - start = pos + 1; - ib_array_push(array, newstr); - } - } - return array; - } -} - -ib_string* ib_string_strip(ib_string *str, const char *seps) -{ - const char *ptr = str->ptr; - const char *endup = str->ptr + str->size; - int off, pos; - for (; ptr < endup; ptr++) { - const char *sep = seps; - int match = 0; - for (; sep[0]; sep++) { - if (ptr[0] == sep[0]) { - match = 1; - break; - } - } - if (match == 0) break; - } - off = (int)(ptr - str->ptr); - if (off > 0) { - ib_string_erase(str, 0, off); - } - ptr = str->ptr; - pos = str->size; - for (; pos > 0; pos--) { - const char *sep = seps; - int match = 0; - for (; sep[0]; sep++) { - if (ptr[pos - 1] == sep[0]) { - match = 1; - break; - } - } - if (match == 0) break; - } - ib_string_resize(str, pos); - return str; -} - -ib_string* ib_string_replace_size(ib_string *str, int pos, int size, - const char *src, int len) -{ - ib_string_erase(str, pos, size); - ib_string_insert(str, pos, src, len); - return str; -} - - -/*--------------------------------------------------------------------*/ -/* static hash table (closed hash table with avlnode) */ -/*--------------------------------------------------------------------*/ - - -void ib_hash_init(struct ib_hash_table *ht, - size_t (*hash)(const void *key), - int (*compare)(const void *key1, const void *key2)) -{ - size_t i; - ht->count = 0; - ht->index_size = IB_HASH_INIT_SIZE; - ht->index_mask = ht->index_size - 1; - ht->hash = hash; - ht->compare = compare; - ilist_init(&ht->head); - ht->index = ht->init; - for (i = 0; i < IB_HASH_INIT_SIZE; i++) { - ht->index[i].avlroot.node = NULL; - ilist_init(&(ht->index[i].node)); - } -} - -struct ib_hash_node* ib_hash_node_first(struct ib_hash_table *ht) -{ - struct ILISTHEAD *head = ht->head.next; - if (head != &ht->head) { - struct ib_hash_index *index = - ilist_entry(head, struct ib_hash_index, node); - struct ib_node *avlnode = ib_node_first(&index->avlroot); - if (avlnode == NULL) return NULL; - return IB_ENTRY(avlnode, struct ib_hash_node, avlnode); - } - return NULL; -} - -struct ib_hash_node* ib_hash_node_last(struct ib_hash_table *ht) -{ - struct ILISTHEAD *head = ht->head.prev; - if (head != &ht->head) { - struct ib_hash_index *index = - ilist_entry(head, struct ib_hash_index, node); - struct ib_node *avlnode = ib_node_last(&index->avlroot); - if (avlnode == NULL) return NULL; - return IB_ENTRY(avlnode, struct ib_hash_node, avlnode); - } - return NULL; -} - -struct ib_hash_node* ib_hash_node_next(struct ib_hash_table *ht, - struct ib_hash_node *node) -{ - struct ib_node *avlnode; - struct ib_hash_index *index; - struct ILISTHEAD *listnode; - if (node == NULL) return NULL; - avlnode = ib_node_next(&node->avlnode); - if (avlnode) { - return IB_ENTRY(avlnode, struct ib_hash_node, avlnode); - } - index = &(ht->index[node->hash & ht->index_mask]); - listnode = index->node.next; - if (listnode == &(ht->head)) { - return NULL; - } - index = ilist_entry(listnode, struct ib_hash_index, node); - avlnode = ib_node_first(&index->avlroot); - if (avlnode == NULL) return NULL; - return IB_ENTRY(avlnode, struct ib_hash_node, avlnode); -} - -struct ib_hash_node* ib_hash_node_prev(struct ib_hash_table *ht, - struct ib_hash_node *node) -{ - struct ib_node *avlnode; - struct ib_hash_index *index; - struct ILISTHEAD *listnode; - if (node == NULL) return NULL; - avlnode = ib_node_prev(&node->avlnode); - if (avlnode) { - return IB_ENTRY(avlnode, struct ib_hash_node, avlnode); - } - index = &(ht->index[node->hash & ht->index_mask]); - listnode = index->node.prev; - if (listnode == &(ht->head)) { - return NULL; - } - index = ilist_entry(listnode, struct ib_hash_index, node); - avlnode = ib_node_last(&index->avlroot); - if (avlnode == NULL) return NULL; - return IB_ENTRY(avlnode, struct ib_hash_node, avlnode); -} - -struct ib_hash_node* ib_hash_find(struct ib_hash_table *ht, - const struct ib_hash_node *node) -{ - size_t hash = node->hash; - const void *key = node->key; - struct ib_hash_index *index = &(ht->index[hash & ht->index_mask]); - struct ib_node *avlnode = index->avlroot.node; - int (*compare)(const void *, const void *) = ht->compare; - while (avlnode) { - struct ib_hash_node *snode = - IB_ENTRY(avlnode, struct ib_hash_node, avlnode); - size_t shash = snode->hash; - if (hash == shash) { - int hc = compare(key, snode->key); - if (hc == 0) return snode; - avlnode = (hc < 0)? avlnode->left : avlnode->right; - } - else { - avlnode = (hash < shash)? avlnode->left : avlnode->right; - } - } - return NULL; -} - -void ib_hash_erase(struct ib_hash_table *ht, struct ib_hash_node *node) -{ - struct ib_hash_index *index; - ASSERTION(node && ht); - ASSERTION(!ib_node_empty(&node->avlnode)); - index = &ht->index[node->hash & ht->index_mask]; - if (index->avlroot.node == &node->avlnode && node->avlnode.height == 1) { - index->avlroot.node = NULL; - ilist_del_init(&index->node); - } - else { - ib_node_erase(&node->avlnode, &index->avlroot); - } - ib_node_init(&node->avlnode); - ht->count--; -} - -struct ib_node** ib_hash_track(struct ib_hash_table *ht, - const struct ib_hash_node *node, struct ib_node **parent) -{ - size_t hash = node->hash; - const void *key = node->key; - struct ib_hash_index *index = &(ht->index[hash & ht->index_mask]); - struct ib_node **link = &index->avlroot.node; - struct ib_node *p = NULL; - int (*compare)(const void *key1, const void *key2) = ht->compare; - parent[0] = NULL; - while (link[0]) { - struct ib_hash_node *snode; - size_t shash; - p = link[0]; - snode = IB_ENTRY(p, struct ib_hash_node, avlnode); - shash = snode->hash; - if (hash == shash) { - int hc = compare(key, snode->key); - if (hc == 0) { - parent[0] = p; - return NULL; - } - link = (hc < 0)? (&p->left) : (&p->right); - } - else { - link = (hash < shash)? (&p->left) : (&p->right); - } - } - parent[0] = p; - return link; -} - - -struct ib_hash_node* ib_hash_add(struct ib_hash_table *ht, - struct ib_hash_node *node) -{ - struct ib_hash_index *index = &(ht->index[node->hash & ht->index_mask]); - if (index->avlroot.node == NULL) { - index->avlroot.node = &node->avlnode; - node->avlnode.parent = NULL; - node->avlnode.left = NULL; - node->avlnode.right = NULL; - node->avlnode.height = 1; - ilist_add_tail(&index->node, &ht->head); - } - else { - struct ib_node **link, *parent; - link = ib_hash_track(ht, node, &parent); - if (link == NULL) { - ASSERTION(parent); - return IB_ENTRY(parent, struct ib_hash_node, avlnode); - } - ib_node_link(&node->avlnode, parent, link); - ib_node_post_insert(&node->avlnode, &index->avlroot); - } - ht->count++; - return NULL; -} - - -void ib_hash_replace(struct ib_hash_table *ht, - struct ib_hash_node *victim, struct ib_hash_node *newnode) -{ - struct ib_hash_index *index = &ht->index[victim->hash & ht->index_mask]; - ib_node_replace(&victim->avlnode, &newnode->avlnode, &index->avlroot); -} - -void ib_hash_clear(struct ib_hash_table *ht, - void (*destroy)(struct ib_hash_node *node)) -{ - while (!ilist_is_empty(&ht->head)) { - struct ib_hash_index *index = ilist_entry(ht->head.next, - struct ib_hash_index, node); - struct ib_node *next = NULL; - while (index->avlroot.node != NULL) { - struct ib_node *avlnode = ib_node_tear(&index->avlroot, &next); - ASSERTION(avlnode); - if (destroy) { - struct ib_hash_node *node = - IB_ENTRY(avlnode, struct ib_hash_node, avlnode); - destroy(node); - } - } - ilist_del_init(&index->node); - } - ht->count = 0; -} - - -void* ib_hash_swap(struct ib_hash_table *ht, void *ptr, size_t nbytes) -{ - struct ib_hash_index *old_index = ht->index; - struct ib_hash_index *new_index = (struct ib_hash_index*)ptr; - size_t index_size = 1; - struct ILISTHEAD head; - size_t i; - ASSERTION(nbytes >= sizeof(struct ib_hash_index)); - if (new_index == NULL) { - if (ht->index == ht->init) { - return NULL; - } - new_index = ht->init; - index_size = IB_HASH_INIT_SIZE; - } - else if (new_index == old_index) { - return old_index; - } - if (new_index != ht->init) { - size_t test_size = sizeof(struct ib_hash_index); - while (test_size < nbytes) { - size_t next_size = test_size * 2; - if (next_size > nbytes) break; - test_size = next_size; - index_size = index_size * 2; - } - } - ht->index = new_index; - ht->index_size = index_size; - ht->index_mask = index_size - 1; - ht->count = 0; - for (i = 0; i < index_size; i++) { - ht->index[i].avlroot.node = NULL; - ilist_init(&ht->index[i].node); - } - ilist_replace(&ht->head, &head); - ilist_init(&ht->head); - while (!ilist_is_empty(&head)) { - struct ib_hash_index *index = ilist_entry(head.next, - struct ib_hash_index, node); - #if 1 - struct ib_node *next = NULL; - while (index->avlroot.node) { - struct ib_node *avlnode = ib_node_tear(&index->avlroot, &next); - struct ib_hash_node *snode, *hr; - ASSERTION(avlnode); - snode = IB_ENTRY(avlnode, struct ib_hash_node, avlnode); - hr = ib_hash_add(ht, snode); - if (hr != NULL) { - ASSERTION(hr == NULL); - return NULL; - } - } - #else - while (index->avlroot.node) { - struct ib_node *avlnode = index->avlroot.node; - struct ib_hash_node *snode, *hr; - ib_node_erase(avlnode, &index->avlroot); - snode = IB_ENTRY(avlnode, struct ib_hash_node, avlnode); - hr = ib_hash_add(ht, snode); - ASSERTION(hr == NULL); - hr = hr; - } - #endif - ilist_del_init(&index->node); - } - return (old_index == ht->init)? NULL : old_index; -} - - -/*--------------------------------------------------------------------*/ -/* hash map, wrapper of ib_hash_table to support direct key/value */ -/*--------------------------------------------------------------------*/ - -struct ib_hash_entry* ib_map_first(struct ib_hash_map *hm) -{ - struct ib_hash_node *node = ib_hash_node_first(&hm->ht); - if (node == NULL) return NULL; - return IB_ENTRY(node, struct ib_hash_entry, node); -} - - -struct ib_hash_entry* ib_map_last(struct ib_hash_map *hm) -{ - struct ib_hash_node *node = ib_hash_node_last(&hm->ht); - if (node == NULL) return NULL; - return IB_ENTRY(node, struct ib_hash_entry, node); -} - - -struct ib_hash_entry* ib_map_next(struct ib_hash_map *hm, - struct ib_hash_entry *n) -{ - struct ib_hash_node *node = ib_hash_node_next(&hm->ht, &n->node); - if (node == NULL) return NULL; - return IB_ENTRY(node, struct ib_hash_entry, node); -} - - -struct ib_hash_entry* ib_map_prev(struct ib_hash_map *hm, - struct ib_hash_entry *n) -{ - struct ib_hash_node *node = ib_hash_node_prev(&hm->ht, &n->node); - if (node == NULL) return NULL; - return IB_ENTRY(node, struct ib_hash_entry, node); -} - - -void ib_map_init(struct ib_hash_map *hm, size_t (*hash)(const void*), - int (*compare)(const void *, const void *)) -{ - hm->count = 0; - hm->key_copy = NULL; - hm->key_destroy = NULL; - hm->value_copy = NULL; - hm->value_destroy = NULL; - hm->insert = 0; - hm->fixed = 0; - ib_hash_init(&hm->ht, hash, compare); - ib_fastbin_init(&hm->fb, sizeof(struct ib_hash_entry)); -} - -void ib_map_destroy(struct ib_hash_map *hm) -{ - void *ptr; - ib_map_clear(hm); - ptr = ib_hash_swap(&hm->ht, NULL, 0); - if (ptr) { - ikmem_free(ptr); - } - ib_fastbin_destroy(&hm->fb); -} - -struct ib_hash_entry* ib_map_find(struct ib_hash_map *hm, const void *key) -{ - struct ib_hash_table *ht = &hm->ht; - struct ib_hash_node dummy; - struct ib_hash_node *rh; - void *ptr = (void*)key; - ib_hash_node_key(ht, &dummy, ptr); - rh = ib_hash_find(ht, &dummy); - return (rh == NULL)? NULL : IB_ENTRY(rh, struct ib_hash_entry, node); -} - - -void* ib_map_lookup(struct ib_hash_map *hm, const void *key, void *defval) -{ - struct ib_hash_entry *entry = ib_map_find(hm, key); - if (entry == NULL) return defval; - return ib_hash_value(entry); -} - -static inline struct ib_hash_entry* -ib_hash_entry_allocate(struct ib_hash_map *hm, void *key, void *value) -{ - struct ib_hash_entry *entry; - entry = (struct ib_hash_entry*)ib_fastbin_new(&hm->fb); - ASSERTION(entry); - if (hm->key_copy) entry->node.key = hm->key_copy(key); - else entry->node.key = key; - if (hm->value_copy) entry->value = hm->value_copy(value); - else entry->value = value; - return entry; -} - -static inline struct ib_hash_entry* -ib_hash_update(struct ib_hash_map *hm, void *key, void *value, int update) -{ - size_t hash = hm->ht.hash(key); - struct ib_hash_index *index = &(hm->ht.index[hash & hm->ht.index_mask]); - struct ib_node **link = &index->avlroot.node; - struct ib_node *parent = NULL; - struct ib_hash_entry *entry; - int (*compare)(const void *key1, const void *key2) = hm->ht.compare; - if (index->avlroot.node == NULL) { - entry = ib_hash_entry_allocate(hm, key, value); - ASSERTION(entry); - entry->node.avlnode.height = 1; - entry->node.avlnode.left = NULL; - entry->node.avlnode.right = NULL; - entry->node.avlnode.parent = NULL; - entry->node.hash = hash; - index->avlroot.node = &(entry->node.avlnode); - ilist_add_tail(&index->node, &(hm->ht.head)); - hm->ht.count++; - hm->insert = 1; - return entry; - } - while (link[0]) { - struct ib_hash_node *snode; - size_t shash; - parent = link[0]; - snode = IB_ENTRY(parent, struct ib_hash_node, avlnode); - shash = snode->hash; - if (hash != shash) { - link = (hash < shash)? (&parent->left) : (&parent->right); - } else { - int hc = compare(key, snode->key); - if (hc == 0) { - entry = IB_ENTRY(snode, struct ib_hash_entry, node); - if (update) { - if (hm->value_destroy) { - hm->value_destroy(entry->value); - } - if (hm->value_copy == NULL) entry->value = value; - else entry->value = hm->value_copy(value); - } - hm->insert = 0; - return entry; - } else { - link = (hc < 0)? (&parent->left) : (&parent->right); - } - } - } - entry = ib_hash_entry_allocate(hm, key, value); - ASSERTION(entry); - entry->node.hash = hash; - ib_node_link(&(entry->node.avlnode), parent, link); - ib_node_post_insert(&(entry->node.avlnode), &index->avlroot); - hm->ht.count++; - hm->insert = 1; - return entry; -} - -static inline void ib_map_rehash(struct ib_hash_map *hm, size_t capacity) -{ - size_t isize = hm->ht.index_size; - size_t limit = (capacity * 6) >> 2; /* capacity * 6 / 4 */ - if (isize < limit && hm->fixed == 0) { - size_t need = isize; - size_t size; - void *ptr; - while (need < limit) need <<= 1; - size = need * sizeof(struct ib_hash_index); - ptr = ikmem_malloc(size); - ASSERTION(ptr); - ptr = ib_hash_swap(&hm->ht, ptr, size); - if (ptr) { - ikmem_free(ptr); - } - } -} - -void ib_map_reserve(struct ib_hash_map *hm, size_t capacity) -{ - ib_map_rehash(hm, capacity); -} - -struct ib_hash_entry* -ib_map_add(struct ib_hash_map *hm, void *key, void *value, int *success) -{ - struct ib_hash_entry *entry = ib_hash_update(hm, key, value, 0); - if (success) success[0] = hm->insert; - ib_map_rehash(hm, hm->ht.count); - return entry; -} - -struct ib_hash_entry* -ib_map_set(struct ib_hash_map *hm, void *key, void *value) -{ - struct ib_hash_entry *entry = ib_hash_update(hm, key, value, 0); - ib_map_rehash(hm, hm->ht.count); - return entry; -} - -void *ib_map_get(struct ib_hash_map *hm, const void *key) -{ - return ib_map_lookup(hm, key, NULL); -} - -void ib_map_erase(struct ib_hash_map *hm, struct ib_hash_entry *entry) -{ - ASSERTION(entry); - ASSERTION(!ib_node_empty(&(entry->node.avlnode))); - ib_hash_erase(&hm->ht, &entry->node); - ib_node_init(&(entry->node.avlnode)); - if (hm->key_destroy) hm->key_destroy(entry->node.key); - if (hm->value_destroy) hm->value_destroy(entry->value); - entry->node.key = NULL; - entry->value = NULL; - ib_fastbin_del(&hm->fb, entry); -} - -int ib_map_remove(struct ib_hash_map *hm, const void *key) -{ - struct ib_hash_entry *entry; - entry = ib_map_find(hm, key); - if (entry == NULL) { - return -1; - } - ib_map_erase(hm, entry); - return 0; -} - -void ib_map_clear(struct ib_hash_map *hm) -{ - while (1) { - struct ib_hash_entry *entry = ib_map_first(hm); - if (entry == NULL) break; - ib_map_erase(hm, entry); - } - ASSERTION(hm->count == 0); -} - - -/*--------------------------------------------------------------------*/ -/* common type hash and equal functions */ -/*--------------------------------------------------------------------*/ -size_t ib_hash_seed = 0x11223344; - -size_t ib_hash_func_uint(const void *key) -{ -#if 0 - size_t x = (size_t)key; - return (x * 2654435761u) ^ ib_hash_seed; -#else - return (size_t)key; -#endif -} - -size_t ib_hash_func_int(const void *key) -{ -#if 0 - size_t x = (size_t)key; - return (x * 2654435761u) ^ ib_hash_seed; -#else - return (size_t)key; -#endif -} - -size_t ib_hash_bytes_stl(const void *ptr, size_t size, size_t seed) -{ - const unsigned char *buf = (const unsigned char*)ptr; - const size_t m = 0x5bd1e995; - size_t hash = size ^ seed; - for (; size >= 4; buf += 4, size -= 4) { - size_t k = *((IUINT32*)buf); - k *= m; - k = (k >> 24) * m; - hash = (hash * m) ^ k; - } - switch (size) { - case 3: hash ^= ((IUINT32)buf[2]) << 16; - case 2: hash ^= ((IUINT32)buf[1]) << 8; - case 1: hash ^= ((IUINT32)buf[0]); hash = hash * m; break; - } - hash = (hash ^ (hash >> 13)) * m; - return hash ^ (hash >> 15); -} - -size_t ib_hash_bytes_lua(const void *ptr, size_t size, size_t seed) -{ - const unsigned char *name = (const unsigned char*)ptr; - size_t step = (size >> 5) + 1; - size_t h = size ^ seed, i; - for(i = size; i >= step; i -= step) - h = h ^ ((h << 5) + (h >> 2) + (size_t)name[i - 1]); - return h; -} - -size_t ib_hash_func_str(const void *key) -{ - ib_string *str = (ib_string*)key; -#ifndef IB_HASH_BYTES_STL - return ib_hash_bytes_lua(str->ptr, str->size, ib_hash_seed); -#else - return ib_hash_bytes_stl(str->ptr, str->size, ib_hash_seed); -#endif -} - -size_t ib_hash_func_cstr(const void *key) -{ - const char *str = (const char*)key; - size_t size = strlen(str); -#ifndef IB_HASH_BYTES_STL - return ib_hash_bytes_lua(str, size, ib_hash_seed); -#else - return ib_hash_bytes_stl(str, size, ib_hash_seed); -#endif -} - -int ib_hash_compare_uint(const void *key1, const void *key2) -{ - size_t x = (size_t)key1; - size_t y = (size_t)key2; - if (x == y) return 0; - return (x < y)? -1 : 1; -} - -int ib_hash_compare_int(const void *key1, const void *key2) -{ - ilong x = (ilong)key1; - ilong y = (ilong)key2; - if (x == y) return 0; - return (x < y)? -1 : 1; -} - -int ib_hash_compare_str(const void *key1, const void *key2) -{ - return ib_string_compare((const ib_string*)key1, (const ib_string*)key2); -} - -int ib_compare_bytes(const void *p1, size_t s1, const void *p2, size_t s2) -{ - size_t minsize = (s1 < s2)? s1 : s2; - int hr = memcmp(p1, p2, minsize); - if (hr == 0) { - if (s1 == s2) return 0; - return (s1 < s2)? -1 : 1; - } - else { - return (hr < 0)? -1 : 1; - } -} - -int ib_hash_compare_cstr(const void *key1, const void *key2) -{ - const char *x = (const char*)key1; - const char *y = (const char*)key2; - return ib_compare_bytes(x, strlen(x), y, strlen(y)); -} - - - -struct ib_hash_entry *ib_map_find_uint(struct ib_hash_map *hm, iulong key) -{ - struct ib_hash_entry *hr; - void *kk = (void*)key; - ib_map_search(hm, kk, ib_hash_func_uint, ib_hash_compare_uint, hr); - return hr; -} - -struct ib_hash_entry *ib_map_find_int(struct ib_hash_map *hm, ilong key) -{ - struct ib_hash_entry *hr; - void *kk = (void*)key; - ib_map_search(hm, kk, ib_hash_func_int, ib_hash_compare_int, hr); - return hr; -} - -struct ib_hash_entry *ib_map_find_str(struct ib_hash_map *hm, const ib_string *key) -{ - struct ib_hash_entry *hr; - void *kk = (void*)key; - ib_map_search(hm, kk, ib_hash_func_str, ib_hash_compare_str, hr); - return hr; -} - -struct ib_hash_entry *ib_map_find_cstr(struct ib_hash_map *hm, const char *key) -{ - struct ib_hash_entry *hr; - void *kk = (void*)key; - ib_map_search(hm, kk, ib_hash_func_cstr, ib_hash_compare_cstr, hr); - return hr; -} - - - - diff --git a/czmod/imembase.h b/czmod/imembase.h deleted file mode 100644 index 811b177..0000000 --- a/czmod/imembase.h +++ /dev/null @@ -1,916 +0,0 @@ -/********************************************************************** - * - * imembase.h - basic interface of memory operation - * skywind3000 (at) gmail.com, 2006-2016 - * - **********************************************************************/ - -#ifndef __IMEMBASE_H__ -#define __IMEMBASE_H__ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - - -/********************************************************************** - * 32BIT INTEGER DEFINITION - **********************************************************************/ -#ifndef __INTEGER_32_BITS__ -#define __INTEGER_32_BITS__ -#if defined(__UINT32_TYPE__) && defined(__UINT32_TYPE__) - typedef __UINT32_TYPE__ ISTDUINT32; - typedef __INT32_TYPE__ ISTDINT32; -#elif defined(__UINT_FAST32_TYPE__) && defined(__INT_FAST32_TYPE__) - typedef __UINT_FAST32_TYPE__ ISTDUINT32; - typedef __INT_FAST32_TYPE__ ISTDINT32; -#elif defined(_WIN64) || defined(WIN64) || defined(__amd64__) || \ - defined(__x86_64) || defined(__x86_64__) || defined(_M_IA64) || \ - defined(_M_AMD64) - typedef unsigned int ISTDUINT32; - typedef int ISTDINT32; -#elif defined(_WIN32) || defined(WIN32) || defined(__i386__) || \ - defined(__i386) || defined(_M_X86) - typedef unsigned long ISTDUINT32; - typedef long ISTDINT32; -#elif defined(__MACOS__) - typedef UInt32 ISTDUINT32; - typedef SInt32 ISTDINT32; -#elif defined(__APPLE__) && defined(__MACH__) - #include - typedef u_int32_t ISTDUINT32; - typedef int32_t ISTDINT32; -#elif defined(__BEOS__) - #include - typedef u_int32_t ISTDUINT32; - typedef int32_t ISTDINT32; -#elif (defined(_MSC_VER) || defined(__BORLANDC__)) && (!defined(__MSDOS__)) - typedef unsigned __int32 ISTDUINT32; - typedef __int32 ISTDINT32; -#elif defined(__GNUC__) && (__GNUC__ > 3) - #include - typedef uint32_t ISTDUINT32; - typedef int32_t ISTDINT32; -#else -#include -#if UINT_MAX == 0xFFFFU - typedef unsigned long ISTDUINT32; - typedef long ISTDINT32; -#else - typedef unsigned int ISTDUINT32; - typedef int ISTDINT32; -#endif -#endif -#endif - - -/********************************************************************** - * Global Macros - **********************************************************************/ -#ifndef __IUINT8_DEFINED -#define __IUINT8_DEFINED -typedef unsigned char IUINT8; -#endif - -#ifndef __IINT8_DEFINED -#define __IINT8_DEFINED -typedef signed char IINT8; -#endif - -#ifndef __IUINT16_DEFINED -#define __IUINT16_DEFINED -typedef unsigned short IUINT16; -#endif - -#ifndef __IINT16_DEFINED -#define __IINT16_DEFINED -typedef signed short IINT16; -#endif - -#ifndef __IINT32_DEFINED -#define __IINT32_DEFINED -typedef ISTDINT32 IINT32; -#endif - -#ifndef __IUINT32_DEFINED -#define __IUINT32_DEFINED -typedef ISTDUINT32 IUINT32; -#endif - - -/*--------------------------------------------------------------------*/ -/* INLINE */ -/*--------------------------------------------------------------------*/ -#ifndef INLINE -#if defined(__GNUC__) - -#if (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) -#define INLINE __inline__ __attribute__((always_inline)) -#else -#define INLINE __inline__ -#endif - -#elif (defined(_MSC_VER) || defined(__WATCOMC__)) -#define INLINE __inline -#else -#define INLINE -#endif -#endif - -#if (!defined(__cplusplus)) && (!defined(inline)) -#define inline INLINE -#endif - -/* you can change this by config.h or predefined macro */ -#ifndef ASSERTION -#define ASSERTION(x) ((void)0) -#endif - - -/*====================================================================*/ -/* IULONG/ILONG (ensure sizeof(iulong) == sizeof(void*)) */ -/*====================================================================*/ -#ifndef __IULONG_DEFINED -#define __IULONG_DEFINED -typedef ptrdiff_t ilong; -typedef size_t iulong; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - -/*====================================================================*/ -/* IALLOCATOR */ -/*====================================================================*/ -struct IALLOCATOR -{ - void *(*alloc)(struct IALLOCATOR *, size_t); - void (*free)(struct IALLOCATOR *, void *); - void *(*realloc)(struct IALLOCATOR *, void *, size_t); - void *udata; -}; - -void* internal_malloc(struct IALLOCATOR *allocator, size_t size); -void internal_free(struct IALLOCATOR *allocator, void *ptr); -void* internal_realloc(struct IALLOCATOR *allocator, void *ptr, size_t size); - - -/*====================================================================*/ -/* IKMEM INTERFACE */ -/*====================================================================*/ -extern struct IALLOCATOR *ikmem_allocator; - -void* ikmem_malloc(size_t size); -void* ikmem_realloc(void *ptr, size_t size); -void ikmem_free(void *ptr); - - -/*====================================================================*/ -/* IVECTOR */ -/*====================================================================*/ -struct IVECTOR -{ - unsigned char *data; - size_t size; - size_t capacity; - struct IALLOCATOR *allocator; -}; - -void iv_init(struct IVECTOR *v, struct IALLOCATOR *allocator); -void iv_destroy(struct IVECTOR *v); -int iv_resize(struct IVECTOR *v, size_t newsize); -int iv_reserve(struct IVECTOR *v, size_t newsize); - -size_t iv_pop(struct IVECTOR *v, void *data, size_t size); -int iv_push(struct IVECTOR *v, const void *data, size_t size); -int iv_insert(struct IVECTOR *v, size_t pos, const void *data, size_t size); -int iv_erase(struct IVECTOR *v, size_t pos, size_t size); - -#define iv_size(v) ((v)->size) -#define iv_data(v) ((v)->data) - -#define iv_entry(v, type) ((type*)iv_data(v)) - -#define iv_obj_index(v, type, index) (iv_entry(v, type)[index]) -#define iv_obj_push(v, type, objptr) iv_push(v, objptr, sizeof(type)) -#define iv_obj_pop(v, type, objptr) iv_pop(v, objptr, sizeof(type)) -#define iv_obj_size(v, type) (((v)->size) / sizeof(type)) -#define iv_obj_capacity(v, type) (((v)->capacity) / sizeof(type)) -#define iv_obj_resize(v, type, count) iv_resize(v, (count) * sizeof(type)) -#define iv_obj_reserve(v, type, count) iv_reserve(v, (count) * sizeof(type)) - -#define iv_obj_insert(v, type, pos, objptr) \ - iv_insert(v, (pos) * sizeof(type), objptr, sizeof(type)) - -#define iv_obj_erase(v, type, pos, count) \ - iv_erase(v, (pos) * sizeof(type), (count) * sizeof(type)) - - -#define IROUND_SIZE(b) (((size_t)1) << (b)) -#define IROUND_UP(s, n) (((s) + (n) - 1) & ~(((size_t)(n)) - 1)) - - -/*====================================================================*/ -/* IMEMNODE */ -/*====================================================================*/ -struct IMEMNODE -{ - struct IALLOCATOR *allocator; /* memory allocator */ - - struct IVECTOR vprev; /* prev node link vector */ - struct IVECTOR vnext; /* next node link vector */ - struct IVECTOR vnode; /* node information data */ - struct IVECTOR vdata; /* node data buffer vector */ - struct IVECTOR vmode; /* mode of allocation */ - ilong *mprev; /* prev node array */ - ilong *mnext; /* next node array */ - ilong *mnode; /* node info array */ - void **mdata; /* node data array */ - ilong *mmode; /* node mode array */ - ilong *extra; /* extra user data */ - ilong node_free; /* number of free nodes */ - ilong node_used; /* number of allocated */ - ilong node_max; /* number of all nodes */ - ilong grow_limit; /* limit of growing */ - - ilong node_size; /* node data fixed size */ - ilong node_shift; /* node data size shift */ - - struct IVECTOR vmem; /* mem-pages in the pool */ - char **mmem; /* mem-pages array */ - ilong mem_max; /* max num of memory pages */ - ilong mem_count; /* number of mem-pages */ - - ilong list_open; /* the entry of open-list */ - ilong list_close; /* the entry of close-list */ - ilong total_mem; /* total memory size */ -}; - - -void imnode_init(struct IMEMNODE *mn, ilong nodesize, struct IALLOCATOR *ac); -void imnode_destroy(struct IMEMNODE *mnode); -ilong imnode_new(struct IMEMNODE *mnode); -void imnode_del(struct IMEMNODE *mnode, ilong index); -ilong imnode_head(const struct IMEMNODE *mnode); -ilong imnode_next(const struct IMEMNODE *mnode, ilong index); -ilong imnode_prev(const struct IMEMNODE *mnode, ilong index); -void*imnode_data(struct IMEMNODE *mnode, ilong index); -const void* imnode_data_const(const struct IMEMNODE *mnode, ilong index); - -#define IMNODE_NODE(mnodeptr, i) ((mnodeptr)->mnode[i]) -#define IMNODE_PREV(mnodeptr, i) ((mnodeptr)->mprev[i]) -#define IMNODE_NEXT(mnodeptr, i) ((mnodeptr)->mnext[i]) -#define IMNODE_DATA(mnodeptr, i) ((mnodeptr)->mdata[i]) -#define IMNODE_MODE(mnodeptr, i) ((mnodeptr)->mmode[i]) - - -/*====================================================================*/ -/* LIST DEFINITION */ -/*====================================================================*/ -#ifndef __ILIST_DEF__ -#define __ILIST_DEF__ - -struct ILISTHEAD { - struct ILISTHEAD *next, *prev; -}; - -typedef struct ILISTHEAD ilist_head; - - -/*--------------------------------------------------------------------*/ -/* list init */ -/*--------------------------------------------------------------------*/ -#define ILIST_HEAD_INIT(name) { &(name), &(name) } -#define ILIST_HEAD(name) \ - struct ILISTHEAD name = ILIST_HEAD_INIT(name) - -#define ILIST_INIT(ptr) ( \ - (ptr)->next = (ptr), (ptr)->prev = (ptr)) - -#define IOFFSETOF(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) - -#define ICONTAINEROF(ptr, type, member) ( \ - (type*)( ((char*)((type*)ptr)) - IOFFSETOF(type, member)) ) - -#define ILIST_ENTRY(ptr, type, member) ICONTAINEROF(ptr, type, member) - - -/*--------------------------------------------------------------------*/ -/* list operation */ -/*--------------------------------------------------------------------*/ -#define ILIST_ADD(node, head) ( \ - (node)->prev = (head), (node)->next = (head)->next, \ - (head)->next->prev = (node), (head)->next = (node)) - -#define ILIST_ADD_TAIL(node, head) ( \ - (node)->prev = (head)->prev, (node)->next = (head), \ - (head)->prev->next = (node), (head)->prev = (node)) - -#define ILIST_DEL_BETWEEN(p, n) ((n)->prev = (p), (p)->next = (n)) - -#define ILIST_DEL(entry) (\ - (entry)->next->prev = (entry)->prev, \ - (entry)->prev->next = (entry)->next, \ - (entry)->next = 0, (entry)->prev = 0) - -#define ILIST_DEL_INIT(entry) do { \ - ILIST_DEL(entry); ILIST_INIT(entry); } while (0) - -#define ILIST_IS_EMPTY(entry) ((entry) == (entry)->next) - -#define ilist_init ILIST_INIT -#define ilist_entry ILIST_ENTRY -#define ilist_add ILIST_ADD -#define ilist_add_tail ILIST_ADD_TAIL -#define ilist_del ILIST_DEL -#define ilist_del_init ILIST_DEL_INIT -#define ilist_is_empty ILIST_IS_EMPTY - -#define ILIST_FOREACH(iterator, head, TYPE, MEMBER) \ - for ((iterator) = ilist_entry((head)->next, TYPE, MEMBER); \ - &((iterator)->MEMBER) != (head); \ - (iterator) = ilist_entry((iterator)->MEMBER.next, TYPE, MEMBER)) - -#define ilist_foreach(iterator, head, TYPE, MEMBER) \ - ILIST_FOREACH(iterator, head, TYPE, MEMBER) - -#define ilist_foreach_entry(pos, head) \ - for( (pos) = (head)->next; (pos) != (head) ; (pos) = (pos)->next ) - - -#define __ilist_splice(list, head) do { \ - ilist_head *first = (list)->next, *last = (list)->prev; \ - ilist_head *at = (head)->next; \ - (first)->prev = (head), (head)->next = (first); \ - (last)->next = (at), (at)->prev = (last); } while (0) - -#define ilist_splice(list, head) do { \ - if (!ilist_is_empty(list)) __ilist_splice(list, head); } while (0) - -#define ilist_splice_init(list, head) do { \ - ilist_splice(list, head); ilist_init(list); } while (0) - -#define ilist_replace(oldnode, newnode) ( \ - (newnode)->next = (oldnode)->next, \ - (newnode)->next->prev = (newnode), \ - (newnode)->prev = (oldnode)->prev, \ - (newnode)->prev->next = (newnode)) - -#ifdef _MSC_VER -#pragma warning(disable:4311) -#pragma warning(disable:4312) -#pragma warning(disable:4996) -#endif - -#endif - - -/*====================================================================*/ -/* IMUTEX - mutex interfaces */ -/*====================================================================*/ -#ifndef IMUTEX_TYPE - -#ifndef IMUTEX_DISABLE -#if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) -#if ((!defined(_M_PPC)) && (!defined(_M_PPC_BE)) && (!defined(_XBOX))) -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0500 -#endif -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#else -#ifndef _XBOX -#define _XBOX -#endif -#include -#endif - -#define IMUTEX_TYPE CRITICAL_SECTION -#define IMUTEX_INIT(m) InitializeCriticalSection((CRITICAL_SECTION*)(m)) -#define IMUTEX_DESTROY(m) DeleteCriticalSection((CRITICAL_SECTION*)(m)) -#define IMUTEX_LOCK(m) EnterCriticalSection((CRITICAL_SECTION*)(m)) -#define IMUTEX_UNLOCK(m) LeaveCriticalSection((CRITICAL_SECTION*)(m)) - -#elif defined(__unix) || defined(__unix__) || defined(__MACH__) -#include -#include -#define IMUTEX_TYPE pthread_mutex_t -#define IMUTEX_INIT(m) pthread_mutex_init((pthread_mutex_t*)(m), 0) -#define IMUTEX_DESTROY(m) pthread_mutex_destroy((pthread_mutex_t*)(m)) -#define IMUTEX_LOCK(m) pthread_mutex_lock((pthread_mutex_t*)(m)) -#define IMUTEX_UNLOCK(m) pthread_mutex_unlock((pthread_mutex_t*)(m)) -#endif -#endif - -#ifndef IMUTEX_TYPE -#define IMUTEX_TYPE int -#define IMUTEX_INIT(m) { (*(m)) = (*(m)); } -#define IMUTEX_DESTROY(m) { (*(m)) = (*(m)); } -#define IMUTEX_LOCK(m) { (*(m)) = (*(m)); } -#define IMUTEX_UNLOCK(m) { (*(m)) = (*(m)); } -#endif - -#endif - - - -/*====================================================================*/ -/* IVECTOR / IMEMNODE MANAGEMENT */ -/*====================================================================*/ - -typedef struct IVECTOR ib_vector; -typedef struct IMEMNODE ib_memnode; - -ib_vector *iv_create(void); -void iv_delete(ib_vector *vec); - -ib_memnode *imnode_create(ilong nodesize, int grow_limit); -void imnode_delete(ib_memnode *); - - -/*--------------------------------------------------------------------*/ -/* Collection - Array */ -/*--------------------------------------------------------------------*/ - -struct ib_array; -typedef struct ib_array ib_array; - -ib_array *ib_array_new(void (*destroy_func)(void*)); -void ib_array_delete(ib_array *array); -void ib_array_reserve(ib_array *array, size_t new_size); -size_t ib_array_size(const ib_array *array); -void** ib_array_ptr(ib_array *array); -void* ib_array_index(ib_array *array, size_t index); -const void* ib_array_const_index(const ib_array *array, size_t index); -void ib_array_push(ib_array *array, void *item); -void ib_array_push_left(ib_array *array, void *item); -void ib_array_replace(ib_array *array, size_t index, void *item); -void* ib_array_pop(ib_array *array); -void* ib_array_pop_left(ib_array *array); -void ib_array_remove(ib_array *array, size_t index); -void ib_array_insert_before(ib_array *array, size_t index, void *item); -void* ib_array_pop_at(ib_array *array, size_t index); -void ib_array_for_each(ib_array *array, void (*iterator)(void *item)); - -void ib_array_sort(ib_array *array, - int (*compare)(const void*, const void*)); - -ilong ib_array_search(const ib_array *array, - int (*compare)(const void*, const void*), - const void *item, - ilong start_pos); - -ilong ib_array_bsearch(const ib_array *array, - int (*compare)(const void*, const void*), - const void *item); - - -/*====================================================================*/ -/* ib_node - binary search tree (can be used in rbtree & avl) */ -/* color/balance won't be packed (can work without alignment) */ -/*====================================================================*/ -struct ib_node -{ - struct ib_node *left; /* left child */ - struct ib_node *right; /* right child */ - struct ib_node *parent; /* pointing to node itself for empty node */ - int height; /* equals to 1 + max height in childs */ -}; - -struct ib_root -{ - struct ib_node *node; /* root node */ -}; - - -/*--------------------------------------------------------------------*/ -/* NODE MACROS */ -/*--------------------------------------------------------------------*/ -#define IB_OFFSET(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) - -#define IB_NODE2DATA(n, o) ((void *)((size_t)(n) - (o))) -#define IB_DATA2NODE(d, o) ((struct ib_node*)((size_t)(d) + (o))) - -#define IB_ENTRY(ptr, type, member) \ - ((type*)IB_NODE2DATA(ptr, IB_OFFSET(type, member))) - -#define ib_node_init(node) do { ((node)->parent) = (node); } while (0) -#define ib_node_empty(node) ((node)->parent == (node)) - -#define IB_LEFT_HEIGHT(node) (((node)->left)? ((node)->left)->height : 0) -#define IB_RIGHT_HEIGHT(node) (((node)->right)? ((node)->right)->height : 0) - - -/*--------------------------------------------------------------------*/ -/* binary search tree - node manipulation */ -/*--------------------------------------------------------------------*/ -struct ib_node *ib_node_first(struct ib_root *root); -struct ib_node *ib_node_last(struct ib_root *root); -struct ib_node *ib_node_next(struct ib_node *node); -struct ib_node *ib_node_prev(struct ib_node *node); - -void ib_node_replace(struct ib_node *victim, struct ib_node *newnode, - struct ib_root *root); - -static inline void ib_node_link(struct ib_node *node, struct ib_node *parent, - struct ib_node **ib_link) { - node->parent = parent; - node->height = 1; - node->left = node->right = NULL; - ib_link[0] = node; -} - - -/* avl insert rebalance and erase */ -void ib_node_post_insert(struct ib_node *node, struct ib_root *root); -void ib_node_erase(struct ib_node *node, struct ib_root *root); - -/* avl nodes destroy: fast tear down the whole tree */ -struct ib_node* ib_node_tear(struct ib_root *root, struct ib_node **next); - - -/*--------------------------------------------------------------------*/ -/* avl - node templates */ -/*--------------------------------------------------------------------*/ -#define ib_node_find(root, what, compare_fn, res_node) do {\ - struct ib_node *__n = (root)->node; \ - (res_node) = NULL; \ - while (__n) { \ - int __hr = (compare_fn)(what, __n); \ - if (__hr == 0) { (res_node) = __n; break; } \ - else if (__hr < 0) { __n = __n->left; } \ - else { __n = __n->right; } \ - } \ - } while (0) - - -#define ib_node_add(root, newnode, compare_fn, duplicate_node) do { \ - struct ib_node **__link = &((root)->node); \ - struct ib_node *__parent = NULL; \ - struct ib_node *__duplicate = NULL; \ - int __hr = 1; \ - while (__link[0]) { \ - __parent = __link[0]; \ - __hr = (compare_fn)(newnode, __parent); \ - if (__hr == 0) { __duplicate = __parent; break; } \ - else if (__hr < 0) { __link = &(__parent->left); } \ - else { __link = &(__parent->right); } \ - } \ - (duplicate_node) = __duplicate; \ - if (__duplicate == NULL) { \ - ib_node_link(newnode, __parent, __link); \ - ib_node_post_insert(newnode, root); \ - } \ - } while (0) - - -/*--------------------------------------------------------------------*/ -/* avltree - friendly interface */ -/*--------------------------------------------------------------------*/ -struct ib_tree -{ - struct ib_root root; /* avl root */ - size_t offset; /* node offset in user data structure */ - size_t size; /* size of user data structure */ - size_t count; /* node count */ - /* returns 0 for equal, -1 for n1 < n2, 1 for n1 > n2 */ - int (*compare)(const void *n1, const void *n2); -}; - - -/* initialize avltree, use IB_OFFSET(type, member) for "offset" - * eg: - * ib_tree_init(&mytree, mystruct_compare, - * sizeof(struct mystruct_t), - * IB_OFFSET(struct mystruct_t, node)); - */ -void ib_tree_init(struct ib_tree *tree, - int (*compare)(const void*, const void*), size_t size, size_t offset); - -void *ib_tree_first(struct ib_tree *tree); -void *ib_tree_last(struct ib_tree *tree); -void *ib_tree_next(struct ib_tree *tree, void *data); -void *ib_tree_prev(struct ib_tree *tree, void *data); - -/* require a temporary user structure (data) which contains the key */ -void *ib_tree_find(struct ib_tree *tree, const void *data); -void *ib_tree_nearest(struct ib_tree *tree, const void *data); - -/* returns NULL for success, otherwise returns conflict node with same key */ -void *ib_tree_add(struct ib_tree *tree, void *data); - -void ib_tree_remove(struct ib_tree *tree, void *data); -void ib_tree_replace(struct ib_tree *tree, void *victim, void *newdata); - -void ib_tree_clear(struct ib_tree *tree, void (*destroy)(void *data)); - - -/*--------------------------------------------------------------------*/ -/* fastbin - fixed size object allocator */ -/*--------------------------------------------------------------------*/ -struct ib_fastbin -{ - size_t obj_size; - size_t page_size; - size_t maximum; - char *start; - char *endup; - void *next; - void *pages; -}; - - -#define IB_NEXT(ptr) (((void**)(ptr))[0]) - -void ib_fastbin_init(struct ib_fastbin *fb, size_t obj_size); -void ib_fastbin_destroy(struct ib_fastbin *fb); - -void* ib_fastbin_new(struct ib_fastbin *fb); -void ib_fastbin_del(struct ib_fastbin *fb, void *ptr); - - -/*--------------------------------------------------------------------*/ -/* string */ -/*--------------------------------------------------------------------*/ -struct ib_string; -typedef struct ib_string ib_string; - -#ifndef IB_STRING_SSO -#define IB_STRING_SSO 14 -#endif - -struct ib_string -{ - char *ptr; - int size; - int capacity; - char sso[IB_STRING_SSO + 2]; -}; - -#define ib_string_ptr(str) ((str)->ptr) -#define ib_string_size(str) ((str)->size) - -ib_string* ib_string_new(void); -ib_string* ib_string_new_from(const char *text); -ib_string* ib_string_new_size(const char *text, int size); - -void ib_string_delete(ib_string *str); - -ib_string* ib_string_resize(ib_string *str, int newsize); - -ib_string* ib_string_assign(ib_string *str, const char *src); -ib_string* ib_string_assign_size(ib_string *str, const char *src, int size); - -ib_string* ib_string_erase(ib_string *str, int pos, int size); -ib_string* ib_string_insert(ib_string *str, int pos, - const void *data, int size); - -ib_string* ib_string_append(ib_string *str, const char *src); -ib_string* ib_string_append_size(ib_string *str, const char *src, int size); -ib_string* ib_string_append_c(ib_string *str, char c); - -ib_string* ib_string_prepend(ib_string *str, const char *src); -ib_string* ib_string_prepend_size(ib_string *str, const char *src, int size); -ib_string* ib_string_prepend_c(ib_string *str, char c); - -ib_string* ib_string_rewrite(ib_string *str, int pos, const char *src); -ib_string* ib_string_rewrite_size(ib_string *str, int pos, - const char *src, int size); - -int ib_string_compare(const struct ib_string *a, const struct ib_string *b); - -int ib_string_find(const ib_string *str, const char *src, int len, int start); -int ib_string_find_c(const ib_string *str, char ch, int start); - -ib_array* ib_string_split(const ib_string *str, const char *sep, int len); -ib_array* ib_string_split_c(const ib_string *str, char sep); - -ib_string* ib_string_strip(ib_string *str, const char *seps); - - -/*--------------------------------------------------------------------*/ -/* static hash table (closed hash table with avlnode) */ -/*--------------------------------------------------------------------*/ -struct ib_hash_node -{ - struct ib_node avlnode; - void *key; - size_t hash; -}; - -struct ib_hash_index -{ - struct ILISTHEAD node; - struct ib_root avlroot; -}; - -#define IB_HASH_INIT_SIZE 8 - -struct ib_hash_table -{ - size_t count; - size_t index_size; - size_t index_mask; - size_t (*hash)(const void *key); - int (*compare)(const void *key1, const void *key2); - struct ILISTHEAD head; - struct ib_hash_index *index; - struct ib_hash_index init[IB_HASH_INIT_SIZE]; -}; - - -void ib_hash_init(struct ib_hash_table *ht, - size_t (*hash)(const void *key), - int (*compare)(const void *key1, const void *key2)); - -struct ib_hash_node* ib_hash_node_first(struct ib_hash_table *ht); -struct ib_hash_node* ib_hash_node_last(struct ib_hash_table *ht); - -struct ib_hash_node* ib_hash_node_next(struct ib_hash_table *ht, - struct ib_hash_node *node); - -struct ib_hash_node* ib_hash_node_prev(struct ib_hash_table *ht, - struct ib_hash_node *node); - -static inline void ib_hash_node_key(struct ib_hash_table *ht, - struct ib_hash_node *node, void *key) { - node->key = key; - node->hash = ht->hash(key); -} - -struct ib_hash_node* ib_hash_find(struct ib_hash_table *ht, - const struct ib_hash_node *node); - -struct ib_node** ib_hash_track(struct ib_hash_table *ht, - const struct ib_hash_node *node, struct ib_node **parent); - -struct ib_hash_node* ib_hash_add(struct ib_hash_table *ht, - struct ib_hash_node *node); - -void ib_hash_erase(struct ib_hash_table *ht, struct ib_hash_node *node); - -void ib_hash_replace(struct ib_hash_table *ht, - struct ib_hash_node *victim, struct ib_hash_node *newnode); - -void ib_hash_clear(struct ib_hash_table *ht, - void (*destroy)(struct ib_hash_node *node)); - -/* re-index nbytes must be: sizeof(struct ib_hash_index) * n */ -void* ib_hash_swap(struct ib_hash_table *ht, void *index, size_t nbytes); - - -/*--------------------------------------------------------------------*/ -/* fast inline search, compare function will be expanded inline here */ -/*--------------------------------------------------------------------*/ -#define ib_hash_search(ht, srcnode, result, compare) do { \ - size_t __hash = (srcnode)->hash; \ - const void *__key = (srcnode)->key; \ - struct ib_hash_index *__index = \ - &((ht)->index[__hash & ((ht)->index_mask)]); \ - struct ib_node *__anode = __index->avlroot.node; \ - (result) = NULL; \ - while (__anode) { \ - struct ib_hash_node *__snode = \ - IB_ENTRY(__anode, struct ib_hash_node, avlnode); \ - size_t __shash = __snode->hash; \ - if (__hash == __shash) { \ - int __hc = (compare)(__key, __snode->key); \ - if (__hc == 0) { (result) = __snode; break; } \ - __anode = (__hc < 0)? __anode->left : __anode->right; \ - } else { \ - __anode = (__hash < __shash)? __anode->left:__anode->right;\ - } \ - } \ - } while (0) - - -/*--------------------------------------------------------------------*/ -/* hash map, wrapper of ib_hash_table to support direct key/value */ -/*--------------------------------------------------------------------*/ -struct ib_hash_entry -{ - struct ib_hash_node node; - void *value; -}; - -struct ib_hash_map -{ - size_t count; - int insert; - int fixed; - int builtin; - void* (*key_copy)(void *key); - void (*key_destroy)(void *key); - void* (*value_copy)(void *value); - void (*value_destroy)(void *value); - struct ib_fastbin fb; - struct ib_hash_table ht; -}; - - -#define ib_hash_key(entry) ((entry)->node.key) -#define ib_hash_value(entry) ((entry)->value) - -void ib_map_init(struct ib_hash_map *hm, size_t (*hash)(const void*), - int (*compare)(const void *, const void *)); - -void ib_map_destroy(struct ib_hash_map *hm); - -struct ib_hash_entry* ib_map_first(struct ib_hash_map *hm); -struct ib_hash_entry* ib_map_last(struct ib_hash_map *hm); - -struct ib_hash_entry* ib_map_next(struct ib_hash_map *hm, - struct ib_hash_entry *n); -struct ib_hash_entry* ib_map_prev(struct ib_hash_map *hm, - struct ib_hash_entry *n); - -struct ib_hash_entry* ib_map_find(struct ib_hash_map *hm, const void *key); -void* ib_map_lookup(struct ib_hash_map *hm, const void *key, void *defval); - - -struct ib_hash_entry* ib_map_add(struct ib_hash_map *hm, - void *key, void *value, int *success); - -struct ib_hash_entry* ib_map_set(struct ib_hash_map *hm, - void *key, void *value); - -void* ib_map_get(struct ib_hash_map *hm, const void *key); - -void ib_map_erase(struct ib_hash_map *hm, struct ib_hash_entry *entry); - - -/* returns 0 for success, -1 for key mismatch */ -int ib_map_remove(struct ib_hash_map *hm, const void *key); - -void ib_map_clear(struct ib_hash_map *hm); - - -/*--------------------------------------------------------------------*/ -/* fast inline search template */ -/*--------------------------------------------------------------------*/ - -#define ib_map_search(hm, srckey, hash_func, cmp_func, result) do { \ - size_t __hash = (hash_func)(srckey); \ - struct ib_hash_index *__index = \ - &((hm)->ht.index[__hash & ((hm)->ht.index_mask)]); \ - struct ib_node *__anode = __index->avlroot.node; \ - (result) = NULL; \ - while (__anode) { \ - struct ib_hash_node *__snode = \ - IB_ENTRY(__anode, struct ib_hash_node, avlnode); \ - size_t __shash = __snode->hash; \ - if (__hash == __shash) { \ - int __hc = (cmp_func)((srckey), __snode->key); \ - if (__hc == 0) { \ - (result) = IB_ENTRY(__snode, \ - struct ib_hash_entry, node);\ - break; \ - } \ - __anode = (__hc < 0)? __anode->left : __anode->right; \ - } else { \ - __anode = (__hash < __shash)? __anode->left:__anode->right;\ - } \ - } \ - } while (0) - - -/*--------------------------------------------------------------------*/ -/* common type hash */ -/*--------------------------------------------------------------------*/ -size_t ib_hash_func_uint(const void *key); -int ib_hash_compare_uint(const void *key1, const void *key2); - -size_t ib_hash_func_int(const void *key); -int ib_hash_compare_int(const void *key1, const void *key2); - -size_t ib_hash_func_str(const void *key); -int ib_hash_compare_str(const void *key1, const void *key2); - -size_t ib_hash_func_cstr(const void *key); -int ib_hash_compare_cstr(const void *key1, const void *key2); - - -struct ib_hash_entry *ib_map_find_uint(struct ib_hash_map *hm, iulong key); -struct ib_hash_entry *ib_map_find_int(struct ib_hash_map *hm, ilong key); -struct ib_hash_entry *ib_map_find_str(struct ib_hash_map *hm, const ib_string *key); -struct ib_hash_entry *ib_map_find_cstr(struct ib_hash_map *hm, const char *key); - - - -#ifdef __cplusplus -} -#endif - -#endif - - - - diff --git a/czmod/iposix.c b/czmod/iposix.c deleted file mode 100644 index d94fb83..0000000 --- a/czmod/iposix.c +++ /dev/null @@ -1,1059 +0,0 @@ -//===================================================================== -// -// iposix.c - posix file system accessing -// -// NOTE: -// for more information, please see the readme file. -// -//===================================================================== - -#include "iposix.h" - -#ifndef IDISABLE_FILE_SYSTEM_ACCESS -//--------------------------------------------------------------------- -// Global Definition -//--------------------------------------------------------------------- -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) -#include -#endif - -#ifdef _WIN32 -#include -#include -#include -#define ISYSNAME 'w' -#else -#ifndef __unix -#define __unix -#endif -#define ISYSNAME 'u' -#endif - - - -//--------------------------------------------------------------------- -// Posix Stat -//--------------------------------------------------------------------- -#ifdef __unix -typedef struct stat iposix_ostat_t; -#define iposix_stat_proc stat -#define iposix_lstat_proc lstat -#define iposix_fstat_proc fstat -#else -typedef struct _stat iposix_ostat_t; -#define iposix_stat_proc _stat -#define iposix_lstat_proc _stat -#define iposix_fstat_proc _fstat -#endif - - -#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64) - #if defined(_S_IFMT) && (!defined(S_IFMT)) - #define S_IFMT _S_IFMT - #endif - - #if defined(_S_IFDIR) && (!defined(S_IFDIR)) - #define S_IFDIR _S_IFDIR - #endif - - #if defined(_S_IFCHR) && (!defined(S_IFCHR)) - #define S_IFCHR _S_IFCHR - #endif - - #if defined(_S_IFIFO) && (!defined(S_IFIFO)) - #define S_IFIFO _S_IFIFO - #endif - - #if defined(_S_IFREG) && (!defined(S_IFREG)) - #define S_IFREG _S_IFREG - #endif - - #if defined(_S_IREAD) && (!defined(S_IREAD)) - #define S_IREAD _S_IREAD - #endif - - #if defined(_S_IWRITE) && (!defined(S_IWRITE)) - #define S_IWRITE _S_IWRITE - #endif - - #if defined(_S_IEXEC) && (!defined(S_IEXEC)) - #define S_IEXEC _S_IEXEC - #endif -#endif - -#define IX_FMT(m, t) (((m) & S_IFMT) == (t)) - - -// convert stat structure -void iposix_stat_convert(iposix_stat_t *ostat, const iposix_ostat_t *x) -{ - ostat->st_mode = 0; - - #ifdef S_IFDIR - if (IX_FMT(x->st_mode, S_IFDIR)) ostat->st_mode |= ISTAT_IFDIR; - #endif - #ifdef S_IFCHR - if (IX_FMT(x->st_mode, S_IFCHR)) ostat->st_mode |= ISTAT_IFCHR; - #endif - #ifdef S_IFBLK - if (IX_FMT(x->st_mode, S_IFBLK)) ostat->st_mode |= ISTAT_IFBLK; - #endif - #ifdef S_IFREG - if (IX_FMT(x->st_mode, S_IFREG)) ostat->st_mode |= ISTAT_IFREG; - #endif - #ifdef S_IFIFO - if (IX_FMT(x->st_mode, S_IFIFO)) ostat->st_mode |= ISTAT_IFIFO; - #endif - #ifdef S_IFLNK - if (IX_FMT(x->st_mode, S_IFLNK)) ostat->st_mode |= ISTAT_IFLNK; - #endif - #ifdef S_IFSOCK - if (IX_FMT(x->st_mode, S_IFSOCK)) ostat->st_mode |= ISTAT_IFSOCK; - #endif - #ifdef S_IFWHT - if (IX_FMT(x->st_mode, S_IFWHT)) ostat->st_mode |= ISTAT_IFWHT; - #endif - -#ifdef S_IREAD - if (x->st_mode & S_IREAD) ostat->st_mode |= ISTAT_IRUSR; -#endif - -#ifdef S_IWRITE - if (x->st_mode & S_IWRITE) ostat->st_mode |= ISTAT_IWUSR; -#endif - -#ifdef S_IEXEC - if (x->st_mode & S_IEXEC) ostat->st_mode |= ISTAT_IXUSR; -#endif - -#ifdef S_IRUSR - if (x->st_mode & S_IRUSR) ostat->st_mode |= ISTAT_IRUSR; - if (x->st_mode & S_IWUSR) ostat->st_mode |= ISTAT_IWUSR; - if (x->st_mode & S_IXUSR) ostat->st_mode |= ISTAT_IXUSR; -#endif - -#ifdef S_IRGRP - if (x->st_mode & S_IRGRP) ostat->st_mode |= ISTAT_IRGRP; - if (x->st_mode & S_IWGRP) ostat->st_mode |= ISTAT_IWGRP; - if (x->st_mode & S_IXGRP) ostat->st_mode |= ISTAT_IXGRP; -#endif - -#ifdef S_IROTH - if (x->st_mode & S_IROTH) ostat->st_mode |= ISTAT_IROTH; - if (x->st_mode & S_IWOTH) ostat->st_mode |= ISTAT_IWOTH; - if (x->st_mode & S_IXOTH) ostat->st_mode |= ISTAT_IXOTH; -#endif - - ostat->st_size = (IUINT64)x->st_size; - - ostat->atime = (IUINT32)x->st_atime; - ostat->mtime = (IUINT32)x->st_mtime; - ostat->ctime = (IUINT32)x->st_mtime; - - ostat->st_ino = (IUINT64)x->st_ino; - ostat->st_dev = (IUINT32)x->st_dev; - ostat->st_nlink = (IUINT32)x->st_nlink; - ostat->st_uid = (IUINT32)x->st_uid; - ostat->st_gid = (IUINT32)x->st_gid; - ostat->st_rdev = (IUINT32)x->st_rdev; - -#ifdef __unix -// #define IHAVE_STAT_ST_BLKSIZE -// #define IHAVE_STAT_ST_BLOCKS -// #define IHAVE_STAT_ST_FLAGS -#endif - -#if defined(__unix) - #ifdef IHAVE_STAT_ST_BLOCKS - ostat->st_blocks = (IUINT32)x->st_blocks; - #endif - #ifdef IHAVE_STAT_ST_BLKSIZE - ostat->st_blksize = (IUINT32)x->st_blksize; - #endif - #if !defined(__CYGWIN__) && defined(IHAVE_STAT_ST_FLAGS) - ostat->st_flags = (IUINT32)x->st_flags; - #endif -#endif -} - -// returns 0 for success, -1 for error -int iposix_stat_imp(const char *path, iposix_stat_t *ostat) -{ - iposix_ostat_t xstat; - int retval; - retval = iposix_stat_proc(path, &xstat); - if (retval != 0) return -1; - iposix_stat_convert(ostat, &xstat); - return 0; -} - -// returns 0 for success, -1 for error -int iposix_lstat_imp(const char *path, iposix_stat_t *ostat) -{ - iposix_ostat_t xstat; - int retval; - retval = iposix_lstat_proc(path, &xstat); - if (retval != 0) return -1; - iposix_stat_convert(ostat, &xstat); - return 0; -} - -// returns 0 for success, -1 for error -int iposix_fstat(int fd, iposix_stat_t *ostat) -{ - iposix_ostat_t xstat; - int retval; - retval = iposix_fstat_proc(fd, &xstat); - if (retval != 0) return -1; - iposix_stat_convert(ostat, &xstat); - return 0; -} - -// normalize stat path -static void iposix_path_stat(const char *src, char *dst) -{ - int size = (int)strlen(src); - if (size > IPOSIX_MAXPATH) size = IPOSIX_MAXPATH; - memcpy(dst, src, size + 1); - if (size > 1) { - int trim = 1; - if (size == 3) { - if (isalpha((int)dst[0]) && dst[1] == ':' && - (dst[2] == '/' || dst[2] == '\\')) trim = 0; - } - if (size == 1) { - if (dst[0] == '/' || dst[0] == '\\') trim = 0; - } - if (trim) { - if (dst[size - 1] == '/' || dst[size - 1] == '\\') { - dst[size - 1] = 0; - size--; - } - } - } -} - - -// returns 0 for success, -1 for error -int iposix_stat(const char *path, iposix_stat_t *ostat) -{ - char buf[IPOSIX_MAXBUFF]; - iposix_path_stat(path, buf); - return iposix_stat_imp(buf, ostat); -} - -// returns 0 for success, -1 for error -int iposix_lstat(const char *path, iposix_stat_t *ostat) -{ - char buf[IPOSIX_MAXBUFF]; - iposix_path_stat(path, buf); - return iposix_lstat_imp(buf, ostat); -} - -// get current directory -char *iposix_getcwd(char *path, int size) -{ -#ifdef _WIN32 - return _getcwd(path, size); -#else - return getcwd(path, size); -#endif -} - -// create directory -int iposix_mkdir(const char *path, int mode) -{ -#ifdef _WIN32 - return _mkdir(path); -#else - if (mode < 0) mode = 0755; - return mkdir(path, mode); -#endif -} - -// change directory -int iposix_chdir(const char *path) -{ -#ifdef _WIN32 - return _chdir(path); -#else - return chdir(path); -#endif -} - -// check access -int iposix_access(const char *path, int mode) -{ -#ifdef _WIN32 - return _access(path, mode); -#else - return access(path, mode); -#endif -} - -// returns 1 for true 0 for false, -1 for not exist -int iposix_path_isdir(const char *path) -{ - iposix_stat_t s; - int hr = iposix_stat(path, &s); - if (hr != 0) return -1; - return (ISTAT_ISDIR(s.st_mode))? 1 : 0; -} - -// returns 1 for true 0 for false, -1 for not exist -int iposix_path_isfile(const char *path) -{ - iposix_stat_t s; - int hr = iposix_stat(path, &s); - if (hr != 0) return -1; - return (ISTAT_ISDIR(s.st_mode))? 0 : 1; -} - -// returns 1 for true 0 for false, -1 for not exist -int iposix_path_islink(const char *path) -{ - iposix_stat_t s; - int hr = iposix_stat(path, &s); - if (hr != 0) return -1; - return (ISTAT_ISLNK(s.st_mode))? 1 : 0; -} - -// returns 1 for true 0 for false -int iposix_path_exists(const char *path) -{ - iposix_stat_t s; - int hr = iposix_stat(path, &s); - if (hr != 0) return 0; - return 1; -} - -// returns file size, -1 for error -IINT64 iposix_path_getsize(const char *path) -{ - iposix_stat_t s; - int hr = iposix_stat(path, &s); - if (hr != 0) return -1; - return (IINT64)s.st_size; -} - - -//--------------------------------------------------------------------- -// Posix Path -//--------------------------------------------------------------------- - -// 是否是绝对路径,如果是的话返回1,否则返回0 -int iposix_path_isabs(const char *path) -{ - if (path == NULL) return 0; - if (path[0] == '/') return 1; - if (path[0] == 0) return 0; -#ifdef _WIN32 - if (path[0] == IPATHSEP) return 1; - if (isalpha(path[0]) && path[1] == ':') { - if (path[2] == '/' || path[2] == '\\') return 1; - } -#endif - return 0; -} - - - -//--------------------------------------------------------------------- -// iposix_string_t - basic string definition -//--------------------------------------------------------------------- -typedef struct -{ - char *p; - int l; - int m; -} iposix_string_t; - - -//--------------------------------------------------------------------- -// iposix_string_t interface -//--------------------------------------------------------------------- -#define _istrlen(s) ((s)->l) -#define _istrch(s, i) (((i) >= 0)? ((s)->p)[i] : ((s)->p)[(s)->l + (i)]) - -static char *_istrset(iposix_string_t *s, const char *p, int max) -{ - assert((max > 0) && p && s); - s->p = (char*)p; - s->l = strlen(p); - s->m = max; - return (char*)p; -} - -static char *_istrcat(iposix_string_t *s, const char *p) -{ - char *p1; - - assert(s && p); - for (p1 = (char*)p; p1[0]; p1++, s->l++) { - if (s->l >= s->m) break; - s->p[s->l] = p1[0]; - } - return s->p; -} - -static char *_istrcpy(iposix_string_t *s, const char *p) -{ - assert(s && p); - s->l = 0; - return _istrcat(s, p); -} - -static char *_istrcats(iposix_string_t *s1, const iposix_string_t *s2) -{ - int i; - assert(s1 && s2); - for (i = 0; i < s2->l; i++, s1->l++) { - if (s1->l >= s1->m) break; - s1->p[s1->l] = s2->p[i]; - } - return s1->p; -} - -static char *_icstr(iposix_string_t *s) -{ - assert(s); - if (s->l >= s->m) s->l = s->m - 1; - if (s->l < 0) s->l = 0; - s->p[s->l] = 0; - return s->p; -} - -static char _istrc(const iposix_string_t *s, int pos) -{ - if (pos >= 0) return (pos > s->l)? 0 : s->p[pos]; - return (pos < -(s->l))? 0 : s->p[s->l + pos]; -} - -static char _istrchop(iposix_string_t *s) -{ - char ch = _istrc(s, -1); - s->l--; - if (s->l < 0) s->l = 0; - return ch; -} - -static char *_istrctok(iposix_string_t *s, const char *p) -{ - int i, k; - - assert(s && p); - - for (; _istrlen(s) > 0; ) { - for (i = 0, k = 0; p[i] && k == 0; i++) { - if (_istrc(s, -1) == p[i]) k++; - } - if (k == 0) break; - _istrchop(s); - } - for (; _istrlen(s) > 0; ) { - for (i = 0, k = 0; p[i] && k == 0; i++) { - if (_istrc(s, -1) == p[i]) k++; - } - if (k) break; - _istrchop(s); - } - - return s->p; -} - -static int _istrcmp(iposix_string_t *s, const char *p) -{ - int i; - for (i = 0; i < s->l && ((char*)p)[i]; i++) - if (_istrc(s, i) != ((char*)p)[i]) break; - if (((char*)p)[i] == 0 && i == s->l) return 0; - return 1; -} - -static char *_istrcatc(iposix_string_t *s, char ch) -{ - char text[2] = " "; - assert(s); - text[0] = ch; - return _istrcat(s, text); -} - -static int istrtok(const char *p1, int *pos, const char *p2) -{ - int i, j, k, r; - - assert(p1 && pos && p2); - - for (i = *pos; p1[i]; i++) { - for (j = 0, k = 0; p2[j] && k == 0; j++) { - if (p1[i] == p2[j]) k++; - } - if (k == 0) break; - } - *pos = i; - r = i; - - if (p1[i] == 0) return -1; - for (; p1[i]; i++) { - for (j = 0, k = 0; p2[j] && k == 0; j++) { - if (p1[i] == p2[j]) k++; - } - if (k) break; - } - *pos = i; - - return r; -} - - -//--------------------------------------------------------------------- -// normalize path -//--------------------------------------------------------------------- -char *iposix_path_normal(const char *srcpath, char *path, int maxsize) -{ - int i, p, c, k, r; - iposix_string_t s1, s2; - char *p1, *p2; - char pp2[3]; - - assert(srcpath && path && maxsize > 0); - - if (srcpath[0] == 0) { - if (maxsize > 0) path[0] = 0; - return path; - } - - for (p1 = (char*)srcpath; p1[0] && isspace((int)p1[0]); p1++); - - path[0] = 0; - _istrset(&s1, path, maxsize); - - if (IPATHSEP == '\\') { - pp2[0] = '/'; - pp2[1] = '\\'; - pp2[2] = 0; - } else { - pp2[0] = '/'; - pp2[1] = 0; - } - - p2 = pp2; - - if (p1[0] && p1[1] == ':' && (ISYSNAME == 'u' || ISYSNAME == 'w')) { - _istrcatc(&s1, *p1++); - _istrcatc(&s1, *p1++); - } - - if (IPATHSEP == '/') { - if (p1[0] == '/') _istrcatc(&s1, *p1++); - } - else if (p1[0] == '/' || p1[0] == IPATHSEP) { - _istrcatc(&s1, IPATHSEP); - p1++; - } - - r = (_istrc(&s1, -1) == IPATHSEP)? 1 : 0; - srcpath = (const char*)p1; - - for (i = 0, c = 0, k = 0; (p = istrtok(srcpath, &i, p2)) >= 0; k++) { - s2.p = (char*)(srcpath + p); - s2.l = s2.m = i - p; - //_iputs(&s2); printf("*\n"); - if (_istrcmp(&s2, ".") == 0) continue; - if (_istrcmp(&s2, "..") == 0) { - if (c != 0) { - _istrctok(&s1, (IPATHSEP == '\\')? "/\\:" : "/"); - c--; - continue; - } - if (c == 0 && r) { - continue; - } - } else { - c++; - } - _istrcats(&s1, &s2); - _istrcatc(&s1, IPATHSEP); - } - if (_istrlen(&s1) == 0) { - _istrcpy(&s1, "."); - } else { - if (_istrc(&s1, -1) == IPATHSEP && c > 0) _istrchop(&s1); - } - return _icstr(&s1); -} - - -//--------------------------------------------------------------------- -// join path -//--------------------------------------------------------------------- -char *iposix_path_join(const char *p1, const char *p2, char *path, int len) -{ - iposix_string_t s; - int maxsize = len; - char *p, r; - - assert(p1 && p2 && maxsize > 0); - - for (; p1[0] && isspace((int)p1[0]); p1++); - for (; p2[0] && isspace((int)p2[0]); p2++); - r = 0; - p = (char*)p2; - if (IPATHSEP == '/') { - if (p[0] == '/') r = 1; - } else { - if (p[0] == '/' || p[0] == IPATHSEP) r = 1; - } - - if (p[0] && p[1] == ':' && (ISYSNAME == 'u' || ISYSNAME == 'w')) - return iposix_path_normal(p2, path, maxsize); - - if (r && (p1[0] == 0 || p1[1] != ':' || p1[2])) - return iposix_path_normal(p2, path, maxsize); - - p = (char*)malloc(maxsize + 10); - - if (p == NULL) { - return iposix_path_normal(p1, path, maxsize); - } - - iposix_path_normal(p1, p, maxsize); - _istrset(&s, p, maxsize); - - r = 1; - if (_istrlen(&s) <= 2 && _istrc(&s, 1) == ':') r = 0; - if (_istrc(&s, -1) == IPATHSEP) r = 0; - if (_istrlen(&s) == 0) r = 0; - if (r) _istrcatc(&s, IPATHSEP); - - _istrcat(&s, p2); - iposix_path_normal(_icstr(&s), path, maxsize); - free(p); - - return path; -} - - -// 绝对路径 -char *iposix_path_abspath_u(const char *srcpath, char *path, int maxsize) -{ - char *base; - base = (char*)malloc(IPOSIX_MAXBUFF * 2); - if (base == NULL) return NULL; - iposix_getcwd(base, IPOSIX_MAXPATH); - iposix_path_join(base, srcpath, path, maxsize); - free(base); - return path; -} - -#ifdef _WIN32 -char *iposix_path_abspath_w(const char *srcpath, char *path, int maxsize) -{ - char *fname; - DWORD hr = GetFullPathNameA(srcpath, maxsize, path, &fname); - if (hr == 0) return NULL; - return path; -} -#endif - - -// 绝对路径 -char *iposix_path_abspath(const char *srcpath, char *path, int maxsize) -{ -#ifdef _WIN32 - return iposix_path_abspath_w(srcpath, path, maxsize); -#else - return iposix_path_abspath_u(srcpath, path, maxsize); -#endif -} - -// 路径分割:从右向左找到第一个"/"分成两个字符串 -int iposix_path_split(const char *path, char *p1, int l1, char *p2, int l2) -{ - int length, i, k; - length = (int)strlen(path); - - for (i = length - 1; i >= 0; i--) { - if (IPATHSEP == '/') { - if (path[i] == '/') break; - } else { - if (path[i] == '/' || path[i] == '\\') break; - } - } - - if (p1) { - if (i < 0) { - if (l1 > 0) p1[0] = 0; - } - else if (i == 0) { - p1[0] = '/'; - p1[1] = 0; - } - else { - int size = i < l1 ? i : l1; - memcpy(p1, path, size); - if (size < l1) p1[size] = 0; - } - } - - k = length - i - 1; - - if (p2) { - if (k <= 0) { - if (l2 > 0) p2[0] = 0; - } else { - int size = k < l2 ? k : l2; - memcpy(p2, path + i + 1, k); - if (size < l2) p2[size] = 0; - } - } - - return 0; -} - - -// 扩展分割:分割文件主名与扩展名 -int iposix_path_splitext(const char *path, char *p1, int l1, - char *p2, int l2) -{ - int length, i, k, size; - length = (int)strlen(path); - for (i = length - 1, k = length; i >= 0; i--) { - if (path[i] == '.') { - k = i; - break; - } - else if (IPATHSEP == '/') { - if (path[i] == '/') break; - - } - else { - if (path[i] == '/' || path[i] == '\\') break; - } - } - - if (p1) { - - size = k < l1 ? k : l1; - if (size > 0) memcpy(p1, path, size); - if (size < l1) p1[size] = 0; - } - - size = length - k - 1; - if (size < 0) size = 0; - size = size < l2 ? size : l2; - - if (p2) { - if (size > 0) memcpy(p2, path + k + 1, size); - if (size < l2) p2[size] = 0; - } - - return 0; -} - - -//--------------------------------------------------------------------- -// platform special -//--------------------------------------------------------------------- - -// cross os GetModuleFileName, returns size for success, -1 for error -int iposix_path_exepath(char *ptr, int size) -{ - int retval = -1; -#if defined(_WIN32) - DWORD hr = GetModuleFileNameA(NULL, ptr, (DWORD)size); - if (hr > 0) retval = (int)hr; -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) - int mib[4]; - size_t cb = (size_t)size; - int hr; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PATHNAME; - mib[3] = -1; - hr = sysctl(mib, 4, ptr, &cb, NULL, 0); - if (hr >= 0) retval = (int)cb; -#elif defined(linux) || defined(__CYGWIN__) - FILE *fp; - fp = fopen("/proc/self/exename", "r"); - if (fp) { - retval = fread(ptr, 1, size, fp); - fclose(fp); - } else { - retval = 0; - } -#else -#endif - if (retval >= 0 && retval < size) { - ptr[retval] = '\0'; - } else if (size > 0) { - ptr[0] = '\0'; - } - - if (size > 0) ptr[size - 1] = 0; - - return retval; -} - -// 取得进程可执行文件的目录 -int iposix_path_execwd(char *ptr, int size) -{ - char *buffer; - int retval; - - if (ptr) { - if (size > 0) ptr[0] = 0; - } - - buffer = (char*)malloc(IPOSIX_MAXBUFF * 2); - if (buffer == NULL) { - return -1; - } - - retval = iposix_path_exepath(buffer, IPOSIX_MAXBUFF * 2); - - if (retval < 0) { - free(buffer); - return -2; - } - - iposix_path_split(buffer, ptr, size, NULL, IPOSIX_MAXPATH); - - free(buffer); - - return 0; -} - - -// 递归创建路径:直接从 ilog移植过来 -int iposix_path_mkdir(const char *path, int mode) -{ - int i, len; - char str[IPOSIX_MAXBUFF]; - - len = (int)strlen(path); - if (len > IPOSIX_MAXPATH) len = IPOSIX_MAXPATH; - - memcpy(str, path, len); - str[len] = 0; - -#ifdef _WIN32 - for (i = 0; i < len; i++) { - if (str[i] == '/') str[i] = '\\'; - } -#endif - - for (i = 0; i < len; i++) { - if (str[i] == '/' || str[i] == '\\') { - str[i] = '\0'; - if (iposix_access(str, F_OK) != 0) { - iposix_mkdir(str, mode); - } - str[i] = IPATHSEP; - } - } - - if (len > 0 && iposix_access(str, 0) != 0) { - iposix_mkdir(str, mode); - } - - return 0; -} - - -// 精简版取得可执行路径 -const char *iposix_get_exepath(void) -{ - static int inited = 0; - static char *ptr = NULL; - if (inited == 0) { - char *buffer = (char*)malloc(IPOSIX_MAXBUFF); - char *b2; - int size; - if (buffer == NULL) { - inited = -1; - return ""; - } - if (iposix_path_exepath(buffer, IPOSIX_MAXPATH) != 0) { - free(buffer); - inited = -1; - return ""; - } - size = (int)strlen(buffer); - b2 = (char*)malloc(size + 1); - if (b2 == NULL) { - free(buffer); - inited = -1; - return ""; - } - memcpy(b2, buffer, size + 1); - free(buffer); - ptr = b2; - inited = 1; - } - if (inited < 0) return ""; - return ptr; -} - -// 精简版取得可执行目录 -const char *iposix_get_execwd(void) -{ - static int inited = 0; - static char ptr[IPOSIX_MAXBUFF + 10]; - if (inited == 0) { - if (iposix_path_execwd(ptr, IPOSIX_MAXPATH) != 0) { - inited = -1; - return ""; - } - inited = 1; - } - if (inited < 0) return ""; - return ptr; -} - -#ifdef _MSC_VER -#pragma warning(disable:4996) -#endif - -// 文件路径格式化: -// out - 输出路径,长度不小于 IPOSIX_MAXPATH -// base - 根路径 -// ... - 后续的相对路径 -// 返回 - out -// 假设可执行路径位于 /home/abc/work,那么: -// iposix_path_format(out, iposix_get_execwd(), "images/%s", "abc.jpg") -// 结果就是 /home/abc/work/images/abc.jpg -char *iposix_path_format(char *out, const char *root, const char *fmt, ...) -{ - char buffer[IPOSIX_MAXBUFF]; - va_list argptr; - va_start(argptr, fmt); - vsprintf(buffer, fmt, argptr); - va_end(argptr); - return iposix_path_join(root, buffer, out, IPOSIX_MAXPATH); -} - - - -/*-------------------------------------------------------------------*/ -/* System Utilities */ -/*-------------------------------------------------------------------*/ -#ifndef IDISABLE_SHARED_LIBRARY - #if defined(__unix) - #include - #endif -#endif - -void *iposix_shared_open(const char *dllname) -{ -#ifndef IDISABLE_SHARED_LIBRARY - #ifdef __unix - return dlopen(dllname, RTLD_LAZY); - #else - return (void*)LoadLibraryA(dllname); - #endif -#else - return NULL; -#endif -} - -void *iposix_shared_get(void *shared, const char *name) -{ -#ifndef IDISABLE_SHARED_LIBRARY - #ifdef __unix - return dlsym(shared, name); - #else - return (void*)GetProcAddress((HINSTANCE)shared, name); - #endif -#else - return NULL; -#endif -} - -void iposix_shared_close(void *shared) -{ -#ifndef IDISABLE_SHARED_LIBRARY - #ifdef __unix - dlclose(shared); - #else - FreeLibrary((HINSTANCE)shared); - #endif -#endif -} - -/* load file content */ -void *iposix_file_load_content(const char *filename, long *size) -{ - size_t length, remain; - char *ptr, *out; - FILE *fp; - - if ((fp = fopen(filename, "rb")) == NULL) { - if (size) size[0] = 0; - return NULL; - } - - fseek(fp, 0, SEEK_END); - length = ftell(fp); - fseek(fp, 0, SEEK_SET); - - // avoid zero-size file returns null - ptr = (char*)malloc(length + 8); - - if (ptr == NULL) { - fclose(fp); - if (size) size[0] = 0; - return NULL; - } - - for (remain = length, out = ptr; remain > 0; ) { - size_t ret = fread(out, 1, remain, fp); - if (ret == 0) break; - remain -= ret; - out += ret; - } - - fclose(fp); - - if (size) size[0] = length; - - return ptr; -} - - -/* save file content */ -int iposix_file_save_content(const char *filename, const void *data, long size) -{ - const char *ptr = (const char*)data; - FILE *fp; - int hr = 0; - if ((fp = fopen(filename, "wb")) == NULL) return -1; - for (; size > 0; ) { - long written = (long)fwrite(ptr, 1, size, fp); - if (written <= 0) { - hr = -2; - break; - } - size -= written; - ptr += written; - } - fclose(fp); - return hr; -} - - - -#endif - - - - diff --git a/czmod/iposix.h b/czmod/iposix.h deleted file mode 100644 index 0d0f605..0000000 --- a/czmod/iposix.h +++ /dev/null @@ -1,401 +0,0 @@ -//===================================================================== -// -// iposix.h - posix file system accessing -// -// NOTE: -// for more information, please see the readme file. -// -//===================================================================== -#ifndef __IPOSIX_H__ -#define __IPOSIX_H__ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - - -/*-------------------------------------------------------------------*/ -/* C99 Compatible */ -/*-------------------------------------------------------------------*/ -#if defined(linux) || defined(__linux) || defined(__linux__) -#ifdef _POSIX_C_SOURCE -#if _POSIX_C_SOURCE < 200112L -#undef _POSIX_C_SOURCE -#endif -#endif - -#ifndef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 200112L -#endif - -#ifdef _GNU_SOURCE -#undef _GNU_SOURCE -#endif - -#ifdef _BSD_SOURCE -#undef _BSD_SOURCE -#endif - -#ifdef __BSD_VISIBLE -#undef __BSD_VISIBLE -#endif - -#ifdef _XOPEN_SOURCE -#undef _XOPEN_SOURCE -#endif - -#define _GNU_SOURCE 1 -#define _BSD_SOURCE 1 -#define __BSD_VISIBLE 1 -#define _XOPEN_SOURCE 600 -#endif - - -#ifndef IDISABLE_FILE_SYSTEM_ACCESS -//--------------------------------------------------------------------- -// Global Definition -//--------------------------------------------------------------------- -#ifndef __INTEGER_32_BITS__ -#define __INTEGER_32_BITS__ -#if defined(__UINT32_TYPE__) && defined(__UINT32_TYPE__) - typedef __UINT32_TYPE__ ISTDUINT32; - typedef __INT32_TYPE__ ISTDINT32; -#elif defined(__UINT_FAST32_TYPE__) && defined(__INT_FAST32_TYPE__) - typedef __UINT_FAST32_TYPE__ ISTDUINT32; - typedef __INT_FAST32_TYPE__ ISTDINT32; -#elif defined(_WIN64) || defined(WIN64) || defined(__amd64__) || \ - defined(__x86_64) || defined(__x86_64__) || defined(_M_IA64) || \ - defined(_M_AMD64) - typedef unsigned int ISTDUINT32; - typedef int ISTDINT32; -#elif defined(_WIN32) || defined(WIN32) || defined(__i386__) || \ - defined(__i386) || defined(_M_X86) - typedef unsigned long ISTDUINT32; - typedef long ISTDINT32; -#elif defined(__MACOS__) - typedef UInt32 ISTDUINT32; - typedef SInt32 ISTDINT32; -#elif defined(__APPLE__) && defined(__MACH__) - #include - typedef u_int32_t ISTDUINT32; - typedef int32_t ISTDINT32; -#elif defined(__BEOS__) - #include - typedef u_int32_t ISTDUINT32; - typedef int32_t ISTDINT32; -#elif (defined(_MSC_VER) || defined(__BORLANDC__)) && (!defined(__MSDOS__)) - typedef unsigned __int32 ISTDUINT32; - typedef __int32 ISTDINT32; -#elif defined(__GNUC__) && (__GNUC__ > 3) - #include - typedef uint32_t ISTDUINT32; - typedef int32_t ISTDINT32; -#else - typedef unsigned long ISTDUINT32; - typedef long ISTDINT32; -#endif -#endif - - -#if (defined(__APPLE__) && defined(__MACH__)) || defined(__MACOS__) -#ifndef __unix -#define __unix 1 -#endif -#endif - -#if defined(__unix__) || defined(unix) || defined(__linux) -#ifndef __unix -#define __unix 1 -#endif -#endif - -#include -#ifdef __unix -#include -#define IPATHSEP '/' -#else -#include -#if defined(_WIN32) -#define IPATHSEP '\\' -#else -#define IPATHSEP '/' -#endif -#endif - - -#ifndef __IINT8_DEFINED -#define __IINT8_DEFINED -typedef char IINT8; -#endif - -#ifndef __IUINT8_DEFINED -#define __IUINT8_DEFINED -typedef unsigned char IUINT8; -#endif - -#ifndef __IUINT16_DEFINED -#define __IUINT16_DEFINED -typedef unsigned short IUINT16; -#endif - -#ifndef __IINT16_DEFINED -#define __IINT16_DEFINED -typedef short IINT16; -#endif - -#ifndef __IINT32_DEFINED -#define __IINT32_DEFINED -typedef ISTDINT32 IINT32; -#endif - -#ifndef __IUINT32_DEFINED -#define __IUINT32_DEFINED -typedef ISTDUINT32 IUINT32; -#endif - -#ifndef __IINT64_DEFINED -#define __IINT64_DEFINED -#if defined(_MSC_VER) || defined(__BORLANDC__) -typedef __int64 IINT64; -#else -typedef long long IINT64; -#endif -#endif - -#ifndef __IUINT64_DEFINED -#define __IUINT64_DEFINED -#if defined(_MSC_VER) || defined(__BORLANDC__) -typedef unsigned __int64 IUINT64; -#else -typedef unsigned long long IUINT64; -#endif -#endif - -#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) - #ifndef _WIN32 - #define _WIN32 - #endif -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - -//--------------------------------------------------------------------- -// Posix Stat -//--------------------------------------------------------------------- -#define ISTAT_IFMT 0170000 // file type mask -#define ISTAT_IFIFO 0010000 // named pipe (fifo) -#define ISTAT_IFCHR 0020000 // charactor special -#define ISTAT_IFDIR 0040000 // directory -#define ISTAT_IFBLK 0060000 // block special -#define ISTAT_IFREG 0100000 // regular -#define ISTAT_IFLNK 0120000 // symbolic link -#define ISTAT_IFSOCK 0140000 // socket -#define ISTAT_IFWHT 0160000 // whiteout -#define ISTAT_ISUID 0004000 // set user id on execution -#define ISTAT_ISGID 0002000 // set group id on execution -#define ISTAT_ISVXT 0001000 // swapped text even after use -#define ISTAT_IRWXU 0000700 // owner RWX mask -#define ISTAT_IRUSR 0000400 // owner read permission -#define ISTAT_IWUSR 0000200 // owner writer permission -#define ISTAT_IXUSR 0000100 // owner execution permission -#define ISTAT_IRWXG 0000070 // group RWX mask -#define ISTAT_IRGRP 0000040 // group read permission -#define ISTAT_IWGRP 0000020 // group write permission -#define ISTAT_IXGRP 0000010 // group execution permission -#define ISTAT_IRWXO 0000007 // other RWX mask -#define ISTAT_IROTH 0000004 // other read permission -#define ISTAT_IWOTH 0000002 // other writer permission -#define ISTAT_IXOTH 0000001 // other execution permission - -#define ISTAT_ISFMT(m, t) (((m) & ISTAT_IFMT) == (t)) -#define ISTAT_ISDIR(m) ISTAT_ISFMT(m, ISTAT_IFDIR) -#define ISTAT_ISCHR(m) ISTAT_ISFMT(m, ISTAT_IFCHR) -#define ISTAT_ISBLK(m) ISTAT_ISFMT(m, ISTAT_IFBLK) -#define ISTAT_ISREG(m) ISTAT_ISFMT(m, ISTAT_IFREG) -#define ISTAT_ISFIFO(m) ISTAT_ISFMT(m, ISTAT_IFIFO) -#define ISTAT_ISLNK(m) ISTAT_ISFMT(m, ISTAT_IFLNK) -#define ISTAT_ISSOCK(m) ISTAT_ISFMT(m, ISTAT_IFSOCK) -#define ISTAT_ISWHT(m) ISTAT_ISFMT(m, ISTAT_IFWHT) - -struct IPOSIX_STAT -{ - IUINT32 st_mode; - IUINT64 st_ino; - IUINT32 st_dev; - IUINT32 st_nlink; - IUINT32 st_uid; - IUINT32 st_gid; - IUINT64 st_size; - IUINT32 atime; - IUINT32 mtime; - IUINT32 ctime; - IUINT32 st_blocks; - IUINT32 st_blksize; - IUINT32 st_rdev; - IUINT32 st_flags; -}; - -typedef struct IPOSIX_STAT iposix_stat_t; - -#define IPOSIX_MAXPATH 1024 -#define IPOSIX_MAXBUFF ((IPOSIX_MAXPATH) + 8) - - -// returns 0 for success, -1 for error -int iposix_stat(const char *path, iposix_stat_t *ostat); - -// returns 0 for success, -1 for error -int iposix_lstat(const char *path, iposix_stat_t *ostat); - -// returns 0 for success, -1 for error -int iposix_fstat(int fd, iposix_stat_t *ostat); - -// get current directory -char *iposix_getcwd(char *path, int size); - -// create directory -int iposix_mkdir(const char *path, int mode); - -// change directory -int iposix_chdir(const char *path); - -#ifndef F_OK -#define F_OK 0 -#endif - -#ifndef X_OK -#define X_OK 1 -#endif - -#ifndef W_OK -#define W_OK 2 -#endif - -#ifndef R_OK -#define R_OK 4 -#endif - -// check access -int iposix_access(const char *path, int mode); - - -// returns 1 for true 0 for false, -1 for not exist -int iposix_path_isdir(const char *path); - -// returns 1 for true 0 for false, -1 for not exist -int iposix_path_isfile(const char *path); - -// returns 1 for true 0 for false, -1 for not exist -int iposix_path_islink(const char *path); - -// returns 1 for true 0 for false -int iposix_path_exists(const char *path); - -// returns file size, -1 for error -IINT64 iposix_path_getsize(const char *path); - - -//--------------------------------------------------------------------- -// Posix Path -//--------------------------------------------------------------------- - -// 是否是绝对路径,如果是的话返回1,否则返回0 -int iposix_path_isabs(const char *path); - -// 绝对路径 -char *iposix_path_abspath(const char *srcpath, char *path, int maxsize); - -// 归一化路径:去掉重复斜杠,以及处理掉".", ".."等。 -char *iposix_path_normal(const char *srcpath, char *path, int maxsize); - -// 连接路径 -char *iposix_path_join(const char *p1, const char *p2, char *path, int len); - -// 路径分割:从右向左找到第一个"/"分成两个字符串 -int iposix_path_split(const char *path, char *p1, int l1, char *p2, int l2); - -// 扩展分割:分割文件主名与扩展名 -int iposix_path_splitext(const char *path, char *p1, int l1, - char *p2, int l2); - - -//--------------------------------------------------------------------- -// platform special -//--------------------------------------------------------------------- - -// 取得进程可执行文件的文件名 -int iposix_path_exepath(char *ptr, int size); - -// 取得进程可执行文件的目录 -int iposix_path_execwd(char *ptr, int size); - -// 递归创建路径 -int iposix_path_mkdir(const char *path, int mode); - -// 精简版取得可执行路径 -const char *iposix_get_exepath(void); - -// 精简版取得可执行目录 -const char *iposix_get_execwd(void); - - -// 文件路径格式化: -// out - 输出路径,长度不小于 IPOSIX_MAXPATH -// root - 根路径 -// ... - 后续的相对路径 -// 返回 - out -// 假设可执行路径位于 /home/abc/work,那么: -// iposix_path_format(out, iposix_get_execwd(), "images/%s", "abc.jpg") -// 结果就是 /home/abc/work/images/abc.jpg -char *iposix_path_format(char *out, const char *root, const char *fmt, ...); - - - -//--------------------------------------------------------------------- -// System Utilities -//--------------------------------------------------------------------- - -#ifndef IDISABLE_SHARED_LIBRARY - -/* LoadLibraryA */ -void *iposix_shared_open(const char *dllname); - -/* GetProcAddress */ -void *iposix_shared_get(void *shared, const char *name); - -/* FreeLibrary */ -void iposix_shared_close(void *shared); - -#endif - -#ifndef IDISABLE_FILE_SYSTEM_ACCESS - -/* load file content, use free to dispose */ -void *iposix_file_load_content(const char *filename, long *size); - -/* save file content */ -int iposix_file_save_content(const char *filename, const void *data, long size); - -/* cross os GetModuleFileName, returns size for success, -1 for error */ -int iposix_get_proc_pathname(char *ptr, int size); - -#endif - - - -#ifdef __cplusplus -} -#endif - - -#endif - - -#endif - - - -