#include "precompile.h" #include "memutil.h" #include "shm_mem.h" #include #include /*for _strdup*/ //TODO: the returned new buffer may has dirty data. TOOLKIT_API void *buffer_resize(void* old, int elemsize, int oldcnt, int newcnt) { if (newcnt && oldcnt && elemsize && oldcnt != newcnt) { char *newbuf = (char*)calloc(newcnt, elemsize); if (newbuf) { if (old) memcpy(newbuf, old, elemsize*oldcnt); if (newcnt > oldcnt) { memset(newbuf+elemsize*oldcnt, 0, elemsize*(newcnt-oldcnt)); } if (old) free(old); return newbuf; } } return old; } //TODO: the returned new buffer may has dirty data. TOOLKIT_API void *shm_buffer_resize(void* old, int elemsize, int oldcnt, int newcnt) { if (newcnt && oldcnt && elemsize && oldcnt != newcnt) { char *newbuf = (char*)shm_malloc(newcnt*elemsize); if (newbuf) { if (old) memcpy(newbuf, old, elemsize*oldcnt); if (newcnt > oldcnt) { memset(newbuf+elemsize*oldcnt, 0, elemsize*(newcnt-oldcnt)); } if (old) shm_free(old); return newbuf; } } return old; } /*what if elemsize*cnt > new_cap's length.*/ TOOLKIT_API int array_check_expand(void **old, int elemsize, int cnt, int *capacity) { if (cnt >= *capacity) { int new_cap = *capacity * 2 + 1; char *newbuf = (char*)calloc(new_cap, elemsize); if (newbuf) { if (*old) { memcpy(newbuf, *old, elemsize*cnt); free(*old); } *old = newbuf; *capacity = new_cap; return 0; } else { return -1; } } else { return 0; /* no need expand */ } } TOOLKIT_API int shm_array_check_expand(void **old, int elemsize, int cnt, int *capacity) { if (cnt >= *capacity) { int new_cap = *capacity * 2 + 1; char *newbuf = (char*)shm_malloc(new_cap * elemsize); if (newbuf) { if (*old) { memcpy(newbuf, *old, elemsize*cnt); shm_free(*old); } *old = newbuf; *capacity = new_cap; return 0; } else { return -1; } } else { return 0; /* no need expand */ } } TOOLKIT_API void debug_trace(const char *fmt, ...) { int n; va_list arg; va_start(arg, fmt); n = _vscprintf(fmt, arg); if (n > 4096) { char *buf = (char*)malloc(n+2); vsprintf(buf, fmt, arg); buf[n++] = '\n'; buf[n] = 0; OutputDebugStringA(buf); free(buf); } else if (n > 0) { char *buf = (char*)_alloca(n+2); vsprintf(buf, fmt, arg); buf[n++] = '\n'; buf[n] = 0; OutputDebugStringA(buf); } va_end(arg); } ////////////////////////////////////////////////////////////////////////// struct toolkit_allocator_t { toolkit_malloc_func local_malloc; toolkit_realloc_func local_realloc; toolkit_calloc_func local_calloc; toolkit_free_func local_free; }; static tk_allocator_t toolkit_allocator = { malloc, realloc, calloc, free, }; TOOLKIT_API int toolkit_replace_allocator(toolkit_malloc_func malloc_func, toolkit_realloc_func realloc_func, toolkit_calloc_func calloc_func, toolkit_free_func free_func) { if (malloc_func == NULL || realloc_func == NULL || calloc_func == NULL || free_func == NULL) { return -1; } toolkit_allocator.local_malloc = malloc_func; toolkit_allocator.local_realloc = realloc_func; toolkit_allocator.local_calloc = calloc_func; toolkit_allocator.local_free = free_func; return 0; } TOOLKIT_API void toolkit_free(void *ptr) { int saved_errno; saved_errno = errno; toolkit_allocator.local_free(ptr); errno = saved_errno; } TOOLKIT_API void *toolkit_malloc(size_t size) { if (size > 0) return toolkit_allocator.local_malloc(size); return NULL; } TOOLKIT_API void *toolkit_calloc(size_t num, size_t size) { return toolkit_allocator.local_calloc(num, size); } TOOLKIT_API void* toolkit_realloc(void* ptr, size_t size) { if (size > 0) return toolkit_allocator.local_realloc(ptr, size); toolkit_free(ptr); return NULL; } TOOLKIT_API void *toolkit_zalloc(size_t size) { void *buf = toolkit_malloc(size); if (buf) { memset(buf, 0, size); } return buf; } TOOLKIT_API void *toolkit_zcalloc(size_t num, size_t size) { void *buf = toolkit_calloc(num, size); if (buf) { memset(buf, 0, num * size); } return buf; } TOOLKIT_API char *toolkit_strdup(const char *s) { //return _strdup(s); size_t len = strlen(s) + 1; char* m = toolkit_malloc(len); if (m == NULL) return NULL; return memcpy(m, s, len); } TOOLKIT_API char* toolkit_strndup(const char* s, size_t n) { char* m; size_t len = strlen(s); if (n < len) len = n; m = toolkit_malloc(len + 1); if (m == NULL) return NULL; m[len] = '\0'; return memcpy(m, s, len); } TOOLKIT_API wchar_t *toolkit_wcsdup(const wchar_t *s) { return _wcsdup(s); }