51 char* STRING::AllocData(
int used,
int capacity) {
52 data_ = static_cast<STRING_HEADER *>(malloc(capacity +
sizeof(STRING_HEADER)));
55 STRING_HEADER* header = GetHeader();
56 header->capacity_ = capacity;
61 void STRING::DiscardData() {
68 char* STRING::ensure_cstr(int32_t min_capacity) {
69 STRING_HEADER* orig_header = GetHeader();
70 if (min_capacity <= orig_header->capacity_)
71 return (reinterpret_cast<char *>(this->data_)) +
sizeof(STRING_HEADER);
76 if (min_capacity < 2 * orig_header->capacity_)
77 min_capacity = 2 * orig_header->capacity_;
79 int alloc =
sizeof(STRING_HEADER) + min_capacity;
80 auto* new_header = static_cast<STRING_HEADER*>(malloc(alloc));
82 memcpy(&new_header[1], GetCStr(), orig_header->used_);
83 new_header->capacity_ = min_capacity;
84 new_header->used_ = orig_header->used_;
90 assert(InvariantOk());
91 return (reinterpret_cast<char *>(data_)) +
sizeof(STRING_HEADER);
96 void STRING::FixHeader()
const {
97 const STRING_HEADER* header = GetHeader();
98 if (header->used_ < 0)
99 header->used_ = strlen(GetCStr()) + 1;
110 const STRING_HEADER* str_header = str.GetHeader();
111 const int str_used = str_header->used_;
112 char *this_cstr = AllocData(str_used, str_used);
113 memcpy(this_cstr, str.GetCStr(), str_used);
114 assert(InvariantOk());
118 if (cstr ==
nullptr) {
122 const int len = strlen(cstr) + 1;
123 char* this_cstr = AllocData(len, len);
124 memcpy(this_cstr, cstr, len);
126 assert(InvariantOk());
130 if (data ==
nullptr) {
135 memcpy(this_cstr, data,
length);
165 if (len > UINT16_MAX)
return false;
182 return fp->
Skip(len);
186 return (c !=
'\0') && (strchr (GetCStr(), c) !=
nullptr);
191 return GetHeader()->used_ - 1;
195 const STRING_HEADER* header = GetHeader();
196 if (!header || header->used_ == 0)
212 #if STRING_IS_PROTECTED
214 return GetCStr()[index];
217 void STRING::insert_range(int32_t index,
const char* str,
int len) {
220 STRING_HEADER* this_header = GetHeader();
221 int used = this_header->used_;
225 char* this_cstr = ensure_cstr(used + len + 1);
228 memmove(this_cstr + index + len,
230 this_header->used_ - index);
231 }
else if (len > 0) {
233 this_cstr[this_header->used_ + len - 1] =
'\0';
238 if (this_header->used_ == 0)
239 ++this_header->used_;
244 memcpy(this_cstr + index, str, len);
245 this_header->used_ += len;
247 assert(InvariantOk());
250 void STRING::erase_range(int32_t index,
int len) {
251 char* this_cstr = GetCStr();
252 STRING_HEADER* this_header = GetHeader();
254 memcpy(this_cstr+index, this_cstr+index+len,
255 this_header->used_ - index - len);
256 this_header->used_ -= len;
257 assert(InvariantOk());
264 char* this_cstr = ensure_cstr(index + 1);
265 this_cstr[index] =
'\0';
266 GetHeader()->used_ = index + 1;
267 assert(InvariantOk());
273 GetHeader()->used_ = -1;
274 return (const_cast<char *>(GetCStr()))[index];
281 for (
int i = 0; i < len; i++) {
282 if ((*
this)[i] == c) {
283 if (i != start_index) {
292 if (len != start_index) {
293 splited->
push_back(
STRING(GetCStr() + start_index, len - start_index));
300 const STRING_HEADER* str_header = str.GetHeader();
301 const STRING_HEADER* this_header = GetHeader();
302 const int this_used = this_header->used_;
303 const int str_used = str_header->used_;
305 return (this_used == str_used)
306 && (memcmp(GetCStr(), str.GetCStr(), this_used) == 0);
312 const STRING_HEADER* str_header = str.GetHeader();
313 const STRING_HEADER* this_header = GetHeader();
314 const int this_used = this_header->used_;
315 const int str_used = str_header->used_;
317 return (this_used != str_used)
318 || (memcmp(GetCStr(), str.GetCStr(), this_used) != 0);
323 const STRING_HEADER* this_header = GetHeader();
326 return this_header->used_ > 1;
328 const int32_t
length = strlen(cstr) + 1;
329 return (this_header->used_ !=
length)
330 || (memcmp(GetCStr(), cstr,
length) != 0);
336 const STRING_HEADER* str_header = str.GetHeader();
337 const int str_used = str_header->used_;
339 GetHeader()->used_ = 0;
340 char* this_cstr = ensure_cstr(str_used);
341 STRING_HEADER* this_header = GetHeader();
343 memcpy(this_cstr, str.GetCStr(), str_used);
344 this_header->used_ = str_used;
346 assert(InvariantOk());
353 const STRING_HEADER* str_header = str.GetHeader();
354 const char* str_cstr = str.GetCStr();
355 const int str_used = str_header->used_;
356 const int this_used = GetHeader()->used_;
357 char* this_cstr = ensure_cstr(this_used + str_used);
359 STRING_HEADER* this_header = GetHeader();
362 memcpy(this_cstr + this_used - 1, str_cstr, str_used);
363 this_header->used_ += str_used - 1;
365 memcpy(this_cstr, str_cstr, str_used);
366 this_header->used_ = str_used;
369 assert(InvariantOk());
378 snprintf(num_buffer,
kMaxIntSize - 1,
"%d", number);
386 std::stringstream stream;
388 stream.imbue(std::locale::classic());
392 *
this += stream.str().c_str();
396 STRING_HEADER* this_header = GetHeader();
398 const int len = strlen(cstr) + 1;
400 this_header->used_ = 0;
401 char* this_cstr = ensure_cstr(len);
402 this_header = GetHeader();
403 memcpy(this_cstr, cstr, len);
404 this_header->used_ = len;
412 assert(InvariantOk());
417 STRING_HEADER* this_header = GetHeader();
418 this_header->used_ = 0;
419 char* this_cstr = ensure_cstr(len + 1);
421 this_header = GetHeader();
422 memcpy(this_cstr, cstr, len);
423 this_cstr[len] =
'\0';
424 this_header->used_ = len + 1;
426 assert(InvariantOk());
433 assert(InvariantOk());
441 const STRING_HEADER* this_header = GetHeader();
442 const int this_used = this_header->used_;
443 char* result_cstr = result.ensure_cstr(this_used + 1);
444 STRING_HEADER* result_header = result.GetHeader();
445 const int result_used = result_header->used_;
448 memcpy(result_cstr, GetCStr(), this_used);
449 result_cstr[result_used] = ch;
450 result_cstr[result_used + 1] =
'\0';
451 ++result_header->used_;
453 assert(InvariantOk());
463 const int len = strlen(str) + 1;
464 const int this_used = GetHeader()->used_;
465 char* this_cstr = ensure_cstr(this_used + len);
466 STRING_HEADER* this_header = GetHeader();
471 memcpy(this_cstr + this_used - 1, str, len);
472 this_header->used_ += len - 1;
474 memcpy(this_cstr, str, len);
475 this_header->used_ = len;
478 assert(InvariantOk());
488 int this_used = GetHeader()->used_;
489 char* this_cstr = ensure_cstr(this_used + 1);
490 STRING_HEADER* this_header = GetHeader();
495 this_cstr[this_used++] = ch;
496 this_cstr[this_used++] =
'\0';
497 this_header->used_ = this_used;
499 assert(InvariantOk());