303 lines
6.8 KiB
C
Raw Normal View History

#include "memory.h"
#include <string.h>
#include <ctype.h>
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
}