2 +--------------------------------------------------------------------+
3 | libmemcached-awesome - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020-2021 Michael Wallner https://awesome.co/ |
13 +--------------------------------------------------------------------+
16 #include "libhashkit/common.h"
21 #define HASHKIT_BLOCK_SIZE 1024
23 struct hashkit_string_st
{
29 inline static bool _string_check(hashkit_string_st
*string
, size_t need
) {
30 if (need
and need
> (size_t)(string
->current_size
- (size_t)(string
->end
- string
->string
))) {
31 size_t current_offset
= (size_t)(string
->end
- string
->string
);
33 /* This is the block multiplier. To keep it larger and surive division errors we must round it
35 size_t adjust
= (need
- (size_t)(string
->current_size
- (size_t)(string
->end
- string
->string
)))
39 size_t new_size
= sizeof(char) * (size_t)((adjust
* HASHKIT_BLOCK_SIZE
) + string
->current_size
);
40 /* Test for overflow */
41 if (new_size
< need
) {
45 char *new_value
= (char *) realloc(string
->string
, new_size
);
47 if (new_value
== NULL
) {
51 string
->string
= new_value
;
52 string
->end
= string
->string
+ current_offset
;
54 string
->current_size
+= (HASHKIT_BLOCK_SIZE
* adjust
);
60 static inline void _init_string(hashkit_string_st
*self
) {
61 self
->current_size
= 0;
62 self
->end
= self
->string
= NULL
;
65 hashkit_string_st
*hashkit_string_create(size_t initial_size
) {
66 hashkit_string_st
*self
= (hashkit_string_st
*) calloc(1, sizeof(hashkit_string_st
));
69 if (_string_check(self
, initial_size
) == false) {
80 static bool hashkit_string_append_null(hashkit_string_st
*string
)
82 if (_string_check(string
, 1) == false)
93 bool hashkit_string_append_character(hashkit_string_st
*string
, char character
) {
94 if (_string_check(string
, 1) == false) {
98 *string
->end
= character
;
104 bool hashkit_string_append(hashkit_string_st
*string
, const char *value
, size_t length
) {
105 if (_string_check(string
, length
) == false) {
109 assert(length
<= string
->current_size
);
110 assert(string
->string
);
111 assert(string
->end
>= string
->string
);
113 memcpy(string
->end
, value
, length
);
114 string
->end
+= length
;
119 char *hashkit_string_c_copy(hashkit_string_st
*string
) {
120 if (hashkit_string_length(string
) == 0) {
124 char *c_ptr
= static_cast<char *>(malloc((hashkit_string_length(string
) + 1) * sizeof(char)));
129 memcpy(c_ptr
, hashkit_string_c_str(string
), hashkit_string_length(string
));
130 c_ptr
[hashkit_string_length(string
)] = 0;
135 void hashkit_string_reset(hashkit_string_st
*string
) {
136 string
->end
= string
->string
;
139 void hashkit_string_free(hashkit_string_st
*ptr
) {
150 bool hashkit_string_resize(hashkit_string_st
&string
, const size_t need
) {
151 return _string_check(&string
, need
);
154 size_t hashkit_string_length(const hashkit_string_st
*self
) {
155 return size_t(self
->end
- self
->string
);
158 size_t hashkit_string_max_size(const hashkit_string_st
*self
) {
159 return self
->current_size
;
162 char *hashkit_string_take(hashkit_string_st
*self
) {
167 char *value
= self
->string
;
174 char *hashkit_string_c_str_mutable(hashkit_string_st
*self
) {
182 const char *hashkit_string_c_str(const hashkit_string_st
*self
) {
190 void hashkit_string_set_length(hashkit_string_st
*self
, size_t length
) {
192 if (self
and _string_check(self
, length
)) {
193 self
->end
= self
->string
+ length
;