ZFFramework
 
Loading...
Searching...
No Matches
zfstring.h
Go to the documentation of this file.
1
5
6#ifndef _ZFI_zfstring_h_
7#define _ZFI_zfstring_h_
8
11#include "ZFCoreMutex.h"
12#include "ZFMemPool.h"
13
15
16// ============================================================
17template<typename T_Char>
18zfindex _ZFP_zfstring_len(ZF_IN const T_Char *s) {
19 const T_Char *p = s;
20 while(*p) {++p;}
21 return p - s;
22}
23template<typename T_Char>
24zfint _ZFP_zfstring_cmp(
25 ZF_IN const T_Char *s1
26 , ZF_IN const T_Char *s2
27 ) {
28 while(*s1 && *s2 && *s1 == *s2) {++s1, ++s2;}
29 return *s1 - *s2;
30}
31template<typename T_Char>
32zfint _ZFP_zfstring_ncmp(
33 ZF_IN const T_Char *s1
34 , ZF_IN const T_Char *s2
35 , ZF_IN zfindex len
36 ) {
37 while(--len && *s1 && *s2 && *s1 == *s2) {++s1, ++s2;}
38 return *s1 - *s2;
39}
40
41// ============================================================
42inline zfindex _ZFP_zfstring_len(ZF_IN const zfchar *s) {
43 return zfslen(s);
44}
45inline zfint _ZFP_zfstring_cmp(
46 ZF_IN const zfchar *s1
47 , ZF_IN const zfchar *s2
48 ) {
49 return zfscmp(s1, s2);
50}
51inline zfint _ZFP_zfstring_ncmp(
52 ZF_IN const zfchar *s1
53 , ZF_IN const zfchar *s2
54 , ZF_IN zfindex len
55 ) {
56 return zfsncmp(s1, s2, len);
57}
58
59template<typename T_Char>
60zfclassNotPOD _ZFP_zfstringD {
61public:
62 zfuint refCount;
63 zfuint capacity; // capacity including tail '\0'
64 zfuint length;
65 union {
66 T_Char *buf; // capacity != 0
67 const T_Char *ptr; // capacity = 0
68 } d;
69public:
70 _ZFP_zfstringD(void) : refCount(1), capacity(0), length(0), d() {
71 static T_Char buf[1] = {0};
72 d.ptr = buf;
73 }
74};
75template<typename T_Char>
76zfclassLikePOD _ZFP_zfstringH {
77public:
78 _ZFP_zfstringH(void) : d(zfpoolNew(_ZFP_zfstringD<T_Char>)) {}
79 ~_ZFP_zfstringH(void) {zfpoolDelete(d);}
80public:
81 _ZFP_zfstringD<T_Char> *d;
82};
83
84// ============================================================
88template<typename T_Char>
90public:
93 {
95 d = _ZFP_Empty();
96 ++(d->refCount);
97 }
98
100 {
102 d = s.d;
103 ++(d->refCount);
104 }
105
107 {
109 d = _ZFP_Empty();
110 ++(d->refCount);
111 this->assign(s.cString(), len);
112 }
113
115 {
117 d = _ZFP_Empty();
118 ++(d->refCount);
119 if(pos < s.length()) {
120 if(len > s.length() - pos) {
121 len = s.length() - pos;
122 }
123 this->assign(s.cString() + pos, len);
124 }
125 }
126
127 zft_zfstring(ZF_IN const T_Char *s)
128 {
130 d = _ZFP_Empty();
131 ++(d->refCount);
132 if(s) {
133 this->assign(s);
134 }
135 }
136
137 zft_zfstring(ZF_IN const T_Char *s, ZF_IN zfindex len)
138 {
140 d = _ZFP_Empty();
141 ++(d->refCount);
142 if(s) {
143 this->assign(s, len);
144 }
145 }
146
147 zft_zfstring(ZF_IN const T_Char *s, ZF_IN zfindex pos, ZF_IN zfindex len)
148 {
150 d = _ZFP_Empty();
151 ++(d->refCount);
152 if(s) {
153 this->assign(s + pos, len);
154 }
155 }
156
158 {
160 d = _ZFP_Empty();
161 ++(d->refCount);
162 }
163 ~zft_zfstring(void) {
165 if(d->refCount == 1) {
166 if(d->capacity) {
167 zffree(d->d.buf);
168 }
169 zfpoolDelete(d);
170 }
171 else {
172 --(d->refCount);
173 }
174 }
175
176public:
178 inline operator const T_Char * (void) const {
179 return this->isEmpty() ? zfnull : this->cString();
180 }
181public:
182 inline zft_zfstring<T_Char> &operator = (ZF_IN const zft_zfstring<T_Char> &s) {
184 _ZFP_zfstringD<T_Char> *dTmp = d;
185 d = s.d;
186 ++(d->refCount);
187 if(dTmp->refCount == 1) {
188 if(dTmp->capacity) {
189 zffree(dTmp->d.buf);
190 }
191 zfpoolDelete(dTmp);
192 }
193 else {
194 --(dTmp->refCount);
195 }
196 return *this;
197 }
198 inline zft_zfstring<T_Char> &operator = (ZF_IN const T_Char *s) {return this->assign(s);}
199 inline zft_zfstring<T_Char> &operator = (ZF_IN zfnullT const &dummy) {return this->assign(dummy);}
200 zfbool operator == (ZF_IN const zft_zfstring<T_Char> &ref) const {return (this->compare(ref) == 0);}
201 zfbool operator != (ZF_IN const zft_zfstring<T_Char> &ref) const {return (this->compare(ref) != 0);}
202 zfbool operator == (ZF_IN const T_Char *ref) const {return (this->compare(ref) == 0);}
203 zfbool operator != (ZF_IN const T_Char *ref) const {return (this->compare(ref) != 0);}
204 zfbool operator == (ZF_IN zfnullT const &dummy) const {return this->isEmpty();}
205 zfbool operator != (ZF_IN zfnullT const &dummy) const {return !this->isEmpty();}
206public:
207 /* ZFTAG_TRICKS: tricks to make ZFMap<zfstring, xxx> works */
208 inline zfbool operator < (ZF_IN const zft_zfstring<T_Char> &ref) const {return this->compare(ref) < 0;}
209 inline zfbool operator <= (ZF_IN const zft_zfstring<T_Char> &ref) const {return this->compare(ref) <= 0;}
210 inline zfbool operator > (ZF_IN const zft_zfstring<T_Char> &ref) const {return this->compare(ref) > 0;}
211 inline zfbool operator >= (ZF_IN const zft_zfstring<T_Char> &ref) const {return this->compare(ref) >= 0;}
213
214public:
216 inline zft_zfstring<T_Char> &operator += (ZF_IN T_Char c) {return this->append(c);}
217 inline zft_zfstring<T_Char> &operator += (ZF_IN const zft_zfstring<T_Char> &s) {return this->append(s);}
218 inline zft_zfstring<T_Char> &operator += (ZF_IN const T_Char *s) {return this->append(s);}
219
220 template<typename T_Int>
221 inline const T_Char *operator + (ZF_IN T_Int const &offset) const {
222 return this->cString() + offset;
223 }
225
226public:
230 void set(
231 ZF_IN zfindex pos
232 , ZF_IN T_Char c
233 ) {
234 _prepareWrite(this->length());
235 d->d.buf[pos] = c;
236 }
237
240 inline T_Char get(ZF_IN zfindex pos) const {
241 return d->d.ptr[pos];
242 }
243
245 template<typename T_Int>
246 inline T_Char operator [] (ZF_IN T_Int pos) const {
247 return this->get(pos);
248 }
250
251public:
258 _ZFP_zfstringD<T_Char> *dTmp = d;
259 d = ref.d;
260 ref.d = dTmp;
261 }
262
263public:
266 _prepareWrite(d->length + 1);
267 d->d.buf[d->length] = c;
268 d->d.buf[++(d->length)] = '\0';
269 return *this;
270 }
271
273 if(s) {
274 _appendImpl(s.cString(), s.length());
275 }
276 return *this;
277 }
278
281 , ZF_IN zfindex len
282 ) {
283 len = (len <= s.length() ? len : s.length());
284 if(len > 0) {
285 _appendImpl(s.cString(), len);
286 }
287 return *this;
288 }
289
292 , ZF_IN zfindex offset
293 , ZF_IN zfindex len
294 ) {
295 if(offset > s.length()) {
296 offset = s.length();
297 }
298 if(len > s.length() - offset) {
299 len = s.length() - offset;
300 }
301 if(len > 0) {
302 _appendImpl(s.cString() + offset, len);
303 }
304 return *this;
305 }
306
308 ZF_IN const void *s
310 ) {
311 if(s) {
312 if(len == zfindexMax()) {
313 len = _ZFP_zfstring_len((const T_Char *)s);
314 }
315 if(len > 0) {
316 _appendImpl(s, len);
317 }
318 }
319 return *this;
320 }
321private:
322 void _appendImpl(
323 ZF_IN const void *s
324 , ZF_IN zfindex len
325 ) {
326 _prepareWrite(d->length + len);
327 zfmemcpy(d->d.buf + d->length, s, len * sizeof(T_Char));
328 d->d.buf[d->length += (zfuint)len] = '\0';
329 }
330
331public:
334 this->operator = (s);
335 return *this;
336 }
337
340 , ZF_IN zfindex len
341 ) {
342 return this->assign(s.cString(), len <= s.length() ? len : s.length());
343 }
344
347 , ZF_IN zfindex offset
348 , ZF_IN zfindex len
349 ) {
350 if(offset > s.length()) {
351 offset = s.length();
352 }
353 if(len > s.length() - offset) {
354 len = s.length() - offset;
355 }
356 return this->assign(s.cString() + offset, len);
357 }
358
360 ZF_IN const void *s
362 ) {
363 if(len == zfindexMax()) {
364 if(s) {
365 len = _ZFP_zfstring_len((const T_Char *)s);
366 }
367 else {
368 len = 0;
369 }
370 }
371 if(len > 0) {
372 if(len >= d->capacity || d->refCount > 1
373 || (d->capacity >= 128 && len < d->capacity / 3)
374 ) {
375 _capacityChange(len, zffalse);
376 }
377 d->length = (zfuint)len;
378 zfmemcpy(d->d.buf, s, len * sizeof(T_Char));
379 d->d.buf[len] = '\0';
380 }
381 else {
382 this->removeAll();
383 }
384 return *this;
385 }
386
387 inline zft_zfstring<T_Char> &assign(ZF_IN const zfnullT &dummy) {
388 this->removeAll();
389 return *this;
390 }
391
392public:
395 ZF_IN zfindex insertAt
396 , ZF_IN const zft_zfstring<T_Char> &s
397 ) {
398 return this->insert(insertAt, s.cString(), s.length());
399 }
400
402 ZF_IN zfindex insertAt
403 , ZF_IN const void *s
405 ) {
406 if(insertAt >= this->length()) {
407 this->append(s, len);
408 }
409 else if(s) {
410 if(len == zfindexMax()) {
411 len = _ZFP_zfstring_len((const T_Char *)s);
412 }
413 if(len > 0) {
414 zfindex lenTmp = this->length();
415 _prepareWrite(lenTmp + len);
416 d->length = (zfuint)(lenTmp + len);
417 zfmemmove(d->d.buf + insertAt + len, d->d.buf + insertAt, (lenTmp - insertAt) * sizeof(T_Char));
418 zfmemcpy(d->d.buf + insertAt, s, len * sizeof(T_Char));
419 d->d.buf[d->length] = '\0';
420 }
421 }
422 return *this;
423 }
424
425public:
428 ZF_IN zfindex replacePos
429 , ZF_IN zfindex replaceLen
430 , ZF_IN const zft_zfstring<T_Char> &s
431 ) {
432 return this->replace(replacePos, replaceLen, s.cString(), s.length());
433 }
434
436 ZF_IN zfindex replacePos
437 , ZF_IN zfindex replaceLen
438 , ZF_IN const void *s
440 ) {
441 if(replacePos >= this->length()) {
442 this->append(s, len);
443 }
444 else if(s) {
445 zfindex lenTmp = this->length();
446 if(replaceLen > lenTmp - replacePos) {
447 replaceLen = lenTmp - replacePos;
448 }
449 if(len == zfindexMax()) {
450 len = _ZFP_zfstring_len((const T_Char *)s);
451 }
452 if(len > replaceLen) {
453 _prepareWrite(lenTmp + len - replaceLen);
454 }
455 else {
456 _prepareWrite(lenTmp);
457 }
458 zfmemmove(d->d.buf + replacePos + len, d->d.buf + replacePos + replaceLen, (lenTmp - replacePos - replaceLen) * sizeof(T_Char));
459 zfmemcpy(d->d.buf + replacePos, s, len * sizeof(T_Char));
460 d->length = (zfuint)(lenTmp + len - replaceLen);
461 d->d.buf[d->length] = '\0';
462 }
463 return *this;
464 }
465
466public:
468 inline const T_Char *cString(void) const {
469 return d->d.ptr;
470 }
471
472 inline zfindex length(void) const {
473 return (zfindex)d->length;
474 }
475
476 inline zfbool isEmpty(void) const {
477 return d->length == 0;
478 }
479
480public:
483 if(capacity >= d->capacity) {
484 _capacityChange(capacity - 1, zftrue);
485 }
486 }
487
488 inline zfindex capacity(void) const {
489 return (zfindex)d->capacity;
490 }
491
492 inline void capacityTrim(void) {
493 if(d->capacity >= 128 && d->length < d->capacity / 3) {
494 _capacityChange(this->length(), zftrue);
495 }
496 }
497
498 void remove(
499 ZF_IN zfindex pos
501 ) {
502 zfindex lenTmp = this->length();
503 if(pos < lenTmp) {
504 if(len > lenTmp - pos) {
505 len = lenTmp - pos;
506 }
507 if(len > 0) {
508 _prepareWrite(lenTmp);
509 zfmemmove(d->d.buf + pos, d->d.buf + pos + len, (lenTmp - pos - len) * sizeof(T_Char));
510 d->length -= (zfuint)len;
511 d->d.buf[d->length] = '\0';
512 }
513 }
514 }
515
516 void removeAll(void) {
517 if(!this->isEmpty()) {
519 if(d->refCount == 1) {
520 if(d->capacity >= 128) {
521 zffree(d->d.buf);
522 zfpoolDelete(d);
523 d = _ZFP_Empty();
524 ++(d->refCount);
525 }
526 else if(d->capacity > 0) {
527 d->d.buf[0] = '\0';
528 d->length = 0;
529 }
530 else {
531 d->d.ptr = "";
532 d->length = 0;
533 }
534 }
535 else {
536 --(d->refCount);
537 d = _ZFP_Empty();
538 ++(d->refCount);
539 }
540 }
541 }
542
543public:
545 inline zfint compare(ZF_IN const zft_zfstring<T_Char> &s) const {
546 return d == s.d ? 0 : _ZFP_zfstring_cmp(this->cString(), s.cString());
547 }
548
550 ZF_IN const T_Char *s
551 , ZF_IN zfindex len = zfindexMax()
552 ) const {
553 if(len == zfindexMax()) {
554 len = s ? _ZFP_zfstring_len(s) : 0;
555 }
556 if(this->length() < len) {
557 return -1;
558 }
559 else if(this->length() > len) {
560 return 1;
561 }
562 else {
563 return _ZFP_zfstring_ncmp(this->cString(), s, len);
564 }
565 }
566
567public:
571 const void *buffer(void) const {
572 return d->d.ptr;
573 }
574
581 _prepareWrite(this->length());
582 T_Char *ret = d->d.buf;
583 zfpoolDelete(d);
584 d = _ZFP_Empty();
585 ++(d->refCount);
586 return ret;
587 }
588
591 static void zfunsafe_bufferFree(ZF_IN void *buf) {
592 zffree(buf);
593 }
594
598 T_Char *zfunsafe_buffer(void) {
599 _prepareWrite(this->length());
600 return d->d.buf;
601 }
602
606 _prepareWrite(this->length());
607 d->length = (zfuint)length;
608 }
609
610private:
611 _ZFP_zfstringD<T_Char> *d;
612public:
614 static inline const zft_zfstring<T_Char> &Empty(void) {
615 static const zft_zfstring<T_Char> d;
616 return d;
617 }
618public:
624 ZF_IN const void *sLiteral
626 ) {
627 _ZFP_zfstringD<T_Char> *d = zfpoolNew(_ZFP_zfstringD<T_Char>);
628 d->d.ptr = (const T_Char *)sLiteral;
629 d->length = (zfuint)(length == zfindexMax() ? _ZFP_zfstring_len((const T_Char *)sLiteral) : length);
630 return zft_zfstring<T_Char>(d);
631 }
632private:
633 explicit zft_zfstring(ZF_IN _ZFP_zfstringD<T_Char> *d)
634 : d(d)
635 {
636 }
637private:
638 static _ZFP_zfstringD<T_Char> *_ZFP_Empty(void) {
639 static _ZFP_zfstringH<T_Char> d;
640 return d.d;
641 }
642 static inline void _capacityOptimize(ZF_IN_OUT zfindex &capacity) {
643 if(capacity < 32) {
644 capacity = ((capacity / 16) + 1) * 16;
645 }
646 else if(capacity < 64) {
647 capacity = ((capacity / 32) + 1) * 32;
648 }
649 else if(capacity < 1024) {
650 capacity = ((capacity / 128) + 1) * 128;
651 }
652 else {
653 capacity = ((capacity / 1024) + 1) * 1024;
654 }
655 }
656 // capacity: excluding tail '\0'
657 void _capacityChange(ZF_IN zfindex capacity, zfbool keepContents) {
658 _capacityOptimize(capacity);
660 if(d->refCount == 1) {
661 if(d->capacity > 0) {
662 d->d.buf = (T_Char *)zfrealloc(d->d.buf, capacity * sizeof(T_Char));
663 }
664 else {
665 const T_Char *ptr = d->d.ptr;
666 d->d.buf = (T_Char *)zfmalloc(capacity * sizeof(T_Char));
667 if(ptr && keepContents) {
668 zfmemcpy(d->d.buf, ptr, capacity * sizeof(T_Char));
669 }
670 else {
671 d->d.buf[0] = '\0';
672 }
673 }
674 }
675 else {
676 _ZFP_zfstringD<T_Char> *dTmp = d;
677 d = zfpoolNew(_ZFP_zfstringD<T_Char>);
678 d->length = dTmp->length;
679 d->d.buf = (T_Char *)zfmalloc(capacity * sizeof(T_Char));
680 if(dTmp->length > 0 && keepContents) {
681 zfmemcpy(d->d.buf, dTmp->d.ptr, dTmp->length * sizeof(T_Char));
682 d->d.buf[dTmp->length] = '\0';
683 }
684 else {
685 d->d.buf[0] = '\0';
686 }
687 }
688 d->capacity = (zfuint)capacity;
689 if(!keepContents) {
690 d->length = 0;
691 }
692 }
693 inline void _prepareWrite(ZF_IN zfindex len) {
694 if(len >= d->capacity || d->refCount > 1) {
695 _capacityChange(len, zftrue);
696 }
697 }
698};
699
703#ifndef zftext
704 #define zftext(s) zfstring::shared(s)
705#endif
706
708
709#endif // #ifndef _ZFI_zfstring_h_
710
core mutex
#define ZFCoreMutexLocker()
util method to lock current block
Definition ZFCoreMutex.h:95
types for ZFFramework
zfindex zfslen(const zfchar *s)
strlen wrapper as zfchar type
Definition ZFCoreTypeDef_CharType.h:144
_ZFT_t_zfchar zfchar
char wrapper
Definition ZFCoreTypeDef_CharType.h:17
zfint zfsncmp(const zfchar *s1, const zfchar *s2, zfindex count)
strncmp wrapper as zfchar type
Definition ZFCoreTypeDef_CharType.h:158
zfint zfscmp(const zfchar *s1, const zfchar *s2)
strcmp wrapper as zfchar type
Definition ZFCoreTypeDef_CharType.h:152
types for ZFFramework
#define zfclassLikePOD
shows the class is not a POD type, but you may use it like a POD except memset it to 0
Definition ZFCoreTypeDef_ClassType.h:41
#define zffree(ptr)
same as free defined for future use, do nothing if ptr is NULL
Definition ZFCoreTypeDef_ClassType.h:112
#define ZF_IN
dummy macro that shows the param used as required input
Definition ZFCoreTypeDef_ClassType.h:180
#define ZF_IN_OPT
dummy macro that shows the param used as optional input
Definition ZFCoreTypeDef_ClassType.h:184
void * zfmemmove(void *dst, const void *src, zfindex size)
wrapper to memmove
Definition ZFCoreTypeDef_ClassType.h:142
#define zfclassNotPOD
shows the class is not a POD type, you should not memset it or declare it in stack or copy value by c...
Definition ZFCoreTypeDef_ClassType.h:48
#define ZF_IN_OUT
dummy macro that shows the param used as required input and output
Definition ZFCoreTypeDef_ClassType.h:196
#define zfrealloc(oldPtr, newSize)
same as realloc defined for future use
Definition ZFCoreTypeDef_ClassType.h:106
void * zfmemcpy(void *dst, const void *src, zfindex size)
wrapper to memcpy
Definition ZFCoreTypeDef_ClassType.h:140
#define zfmalloc(size)
same as malloc defined for future use
Definition ZFCoreTypeDef_ClassType.h:100
#define zfnullT
type for zfnull, can be used for function overload
Definition ZFCoreTypeDef_CoreType.h:85
_ZFT_t_zfbool zfbool
bool type
Definition ZFCoreTypeDef_CoreType.h:103
_ZFT_t_zfindex zfindex
similar to size_t, used for index and size only
Definition ZFCoreTypeDef_CoreType.h:154
#define zftrue
bool true type
Definition ZFCoreTypeDef_CoreType.h:107
_ZFT_t_zfint zfint
same as int, see zfindex
Definition ZFCoreTypeDef_CoreType.h:165
#define zfindexMax()
(zfindex)-1, indicate a max index value, see zfindex
Definition ZFCoreTypeDef_CoreType.h:159
#define zffalse
bool false type
Definition ZFCoreTypeDef_CoreType.h:111
#define zfnull
same as NULL, defined for future use
Definition ZFCoreTypeDef_CoreType.h:88
_ZFT_t_zfuint zfuint
same as unsigned int, see zfindex
Definition ZFCoreTypeDef_CoreType.h:169
memory pool
#define zfpoolDelete(obj)
see zfpoolNew
Definition ZFMemPool.h:38
#define zfpoolNew(T_Type,...)
internal use only, for allocating internal types for performance
Definition ZFMemPool.h:37
#define ZF_NAMESPACE_GLOBAL_BEGIN
begin namespace ZFFramework
Definition ZFNamespace.h:97
#define ZF_NAMESPACE_GLOBAL_END
end namespace ZFFramework
Definition ZFNamespace.h:98
ZFUIMargin & operator+=(ZFUIMargin &v0, const ZFUIMargin &v1)
v0 += v1
Definition ZFUITypeDef.h:325
ZFUIMargin operator+(const ZFUIMargin &v0, const ZFUIMargin &v1)
v0 + v1
Definition ZFUITypeDef.h:310
low level string container
Definition zfstring.h:89
void * zfunsafe_bufferGiveUp(void)
give up the buffer's ownership and return the buffer, you must free it manually by zfunsafe_bufferFre...
Definition zfstring.h:579
zft_zfstring< T_Char > & assign(const zft_zfstring< T_Char > &s, zfindex len)
replace all content of the string
Definition zfstring.h:338
zfint compare(const zft_zfstring< T_Char > &s) const
compare with another string
Definition zfstring.h:545
zft_zfstring(const zft_zfnullT &dummy)
construct empty string
Definition zfstring.h:157
T_Char get(zfindex pos) const
get char at index
Definition zfstring.h:240
void remove(zfindex pos, zfindex len=((zfindex) -1))
remove part of the string
Definition zfstring.h:498
zft_zfstring< T_Char > & assign(const zft_zfstring< T_Char > &s, zfindex offset, zfindex len)
replace all content of the string
Definition zfstring.h:345
zft_zfstring< zfchar > & assign(const zft_zfstring< zfchar > &s)
Definition zfstring.h:333
const T_Char * cString(void) const
access string value
Definition zfstring.h:468
void swap(zft_zfstring< T_Char > &ref)
swap internal data without deep copy, designed for performance
Definition zfstring.h:256
zft_zfstring< T_Char > & append(const void *s, zfindex len=((zfindex) -1))
append string
Definition zfstring.h:307
zft_zfstring< T_Char > & replace(zfindex replacePos, zfindex replaceLen, const void *s, zfindex len=((zfindex) -1))
replace string in range
Definition zfstring.h:435
zfint compare(const T_Char *s, zfindex len=((zfindex) -1)) const
compare with another string
Definition zfstring.h:549
zft_zfstring< T_Char > & append(const zft_zfstring< T_Char > &s)
append string
Definition zfstring.h:272
void zfunsafe_length(zfindex length)
directly modify the string's length
Definition zfstring.h:605
zft_zfstring(const T_Char *s, zfindex len)
copy content from another string
Definition zfstring.h:137
static void zfunsafe_bufferFree(void *buf)
free buffer returned by zfunsafe_bufferGiveUp
Definition zfstring.h:591
zft_zfstring(const T_Char *s)
copy content from another string
Definition zfstring.h:127
static const zft_zfstring< T_Char > & Empty(void)
global null string ref for impl
Definition zfstring.h:614
T_Char * zfunsafe_buffer(void)
directly access internal writable buffer
Definition zfstring.h:598
zft_zfstring(const zft_zfstring< T_Char > &s)
copy content from another string
Definition zfstring.h:99
zft_zfstring< T_Char > & insert(zfindex insertAt, const zft_zfstring< T_Char > &s)
insert string
Definition zfstring.h:394
void set(zfindex pos, T_Char c)
change char at index
Definition zfstring.h:230
zft_zfstring< T_Char > & append(const zft_zfstring< T_Char > &s, zfindex offset, zfindex len)
append string
Definition zfstring.h:290
zft_zfstring< T_Char > & assign(const zft_zfnullT &dummy)
replace all content of the string
Definition zfstring.h:387
zft_zfstring(const zft_zfstring< T_Char > &s, zfindex pos, zfindex len)
copy content from another string
Definition zfstring.h:114
zfindex length(void) const
Definition zfstring.h:472
zfindex capacity(void) const
get current capacity (including tail '\0')
Definition zfstring.h:488
zft_zfstring< T_Char > & assign(const void *s, zfindex len=((zfindex) -1))
replace all content of the string
Definition zfstring.h:359
zft_zfstring< T_Char > & insert(zfindex insertAt, const void *s, zfindex len=((zfindex) -1))
insert string
Definition zfstring.h:401
void capacity(zfindex capacity)
Definition zfstring.h:482
void capacityTrim(void)
trim to a proper capacity to save memory
Definition zfstring.h:492
zft_zfstring(const T_Char *s, zfindex pos, zfindex len)
copy content from another string
Definition zfstring.h:147
void removeAll(void)
Definition zfstring.h:516
zft_zfstring< T_Char > & append(const zft_zfstring< T_Char > &s, zfindex len)
append string
Definition zfstring.h:279
const void * buffer(void) const
return internal buffer
Definition zfstring.h:571
zft_zfstring(const zft_zfstring< T_Char > &s, zfindex len)
copy content from another string
Definition zfstring.h:106
static zft_zfstring< T_Char > shared(const void *sLiteral, zfindex length=((zfindex) -1))
explicitly create from literal string, you must ensure the literal's life exceeds the returned string
Definition zfstring.h:623
zfbool isEmpty(void) const
true if empty
Definition zfstring.h:476
zft_zfstring(void)
construct an empty string
Definition zfstring.h:92
zft_zfstring< T_Char > & replace(zfindex replacePos, zfindex replaceLen, const zft_zfstring< T_Char > &s)
replace string in range
Definition zfstring.h:427
zft_zfstring< T_Char > & append(T_Char c)
append string
Definition zfstring.h:265