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.
8 * Summary: String structure used for libmemcached.
14 inline static memcached_return_t
_string_check(memcached_string_st
*string
, size_t need
)
16 if (need
&& need
> (size_t)(string
->current_size
- (size_t)(string
->end
- string
->string
)))
18 size_t current_offset
= (size_t) (string
->end
- string
->string
);
23 /* This is the block multiplier. To keep it larger and surive division errors we must round it up */
24 adjust
= (need
- (size_t)(string
->current_size
- (size_t)(string
->end
- string
->string
))) / MEMCACHED_BLOCK_SIZE
;
27 new_size
= sizeof(char) * (size_t)((adjust
* MEMCACHED_BLOCK_SIZE
) + string
->current_size
);
28 /* Test for overflow */
30 return MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
32 new_value
= libmemcached_realloc(string
->root
, string
->string
, new_size
);
34 if (new_value
== NULL
)
36 return MEMCACHED_MEMORY_ALLOCATION_FAILURE
;
39 string
->string
= new_value
;
40 string
->end
= string
->string
+ current_offset
;
42 string
->current_size
+= (MEMCACHED_BLOCK_SIZE
* adjust
);
45 return MEMCACHED_SUCCESS
;
48 static inline void _init_string(memcached_string_st
*self
)
50 self
->current_size
= 0;
51 self
->end
= self
->string
= NULL
;
54 memcached_string_st
*memcached_string_create(const memcached_st
*memc
, memcached_string_st
*self
, size_t initial_size
)
56 memcached_return_t rc
;
58 WATCHPOINT_ASSERT(memc
);
60 /* Saving malloc calls :) */
63 WATCHPOINT_ASSERT(self
->options
.is_initialized
== false);
65 self
->options
.is_allocated
= false;
69 self
= libmemcached_malloc(memc
, sizeof(memcached_string_st
));
76 self
->options
.is_allocated
= true;
78 self
->root
= (memcached_st
*)memc
;
82 rc
= _string_check(self
, initial_size
);
83 if (rc
!= MEMCACHED_SUCCESS
)
85 if (rc
== MEMCACHED_MEMORY_ALLOCATION_FAILURE
)
87 memcached_set_errno(self
->root
, errno
, NULL
);
89 libmemcached_free(memc
, self
);
94 self
->options
.is_initialized
= true;
96 WATCHPOINT_ASSERT(self
->string
== self
->end
);
101 memcached_return_t
memcached_string_append_character(memcached_string_st
*string
,
104 memcached_return_t rc
;
106 rc
= _string_check(string
, 1);
108 if (rc
!= MEMCACHED_SUCCESS
)
113 *string
->end
= character
;
116 return MEMCACHED_SUCCESS
;
119 memcached_return_t
memcached_string_append(memcached_string_st
*string
,
120 const char *value
, size_t length
)
122 memcached_return_t rc
;
124 rc
= _string_check(string
, length
);
126 if (rc
!= MEMCACHED_SUCCESS
)
131 WATCHPOINT_ASSERT(length
<= string
->current_size
);
132 WATCHPOINT_ASSERT(string
->string
);
133 WATCHPOINT_ASSERT(string
->end
>= string
->string
);
135 memcpy(string
->end
, value
, length
);
136 string
->end
+= length
;
138 return MEMCACHED_SUCCESS
;
141 char *memcached_string_c_copy(memcached_string_st
*string
)
145 if (memcached_string_length(string
) == 0)
148 c_ptr
= libmemcached_malloc(string
->root
, (memcached_string_length(string
)+1) * sizeof(char));
153 memcpy(c_ptr
, memcached_string_value(string
), memcached_string_length(string
));
154 c_ptr
[memcached_string_length(string
)]= 0;
159 memcached_return_t
memcached_string_reset(memcached_string_st
*string
)
161 string
->end
= string
->string
;
163 return MEMCACHED_SUCCESS
;
166 void memcached_string_free(memcached_string_st
*ptr
)
173 libmemcached_free(ptr
->root
, ptr
->string
);
176 if (memcached_is_allocated(ptr
))
178 libmemcached_free(ptr
->root
, ptr
);
182 ptr
->options
.is_initialized
= false;
186 memcached_return_t
memcached_string_check(memcached_string_st
*string
, size_t need
)
188 return _string_check(string
, need
);
191 size_t memcached_string_length(const memcached_string_st
*self
)
193 return (size_t)(self
->end
- self
->string
);
196 size_t memcached_string_size(const memcached_string_st
*self
)
198 return self
->current_size
;
201 const char *memcached_string_value(const memcached_string_st
*self
)
206 char *memcached_string_value_mutable(const memcached_string_st
*self
)
211 void memcached_string_set_length(memcached_string_st
*self
, size_t length
)
213 self
->end
= self
->string
+ length
;