235438856549af447f90347470916497809f697c
[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 > (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->end= string->string;
58 string->block_size= initial_size;
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_st *ptr,
73 memcached_string_st *string,
74 char character)
75 {
76 memcached_return rc;
77
78 rc= memcached_string_check(string, 1);
79
80 if (rc != MEMCACHED_SUCCESS)
81 return rc;
82
83 *string->end= ' ';
84 string->end++;
85
86 return MEMCACHED_SUCCESS;
87 }
88
89 memcached_return memcached_string_append(memcached_st *ptr, memcached_string_st *string,
90 char *value, size_t length)
91 {
92 memcached_return rc;
93
94 rc= memcached_string_check(string, length);
95
96 if (rc != MEMCACHED_SUCCESS)
97 return rc;
98
99 WATCHPOINT_ASSERT(length <= string->current_size);
100 WATCHPOINT_ASSERT(string->string);
101 WATCHPOINT_ASSERT(string->end >= string->string);
102
103 memcpy(string->end, value, length);
104 string->end+= length;
105
106 return MEMCACHED_SUCCESS;
107 }
108
109 size_t memcached_string_backspace(memcached_st *ptr, memcached_string_st *string, size_t remove)
110 {
111 if (string->end - string->string > remove)
112 {
113 size_t difference;
114
115 difference= string->end - string->string;
116 string->end= string->string;
117
118 return difference;
119 }
120 string->end-= remove;
121
122 return remove;
123 }
124
125 memcached_return memcached_string_reset(memcached_st *ptr, memcached_string_st *string)
126 {
127 string->end= string->string;
128
129 return MEMCACHED_SUCCESS;
130 }
131
132 void memcached_string_free(memcached_st *ptr, memcached_string_st *string)
133 {
134 free(string->string);
135 if (string->is_allocated == MEMCACHED_ALLOCATED)
136 free(string);
137 }