42f3c326767f112c3ed071fd9a8b215bff85a7df
[awesomized/libmemcached] / lib / 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 new_value= (char *)realloc(string->string, new_size);
22
23 if (new_value == NULL)
24 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
25
26 string->string= new_value;
27 string->end= string->string + current_offset;
28
29 string->current_size+= (string->block_size * adjust);
30 }
31
32 return MEMCACHED_SUCCESS;
33 }
34
35 memcached_string_st *memcached_string_create(memcached_st *ptr, memcached_string_st *string, size_t initial_size)
36 {
37 memcached_return rc;
38
39 /* Saving malloc calls :) */
40 if (string)
41 {
42 memset(string, 0, sizeof(memcached_string_st));
43 string->is_allocated= MEMCACHED_NOT_ALLOCATED;
44 }
45 else
46 {
47 string= (memcached_string_st *)malloc(sizeof(memcached_string_st));
48 if (!string)
49 return NULL;
50 memset(string, 0, sizeof(memcached_string_st));
51 string->is_allocated= MEMCACHED_ALLOCATED;
52 }
53 string->block_size= MEMCACHED_BLOCK_SIZE;
54 string->root= ptr;
55
56 rc= memcached_string_check(string, initial_size);
57 if (rc != MEMCACHED_SUCCESS)
58 {
59 free(string);
60 return NULL;
61 }
62
63 WATCHPOINT_ASSERT(string->string == string->end);
64
65 return string;
66 }
67
68 memcached_return memcached_string_append_character(memcached_string_st *string,
69 char character)
70 {
71 memcached_return rc;
72
73 rc= memcached_string_check(string, 1);
74
75 if (rc != MEMCACHED_SUCCESS)
76 return rc;
77
78 *string->end= ' ';
79 string->end++;
80
81 return MEMCACHED_SUCCESS;
82 }
83
84 memcached_return memcached_string_append(memcached_string_st *string,
85 char *value, size_t length)
86 {
87 memcached_return rc;
88
89 rc= memcached_string_check(string, length);
90
91 if (rc != MEMCACHED_SUCCESS)
92 return rc;
93
94 WATCHPOINT_ASSERT(length <= string->current_size);
95 WATCHPOINT_ASSERT(string->string);
96 WATCHPOINT_ASSERT(string->end >= string->string);
97
98 memcpy(string->end, value, length);
99 string->end+= length;
100
101 return MEMCACHED_SUCCESS;
102 }
103
104 size_t memcached_string_backspace(memcached_string_st *string, size_t remove)
105 {
106 if (string->end - string->string > remove)
107 {
108 size_t difference;
109
110 difference= string->end - string->string;
111 string->end= string->string;
112
113 return difference;
114 }
115 string->end-= remove;
116
117 return remove;
118 }
119
120 char *memcached_string_c_copy(memcached_string_st *string)
121 {
122 char *c_ptr;
123 c_ptr= (char *)malloc(memcached_string_length(string) * sizeof(char));
124 if (!c_ptr)
125 return NULL;
126
127 memcpy(c_ptr, memcached_string_value(string), memcached_string_length(string));
128
129 return c_ptr;
130 }
131
132 memcached_return memcached_string_reset(memcached_string_st *string)
133 {
134 string->end= string->string;
135
136 return MEMCACHED_SUCCESS;
137 }
138
139 void memcached_string_free(memcached_string_st *string)
140 {
141 if (string->string)
142 free(string->string);
143 if (string->is_allocated == MEMCACHED_ALLOCATED)
144 free(string);
145 }