#include "memory.h" #include #include struct memory_pool { void **free_list; size_t block_size; size_t capacity; size_t free_count; mutex_t mutex; }; memory_pool_t *mempool_create(size_t block_size, size_t initial_count) { memory_pool_t *pool = calloc(1, sizeof(memory_pool_t)); if (!pool) return NULL; pool->block_size = block_size; pool->capacity = initial_count; pool->free_count = initial_count; pool->free_list = calloc(initial_count, sizeof(void *)); if (!pool->free_list) { free(pool); return NULL; } for (size_t i = 0; i < initial_count; i++) { pool->free_list[i] = malloc(block_size); if (!pool->free_list[i]) { for (size_t j = 0; j < i; j++) { free(pool->free_list[j]); } free(pool->free_list); free(pool); return NULL; } } pal_mutex_init(&pool->mutex); return pool; } void mempool_destroy(memory_pool_t *pool) { if (!pool) return; pal_mutex_lock(&pool->mutex); for (size_t i = 0; i < pool->free_count; i++) { free(pool->free_list[i]); } free(pool->free_list); pal_mutex_unlock(&pool->mutex); pal_mutex_destroy(&pool->mutex); free(pool); } void *mempool_alloc(memory_pool_t *pool) { if (!pool) return malloc(64); pal_mutex_lock(&pool->mutex); void *ptr; if (pool->free_count > 0) { ptr = pool->free_list[--pool->free_count]; } else { ptr = malloc(pool->block_size); } pal_mutex_unlock(&pool->mutex); return ptr; } void mempool_free(memory_pool_t *pool, void *ptr) { if (!ptr) return; if (!pool) { free(ptr); return; } pal_mutex_lock(&pool->mutex); if (pool->free_count < pool->capacity) { pool->free_list[pool->free_count++] = ptr; } else { void **new_list = realloc(pool->free_list, (pool->capacity * 2) * sizeof(void *)); if (new_list) { pool->free_list = new_list; pool->capacity *= 2; pool->free_list[pool->free_count++] = ptr; } else { free(ptr); } } pal_mutex_unlock(&pool->mutex); } size_t mempool_available(memory_pool_t *pool) { if (!pool) return 0; pal_mutex_lock(&pool->mutex); size_t count = pool->free_count; pal_mutex_unlock(&pool->mutex); return count; } buffer_t *buffer_create(size_t initial_capacity) { buffer_t *buf = calloc(1, sizeof(buffer_t)); if (!buf) return NULL; if (initial_capacity > 0) { buf->data = malloc(initial_capacity); if (!buf->data) { free(buf); return NULL; } buf->capacity = initial_capacity; buf->data[0] = '\0'; } return buf; } void buffer_destroy(buffer_t *buf) { if (!buf) return; free(buf->data); free(buf); } int buffer_reserve(buffer_t *buf, size_t capacity) { if (!buf) return NWEDAV_ERROR; if (buf->capacity >= capacity) return NWEDAV_OK; size_t new_cap = buf->capacity ? buf->capacity : 64; while (new_cap < capacity) { new_cap *= 2; } char *new_data = realloc(buf->data, new_cap); if (!new_data) return NWEDAV_ERROR_MEMORY; buf->data = new_data; buf->capacity = new_cap; return NWEDAV_OK; } int buffer_append(buffer_t *buf, const void *data, size_t len) { if (!buf || !data || len == 0) return NWEDAV_OK; if (buffer_reserve(buf, buf->size + len + 1) != NWEDAV_OK) { return NWEDAV_ERROR_MEMORY; } memcpy(buf->data + buf->size, data, len); buf->size += len; buf->data[buf->size] = '\0'; return NWEDAV_OK; } int buffer_append_str(buffer_t *buf, const char *str) { if (!str) return NWEDAV_OK; return buffer_append(buf, str, strlen(str)); } int buffer_append_fmt(buffer_t *buf, const char *fmt, ...) { if (!buf || !fmt) return NWEDAV_ERROR; va_list ap; va_start(ap, fmt); int needed = vsnprintf(NULL, 0, fmt, ap); va_end(ap); if (needed < 0) return NWEDAV_ERROR; if (buffer_reserve(buf, buf->size + needed + 1) != NWEDAV_OK) { return NWEDAV_ERROR_MEMORY; } va_start(ap, fmt); vsnprintf(buf->data + buf->size, needed + 1, fmt, ap); va_end(ap); buf->size += needed; return NWEDAV_OK; } void buffer_consume(buffer_t *buf, size_t len) { if (!buf || len == 0) return; if (len >= buf->size) { buf->size = 0; if (buf->data) buf->data[0] = '\0'; return; } memmove(buf->data, buf->data + len, buf->size - len); buf->size -= len; buf->data[buf->size] = '\0'; } void buffer_reset(buffer_t *buf) { if (!buf) return; buf->size = 0; if (buf->data) buf->data[0] = '\0'; } char *buffer_detach(buffer_t *buf) { if (!buf) return NULL; char *data = buf->data; buf->data = NULL; buf->size = 0; buf->capacity = 0; return data; } char *str_dup(const char *str) { if (!str) return NULL; size_t len = strlen(str); char *dup = malloc(len + 1); if (dup) { memcpy(dup, str, len + 1); } return dup; } char *str_ndup(const char *str, size_t n) { if (!str) return NULL; size_t len = strlen(str); if (n < len) len = n; char *dup = malloc(len + 1); if (dup) { memcpy(dup, str, len); dup[len] = '\0'; } return dup; } char *str_lower(char *str) { if (!str) return NULL; for (char *p = str; *p; p++) { *p = tolower((unsigned char)*p); } return str; } char *str_upper(char *str) { if (!str) return NULL; for (char *p = str; *p; p++) { *p = toupper((unsigned char)*p); } return str; } char *str_trim(char *str) { if (!str) return NULL; while (isspace((unsigned char)*str)) str++; if (*str == '\0') return str; char *end = str + strlen(str) - 1; while (end > str && isspace((unsigned char)*end)) end--; end[1] = '\0'; return str; } int str_starts_with(const char *str, const char *prefix) { if (!str || !prefix) return 0; size_t prefix_len = strlen(prefix); return strncmp(str, prefix, prefix_len) == 0; } int str_ends_with(const char *str, const char *suffix) { if (!str || !suffix) return 0; size_t str_len = strlen(str); size_t suffix_len = strlen(suffix); if (suffix_len > str_len) return 0; return strcmp(str + str_len - suffix_len, suffix) == 0; } int str_casecmp(const char *a, const char *b) { if (!a && !b) return 0; if (!a) return -1; if (!b) return 1; #ifdef _WIN32 return _stricmp(a, b); #else return strcasecmp(a, b); #endif } int str_ncasecmp(const char *a, const char *b, size_t n) { if (!a && !b) return 0; if (!a) return -1; if (!b) return 1; #ifdef _WIN32 return _strnicmp(a, b, n); #else return strncasecmp(a, b, n); #endif }