47 char* STRING::AllocData(
int used,
int capacity) {
48 data_ = (STRING_HEADER *)
alloc_string(capacity +
sizeof(STRING_HEADER));
51 STRING_HEADER* header = GetHeader();
52 header->capacity_ = capacity;
57 void STRING::DiscardData() {
63 char* STRING::ensure_cstr(
inT32 min_capacity) {
64 STRING_HEADER* orig_header = GetHeader();
65 if (min_capacity <= orig_header->capacity_)
66 return ((
char *)this->data_) +
sizeof(STRING_HEADER);
71 if (min_capacity < 2 * orig_header->capacity_)
72 min_capacity = 2 * orig_header->capacity_;
74 int alloc =
sizeof(STRING_HEADER) + min_capacity;
75 STRING_HEADER* new_header = (STRING_HEADER*)(
alloc_string(alloc));
77 memcpy(&new_header[1], GetCStr(), orig_header->used_);
78 new_header->capacity_ = min_capacity;
79 new_header->used_ = orig_header->used_;
85 assert(InvariantOk());
86 return ((
char *)data_) +
sizeof(STRING_HEADER);
91 void STRING::FixHeader()
const {
92 const STRING_HEADER* header = GetHeader();
93 if (header->used_ < 0)
94 header->used_ = strlen(GetCStr()) + 1;
105 const STRING_HEADER* str_header = str.GetHeader();
106 int str_used = str_header->used_;
107 char *this_cstr = AllocData(str_used, str_used);
108 memcpy(this_cstr, str.GetCStr(), str_used);
109 assert(InvariantOk());
117 int len = strlen(cstr) + 1;
118 char* this_cstr = AllocData(len, len);
119 memcpy(this_cstr, cstr, len);
121 assert(InvariantOk());
131 if (fwrite(&len,
sizeof(len), 1, fp) != 1)
return false;
132 if (fwrite(GetCStr(), 1, len, fp) != len)
return false;
139 if (fread(&len,
sizeof(len), 1, fp) != 1)
return false;
143 if (fread(GetCStr(), 1, len, fp) != len)
return false;
148 return (c !=
'\0') && (strchr (GetCStr(), c) !=
NULL);
153 return GetHeader()->used_ - 1;
157 const STRING_HEADER* header = GetHeader();
158 if (header->used_ == 0)
174 #if STRING_IS_PROTECTED
176 return GetCStr()[index];
179 void STRING::insert_range(
inT32 index,
const char* str,
int len) {
182 STRING_HEADER* this_header = GetHeader();
183 int used = this_header->used_;
187 char* this_cstr = ensure_cstr(used + len + 1);
190 memmove(this_cstr + index + len,
192 this_header->used_ - index);
193 }
else if (len > 0) {
195 this_cstr[this_header->used_ + len - 1] =
'\0';
200 if (this_header->used_ == 0)
201 ++this_header->used_;
206 memcpy(this_cstr + index, str, len);
207 this_header->used_ += len;
209 assert(InvariantOk());
212 void STRING::erase_range(
inT32 index,
int len) {
213 char* this_cstr = GetCStr();
214 STRING_HEADER* this_header = GetHeader();
216 memcpy(this_cstr+index, this_cstr+index+len,
217 this_header->used_ - index - len);
218 this_header->used_ -= len;
219 assert(InvariantOk());
224 char* this_cstr = ensure_cstr(index + 1);
225 this_cstr[index] =
'\0';
226 GetHeader()->used_ = index + 1;
227 assert(InvariantOk());
233 GetHeader()->used_ = -1;
234 return ((
char *)GetCStr())[index];
240 for (
int i = 0; i <
length(); i++) {
241 if ((*
this)[i] == c) {
242 if (i != start_index) {
244 STRING tmp = GetCStr() + start_index;
252 if (
length() != start_index) {
253 STRING tmp = GetCStr() + start_index;
261 const STRING_HEADER* str_header = str.GetHeader();
262 const STRING_HEADER* this_header = GetHeader();
263 int this_used = this_header->used_;
264 int str_used = str_header->used_;
266 return (this_used == str_used)
267 && (memcmp(GetCStr(), str.GetCStr(), this_used) == 0);
273 const STRING_HEADER* str_header = str.GetHeader();
274 const STRING_HEADER* this_header = GetHeader();
275 int this_used = this_header->used_;
276 int str_used = str_header->used_;
278 return (this_used != str_used)
279 || (memcmp(GetCStr(), str.GetCStr(), this_used) != 0);
284 const STRING_HEADER* this_header = GetHeader();
287 return this_header->used_ > 1;
290 return (this_header->used_ != length)
291 || (memcmp(GetCStr(), cstr, length) != 0);
297 const STRING_HEADER* str_header = str.GetHeader();
298 int str_used = str_header->used_;
300 GetHeader()->used_ = 0;
301 char* this_cstr = ensure_cstr(str_used);
302 STRING_HEADER* this_header = GetHeader();
304 memcpy(this_cstr, str.GetCStr(), str_used);
305 this_header->used_ = str_used;
307 assert(InvariantOk());
314 const STRING_HEADER* str_header = str.GetHeader();
315 const char* str_cstr = str.GetCStr();
316 int str_used = str_header->used_;
317 int this_used = GetHeader()->used_;
318 char* this_cstr = ensure_cstr(this_used + str_used);
320 STRING_HEADER* this_header = GetHeader();
323 memcpy(this_cstr + this_used - 1, str_cstr, str_used);
324 this_header->used_ += str_used - 1;
326 memcpy(this_cstr, str_cstr, str_used);
327 this_header->used_ = str_used;
330 assert(InvariantOk());
339 snprintf(num_buffer,
kMaxIntSize - 1,
"%d", number);
345 STRING_HEADER* this_header = GetHeader();
347 int len = strlen(cstr) + 1;
349 this_header->used_ = 0;
350 char* this_cstr = ensure_cstr(len);
351 this_header = GetHeader();
352 memcpy(this_cstr, cstr, len);
353 this_header->used_ = len;
361 assert(InvariantOk());
366 STRING_HEADER* this_header = GetHeader();
367 this_header->used_ = 0;
368 char* this_cstr = ensure_cstr(len + 1);
370 this_header = GetHeader();
371 memcpy(this_cstr, cstr, len);
372 this_cstr[len] =
'\0';
373 this_header->used_ = len + 1;
375 assert(InvariantOk());
382 assert(InvariantOk());
390 const STRING_HEADER* this_header = GetHeader();
391 int this_used = this_header->used_;
392 char* result_cstr = result.ensure_cstr(this_used + 1);
393 STRING_HEADER* result_header = result.GetHeader();
394 int result_used = result_header->used_;
397 memcpy(result_cstr, GetCStr(), this_used);
398 result_cstr[result_used] = ch;
399 result_cstr[result_used + 1] =
'\0';
400 ++result_header->used_;
402 assert(InvariantOk());
412 int len = strlen(str) + 1;
413 int this_used = GetHeader()->used_;
414 char* this_cstr = ensure_cstr(this_used + len);
415 STRING_HEADER* this_header = GetHeader();
420 memcpy(this_cstr + this_used - 1, str, len);
421 this_header->used_ += len - 1;
423 memcpy(this_cstr, str, len);
424 this_header->used_ = len;
427 assert(InvariantOk());
437 int this_used = GetHeader()->used_;
438 char* this_cstr = ensure_cstr(this_used + 1);
439 STRING_HEADER* this_header = GetHeader();
444 this_cstr[this_used++] = ch;
445 this_cstr[this_used++] =
'\0';
446 this_header->used_ = this_used;
448 assert(InvariantOk());