X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=lib%2Fmemcached_string.c;h=1595ec6108b9f00b69ea3293de0cabeeb847e32f;hb=89453bb8a7c9593c48635165b780918bc277c6c5;hp=47dac67e62b103cb7591b79d5edc069272e84e80;hpb=375ad7d822a4bbc121a79ce7e927385d6be7f754;p=awesomized%2Flibmemcached diff --git a/lib/memcached_string.c b/lib/memcached_string.c index 47dac67e..1595ec61 100644 --- a/lib/memcached_string.c +++ b/lib/memcached_string.c @@ -2,16 +2,26 @@ memcached_return memcached_string_check(memcached_string_st *string, size_t need) { - if (need > (size_t)(string->current_size - (size_t)(string->end - string->string))) + if (need && need > (size_t)(string->current_size - (size_t)(string->end - string->string))) { size_t current_offset= string->end - string->string; char *new_value; - size_t adjust= (need - (size_t)(string->current_size - (size_t)(string->end - string->string))) / string->block_size; + size_t adjust; + size_t new_size; + /* This is the block multiplier. To keep it larger and surive division errors we must round it up */ + adjust= (need - (size_t)(string->current_size - (size_t)(string->end - string->string))) / string->block_size; adjust++; - new_value= (char *)realloc(string->string, - sizeof(char) * ((adjust * string->block_size) + string->current_size)); + new_size= sizeof(char) * (size_t)((adjust * string->block_size) + string->current_size); + /* Test for overflow */ + if (new_size < need) + return MEMCACHED_MEMORY_ALLOCATION_FAILURE; + + if (string->root->call_realloc) + new_value= (char *)string->root->call_realloc(string->root, string->string, new_size); + else + new_value= (char *)realloc(string->string, new_size); if (new_value == NULL) return MEMCACHED_MEMORY_ALLOCATION_FAILURE; @@ -20,46 +30,59 @@ memcached_return memcached_string_check(memcached_string_st *string, size_t need string->end= string->string + current_offset; string->current_size+= (string->block_size * adjust); - - /* We zero the block structure we just realloced */ - memset((string->string + current_offset), 0, - sizeof(char) * string->block_size); } return MEMCACHED_SUCCESS; } -memcached_string_st *memcached_string_create(memcached_st *ptr, size_t initial_size) +memcached_string_st *memcached_string_create(memcached_st *ptr, memcached_string_st *string, size_t initial_size) { memcached_return rc; - memcached_string_st *string; /* Saving malloc calls :) */ - string= (memcached_string_st *)malloc(sizeof(memcached_string_st)); - if (!string) - return NULL; - string->end= string->string; - memset(string, 0, sizeof(memcached_string_st)); - string->block_size= initial_size; + if (string) + { + memset(string, 0, sizeof(memcached_string_st)); + string->is_allocated= MEMCACHED_NOT_ALLOCATED; + } + else + { + if (ptr->call_malloc) + string= (memcached_string_st *)ptr->call_malloc(ptr, sizeof(memcached_string_st)); + else + string= (memcached_string_st *)malloc(sizeof(memcached_string_st)); + + if (string == NULL) + return NULL; + memset(string, 0, sizeof(memcached_string_st)); + string->is_allocated= MEMCACHED_ALLOCATED; + } + string->block_size= MEMCACHED_BLOCK_SIZE; + string->root= ptr; rc= memcached_string_check(string, initial_size); if (rc != MEMCACHED_SUCCESS) { - free(string); + if (ptr->call_free) + ptr->call_free(ptr, string); + else + free(string); + return NULL; } - assert(string->string == string->end); + WATCHPOINT_ASSERT(string->string == string->end); return string; } -memcached_return memcached_string_append_character(memcached_st *ptr, - memcached_string_st *string, +memcached_return memcached_string_append_character(memcached_string_st *string, char character) { memcached_return rc; + WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); + rc= memcached_string_check(string, 1); if (rc != MEMCACHED_SUCCESS) @@ -71,32 +94,32 @@ memcached_return memcached_string_append_character(memcached_st *ptr, return MEMCACHED_SUCCESS; } -memcached_return memcached_string_append(memcached_st *ptr, memcached_string_st *string, +memcached_return memcached_string_append(memcached_string_st *string, char *value, size_t length) { memcached_return rc; - WATCHPOINT; + WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); + rc= memcached_string_check(string, length); - WATCHPOINT; if (rc != MEMCACHED_SUCCESS) return rc; - - WATCHPOINT; - assert(string->string); - assert(string->end >= string->string && string->end <= string->string + string->current_size); - WATCHPOINT; + WATCHPOINT_ASSERT(length <= string->current_size); + WATCHPOINT_ASSERT(string->string); + WATCHPOINT_ASSERT(string->end >= string->string); + memcpy(string->end, value, length); - WATCHPOINT; string->end+= length; return MEMCACHED_SUCCESS; } -size_t memcached_string_backspace(memcached_st *ptr, memcached_string_st *string, size_t remove) +size_t memcached_string_backspace(memcached_string_st *string, size_t remove) { + WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); + if (string->end - string->string > remove) { size_t difference; @@ -111,15 +134,57 @@ size_t memcached_string_backspace(memcached_st *ptr, memcached_string_st *string return remove; } -memcached_return memcached_string_reset(memcached_st *ptr, memcached_string_st *string) +char *memcached_string_c_copy(memcached_string_st *string) +{ + char *c_ptr; + + WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); + + if (memcached_string_length(string) == 0) + return NULL; + + if (string->root->call_malloc) + c_ptr= (char *)string->root->call_malloc(string->root, (memcached_string_length(string)+1) * sizeof(char)); + else + c_ptr= (char *)malloc((memcached_string_length(string)+1) * sizeof(char)); + + if (c_ptr == NULL) + return NULL; + + memcpy(c_ptr, memcached_string_value(string), memcached_string_length(string)); + c_ptr[memcached_string_length(string)]= 0; + + return c_ptr; +} + +memcached_return memcached_string_reset(memcached_string_st *string) { + WATCHPOINT_ASSERT(string->is_allocated != MEMCACHED_USED); string->end= string->string; return MEMCACHED_SUCCESS; } -void memcached_string_free(memcached_st *ptr, memcached_string_st *string) +void memcached_string_free(memcached_string_st *ptr) { - free(string->string); - free(string); + if (ptr == NULL) + return; + + if (ptr->string) + { + if (ptr->root->call_free) + ptr->root->call_free(ptr->root, ptr->string); + else + free(ptr->string); + } + + if (ptr->is_allocated == MEMCACHED_ALLOCATED) + { + if (ptr->root->call_free) + ptr->root->call_free(ptr->root, ptr); + else + free(ptr); + } + else + ptr->is_allocated= MEMCACHED_USED; }