2 * Copyright (C) 2006-2009 Brian Aker
5 * Use and distribution licensed under the BSD license. See
6 * the COPYING file in the parent directory for full text.
12 inline static memcached_return_t
_string_check(memcached_string_st
*string
, size_t need
)
14 if (need
&& need
> (size_t)(string
->current_size
- (size_t)(string
->end
- string
->string
)))
16 size_t current_offset
= (size_t) (string
->end
- string
->string
);
21 /* This is the block multiplier. To keep it larger and surive division errors we must round it up */
22 adjust
= (need
- (size_t)(string
->current_size
- (size_t)(string
->end
- string
->string
))) / string
->block_size
;
25 new_size
= sizeof(char) * (size_t)((adjust
* string
->block_size
) + string
->current_size
);
26 /* Test for overflow */
28 return MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
30 new_value
= string
->root
->call_realloc(string
->root
, string
->string
, new_size
);
32 if (new_value
== NULL
)
33 return MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
35 string
->string
= new_value
;
36 string
->end
= string
->string
+ current_offset
;
38 string
->current_size
+= (string
->block_size
* adjust
);
41 return MEMCACHED_SUCCESS
;
44 memcached_string_st
*memcached_string_create(memcached_st
*memc
, memcached_string_st
*string
, size_t initial_size
)
46 memcached_return_t rc
;
48 /* Saving malloc calls :) */
51 WATCHPOINT_ASSERT(memc
->options
.is_safe
&& string
->options
.is_initialized
== false);
53 memset(string
, 0, sizeof(memcached_string_st
));
57 string
= memc
->call_calloc(memc
, 1, sizeof(memcached_string_st
));
64 string
->options
.is_allocated
= true;
66 string
->block_size
= MEMCACHED_BLOCK_SIZE
;
69 rc
= _string_check(string
, initial_size
);
70 if (rc
!= MEMCACHED_SUCCESS
)
72 memc
->call_free(memc
, string
);
76 string
->options
.is_initialized
= true;
78 WATCHPOINT_ASSERT(string
->string
== string
->end
);
83 memcached_return_t
memcached_string_append_character(memcached_string_st
*string
,
86 memcached_return_t rc
;
88 rc
= _string_check(string
, 1);
90 if (rc
!= MEMCACHED_SUCCESS
)
93 *string
->end
= character
;
96 return MEMCACHED_SUCCESS
;
99 memcached_return_t
memcached_string_append(memcached_string_st
*string
,
100 const char *value
, size_t length
)
102 memcached_return_t rc
;
104 rc
= _string_check(string
, length
);
106 if (rc
!= MEMCACHED_SUCCESS
)
109 WATCHPOINT_ASSERT(length
<= string
->current_size
);
110 WATCHPOINT_ASSERT(string
->string
);
111 WATCHPOINT_ASSERT(string
->end
>= string
->string
);
113 memcpy(string
->end
, value
, length
);
114 string
->end
+= length
;
116 return MEMCACHED_SUCCESS
;
119 char *memcached_string_c_copy(memcached_string_st
*string
)
123 if (memcached_string_length(string
) == 0)
126 c_ptr
= string
->root
->call_malloc(string
->root
, (memcached_string_length(string
)+1) * sizeof(char));
131 memcpy(c_ptr
, memcached_string_value(string
), memcached_string_length(string
));
132 c_ptr
[memcached_string_length(string
)]= 0;
137 memcached_return_t
memcached_string_reset(memcached_string_st
*string
)
139 string
->end
= string
->string
;
141 return MEMCACHED_SUCCESS
;
144 void memcached_string_free(memcached_string_st
*ptr
)
151 ptr
->root
->call_free(ptr
->root
, ptr
->string
);
154 if (memcached_is_allocated(ptr
))
156 ptr
->root
->call_free(ptr
->root
, ptr
);
160 ptr
->options
.is_initialized
= false;
161 memset(ptr
, 0, sizeof(memcached_string_st
));
165 memcached_return_t
memcached_string_check(memcached_string_st
*string
, size_t need
)
167 return _string_check(string
, need
);