5a6f190e5dd9f1fdbd526df01afffc991b1ce280
[awesomized/libmemcached] / libmemcached / memcached_string.c
1 #include "common.h"
2
3 memcached_return memcached_string_check(memcached_string_st *string, size_t need)
4 {
5 if (need && need > (size_t)(string->current_size - (size_t)(string->end - string->string)))
6 {
7 size_t current_offset= string->end - string->string;
8 char *new_value;
9 size_t adjust;
10 size_t new_size;
11
12 /* This is the block multiplier. To keep it larger and surive division errors we must round it up */
13 adjust= (need - (size_t)(string->current_size - (size_t)(string->end - string->string))) / string->block_size;
14 adjust++;
15
16 new_size= sizeof(char) * (size_t)((adjust * string->block_size) + string->current_size);
17 /* Test for overflow */
18 if (new_size < need)
19 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
20
21 if (string->root->call_realloc)
22 new_value= (char *)string->root->call_realloc(string->root, string->string, new_size);
23 else
24 new_value= (char *)realloc(string->string, new_size);
25
26 if (new_value == NULL)
27 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
28
29 string->string= new_value;
30 string->end= string->string + current_offset;
31
32 string->current_size+= (string->block_size * adjust);
33 }
34
35 return MEMCACHED_SUCCESS;
36 }
37
38 memcached_string_st *memcached_string_create(memcached_st *ptr, memcached_string_st *string, size_t initial_size)
39 {
40 memcached_return rc;
41
42 /* Saving malloc calls :) */
43 if (string)
44 memset(string, 0, sizeof(memcached_string_st));
45 else
46 {
47 if (ptr->call_malloc)
48 string= (memcached_string_st *)ptr->call_malloc(ptr, sizeof(memcached_string_st));
49 else
50 string= (memcached_string_st *)malloc(sizeof(memcached_string_st));
51
52 if (string == NULL)
53 return NULL;
54 memset(string, 0, sizeof(memcached_string_st));
55 string->is_allocated= true;
56 }
57 string->block_size= MEMCACHED_BLOCK_SIZE;
58 string->root= ptr;
59
60 rc= memcached_string_check(string, initial_size);
61 if (rc != MEMCACHED_SUCCESS)
62 {
63 if (ptr->call_free)
64 ptr->call_free(ptr, string);
65 else
66 free(string);
67
68 return NULL;
69 }
70
71 WATCHPOINT_ASSERT(string->string == string->end);
72
73 return string;
74 }
75
76 memcached_return memcached_string_append_character(memcached_string_st *string,
77 char character)
78 {
79 memcached_return rc;
80
81 rc= memcached_string_check(string, 1);
82
83 if (rc != MEMCACHED_SUCCESS)
84 return rc;
85
86 *string->end= character;
87 string->end++;
88
89 return MEMCACHED_SUCCESS;
90 }
91
92 memcached_return memcached_string_append(memcached_string_st *string,
93 char *value, size_t length)
94 {
95 memcached_return rc;
96
97 rc= memcached_string_check(string, length);
98
99 if (rc != MEMCACHED_SUCCESS)
100 return rc;
101
102 WATCHPOINT_ASSERT(length <= string->current_size);
103 WATCHPOINT_ASSERT(string->string);
104 WATCHPOINT_ASSERT(string->end >= string->string);
105
106 memcpy(string->end, value, length);
107 string->end+= length;
108
109 return MEMCACHED_SUCCESS;
110 }
111
112 char *memcached_string_c_copy(memcached_string_st *string)
113 {
114 char *c_ptr;
115
116 if (memcached_string_length(string) == 0)
117 return NULL;
118
119 if (string->root->call_malloc)
120 c_ptr= (char *)string->root->call_malloc(string->root, (memcached_string_length(string)+1) * sizeof(char));
121 else
122 c_ptr= (char *)malloc((memcached_string_length(string)+1) * sizeof(char));
123
124 if (c_ptr == NULL)
125 return NULL;
126
127 memcpy(c_ptr, memcached_string_value(string), memcached_string_length(string));
128 c_ptr[memcached_string_length(string)]= 0;
129
130 return c_ptr;
131 }
132
133 memcached_return memcached_string_reset(memcached_string_st *string)
134 {
135 string->end= string->string;
136
137 return MEMCACHED_SUCCESS;
138 }
139
140 void memcached_string_free(memcached_string_st *ptr)
141 {
142 if (ptr == NULL)
143 return;
144
145 if (ptr->string)
146 {
147 if (ptr->root->call_free)
148 ptr->root->call_free(ptr->root, ptr->string);
149 else
150 free(ptr->string);
151 }
152
153 if (ptr->is_allocated)
154 {
155 if (ptr->root->call_free)
156 ptr->root->call_free(ptr->root, ptr);
157 else
158 free(ptr);
159 }
160 else
161 memset(ptr, 0, sizeof(memcached_string_st));
162 }