Restructuring for new memcached_result_st.
[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 /* We zero the block structure we just realloced */
32 memset((string->string + current_offset), 0,
33 sizeof(char) * string->block_size);
34 }
35
36 return MEMCACHED_SUCCESS;
37 }
38
39 memcached_string_st *memcached_string_create(memcached_st *ptr, memcached_string_st *string, size_t initial_size)
40 {
41 memcached_return rc;
42
43 /* Saving malloc calls :) */
44 if (string)
45 {
46 memset(string, 0, sizeof(memcached_string_st));
47 string->is_allocated= MEMCACHED_NOT_ALLOCATED;
48 }
49 else
50 {
51 string= (memcached_string_st *)malloc(sizeof(memcached_string_st));
52 if (!string)
53 return NULL;
54 memset(string, 0, sizeof(memcached_string_st));
55 string->is_allocated= MEMCACHED_ALLOCATED;
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 free(string);
64 return NULL;
65 }
66
67 WATCHPOINT_ASSERT(string->string == string->end);
68
69 return string;
70 }
71
72 memcached_return memcached_string_append_character(memcached_string_st *string,
73 char character)
74 {
75 memcached_return rc;
76
77 rc= memcached_string_check(string, 1);
78
79 if (rc != MEMCACHED_SUCCESS)
80 return rc;
81
82 *string->end= ' ';
83 string->end++;
84
85 return MEMCACHED_SUCCESS;
86 }
87
88 memcached_return memcached_string_append(memcached_string_st *string,
89 char *value, size_t length)
90 {
91 memcached_return rc;
92
93 rc= memcached_string_check(string, length);
94
95 if (rc != MEMCACHED_SUCCESS)
96 return rc;
97
98 WATCHPOINT_ASSERT(length <= string->current_size);
99 WATCHPOINT_ASSERT(string->string);
100 WATCHPOINT_ASSERT(string->end >= string->string);
101
102 memcpy(string->end, value, length);
103 string->end+= length;
104
105 return MEMCACHED_SUCCESS;
106 }
107
108 size_t memcached_string_backspace(memcached_string_st *string, size_t remove)
109 {
110 if (string->end - string->string > remove)
111 {
112 size_t difference;
113
114 difference= string->end - string->string;
115 string->end= string->string;
116
117 return difference;
118 }
119 string->end-= remove;
120
121 return remove;
122 }
123
124 char *memcached_string_c_copy(memcached_string_st *string)
125 {
126 char *c_ptr;
127 c_ptr= (char *)malloc(memcached_string_length(string) * sizeof(char));
128 if (!c_ptr)
129 return NULL;
130
131 memcpy(c_ptr, memcached_string_value(string), memcached_string_length(string));
132
133 return c_ptr;
134 }
135
136 memcached_return memcached_string_reset(memcached_string_st *string)
137 {
138 string->end= string->string;
139
140 return MEMCACHED_SUCCESS;
141 }
142
143 void memcached_string_free(memcached_string_st *string)
144 {
145 if (string->string)
146 free(string->string);
147 if (string->is_allocated == MEMCACHED_ALLOCATED)
148 free(string);
149 }