memutil.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #include "precompile.h"
  2. #include "memutil.h"
  3. #include "shm_mem.h"
  4. #include <winpr/locale.h>
  5. #include <winpr/string.h> /*for _strdup*/
  6. //TODO: the returned new buffer may has dirty data.
  7. TOOLKIT_API void *buffer_resize(void* old, int elemsize, int oldcnt, int newcnt)
  8. {
  9. if (newcnt && oldcnt && elemsize && oldcnt != newcnt) {
  10. char *newbuf = (char*)calloc(newcnt, elemsize);
  11. if (newbuf) {
  12. if (old)
  13. memcpy(newbuf, old, elemsize*oldcnt);
  14. if (newcnt > oldcnt) {
  15. memset(newbuf+elemsize*oldcnt, 0, elemsize*(newcnt-oldcnt));
  16. }
  17. if (old)
  18. free(old);
  19. return newbuf;
  20. }
  21. }
  22. return old;
  23. }
  24. //TODO: the returned new buffer may has dirty data.
  25. TOOLKIT_API void *shm_buffer_resize(void* old, int elemsize, int oldcnt, int newcnt)
  26. {
  27. if (newcnt && oldcnt && elemsize && oldcnt != newcnt) {
  28. char *newbuf = (char*)shm_malloc(newcnt*elemsize);
  29. if (newbuf) {
  30. if (old)
  31. memcpy(newbuf, old, elemsize*oldcnt);
  32. if (newcnt > oldcnt) {
  33. memset(newbuf+elemsize*oldcnt, 0, elemsize*(newcnt-oldcnt));
  34. }
  35. if (old)
  36. shm_free(old);
  37. return newbuf;
  38. }
  39. }
  40. return old;
  41. }
  42. /*what if elemsize*cnt > new_cap's length.*/
  43. TOOLKIT_API int array_check_expand(void **old, int elemsize, int cnt, int *capacity)
  44. {
  45. if (cnt >= *capacity) {
  46. int new_cap = *capacity * 2 + 1;
  47. char *newbuf = (char*)calloc(new_cap, elemsize);
  48. if (newbuf) {
  49. if (*old) {
  50. memcpy(newbuf, *old, elemsize*cnt);
  51. free(*old);
  52. }
  53. *old = newbuf;
  54. *capacity = new_cap;
  55. return 0;
  56. } else {
  57. return -1;
  58. }
  59. } else {
  60. return 0; /* no need expand */
  61. }
  62. }
  63. TOOLKIT_API int shm_array_check_expand(void **old, int elemsize, int cnt, int *capacity)
  64. {
  65. if (cnt >= *capacity) {
  66. int new_cap = *capacity * 2 + 1;
  67. char *newbuf = (char*)shm_malloc(new_cap * elemsize);
  68. if (newbuf) {
  69. if (*old) {
  70. memcpy(newbuf, *old, elemsize*cnt);
  71. shm_free(*old);
  72. }
  73. *old = newbuf;
  74. *capacity = new_cap;
  75. return 0;
  76. } else {
  77. return -1;
  78. }
  79. } else {
  80. return 0; /* no need expand */
  81. }
  82. }
  83. TOOLKIT_API void debug_trace(const char *fmt, ...)
  84. {
  85. int n;
  86. va_list arg;
  87. va_start(arg, fmt);
  88. n = _vscprintf(fmt, arg);
  89. if (n > 4096) {
  90. char *buf = (char*)malloc(n+2);
  91. vsprintf(buf, fmt, arg);
  92. buf[n++] = '\n';
  93. buf[n] = 0;
  94. OutputDebugStringA(buf);
  95. free(buf);
  96. } else if (n > 0) {
  97. char *buf = (char*)_alloca(n+2);
  98. vsprintf(buf, fmt, arg);
  99. buf[n++] = '\n';
  100. buf[n] = 0;
  101. OutputDebugStringA(buf);
  102. }
  103. va_end(arg);
  104. }
  105. TOOLKIT_API int GetSystemErrorDesc(int error_code, char *buf, int n)
  106. {
  107. //TODO: implement or compatible
  108. DWORD dwRet = FormatMessageA(
  109. FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
  110. NULL,
  111. error_code,
  112. MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
  113. buf,
  114. n,
  115. NULL);
  116. buf[dwRet] = 0;
  117. return (int)dwRet;
  118. }
  119. //////////////////////////////////////////////////////////////////////////
  120. struct toolkit_allocator_t
  121. {
  122. toolkit_malloc_func local_malloc;
  123. toolkit_realloc_func local_realloc;
  124. toolkit_calloc_func local_calloc;
  125. toolkit_free_func local_free;
  126. };
  127. static tk_allocator_t toolkit_allocator = {
  128. malloc,
  129. realloc,
  130. calloc,
  131. free,
  132. };
  133. TOOLKIT_API int toolkit_replace_allocator(toolkit_malloc_func malloc_func,
  134. toolkit_realloc_func realloc_func,
  135. toolkit_calloc_func calloc_func,
  136. toolkit_free_func free_func)
  137. {
  138. if (malloc_func == NULL || realloc_func == NULL ||
  139. calloc_func == NULL || free_func == NULL) {
  140. return -1;
  141. }
  142. toolkit_allocator.local_malloc = malloc_func;
  143. toolkit_allocator.local_realloc = realloc_func;
  144. toolkit_allocator.local_calloc = calloc_func;
  145. toolkit_allocator.local_free = free_func;
  146. return 0;
  147. }
  148. TOOLKIT_API void toolkit_free(void *ptr)
  149. {
  150. int saved_errno;
  151. saved_errno = errno;
  152. toolkit_allocator.local_free(ptr);
  153. errno = saved_errno;
  154. }
  155. TOOLKIT_API void *toolkit_malloc(size_t size)
  156. {
  157. if (size > 0)
  158. return toolkit_allocator.local_malloc(size);
  159. return NULL;
  160. }
  161. TOOLKIT_API void *toolkit_calloc(size_t num, size_t size)
  162. {
  163. return toolkit_allocator.local_calloc(num, size);
  164. }
  165. TOOLKIT_API void* toolkit_realloc(void* ptr, size_t size)
  166. {
  167. if (size > 0)
  168. return toolkit_allocator.local_realloc(ptr, size);
  169. toolkit_free(ptr);
  170. return NULL;
  171. }
  172. TOOLKIT_API void *toolkit_zalloc(size_t size)
  173. {
  174. void *buf = toolkit_malloc(size);
  175. if (buf) {
  176. memset(buf, 0, size);
  177. }
  178. return buf;
  179. }
  180. TOOLKIT_API void *toolkit_zcalloc(size_t num, size_t size)
  181. {
  182. void *buf = toolkit_calloc(num, size);
  183. if (buf) {
  184. memset(buf, 0, num * size);
  185. }
  186. return buf;
  187. }
  188. TOOLKIT_API char *toolkit_strdup(const char *s)
  189. {
  190. //return _strdup(s);
  191. size_t len = strlen(s) + 1;
  192. char* m = toolkit_malloc(len);
  193. if (m == NULL)
  194. return NULL;
  195. return memcpy(m, s, len);
  196. }
  197. TOOLKIT_API char* toolkit_strndup(const char* s, size_t n)
  198. {
  199. char* m;
  200. size_t len = strlen(s);
  201. if (n < len)
  202. len = n;
  203. m = toolkit_malloc(len + 1);
  204. if (m == NULL)
  205. return NULL;
  206. m[len] = '\0';
  207. return memcpy(m, s, len);
  208. }
  209. TOOLKIT_API wchar_t *toolkit_wcsdup(const wchar_t *s)
  210. {
  211. return _wcsdup(s);
  212. }