6#ifndef _ZFI_zfstring_h_
7#define _ZFI_zfstring_h_
17template<
typename T_Char>
26template<
typename T_Char>
27zfint _ZFP_zfstring_cmp(
28 ZF_IN const T_Char *s1
29 ,
ZF_IN const T_Char *s1End
30 ,
ZF_IN const T_Char *s2
31 ,
ZF_IN const T_Char *s2End
33 while(s1 < s1End && s2 < s2End && *s1 == *s2) {++s1, ++s2;}
52template<
typename T_Char>
63 _ZFP_zfstringD(
void) : refCount(1), capacity(0), length(0), d() {
66 ~_ZFP_zfstringD(
void) {
72 static const T_Char *Empty(
void) {
73 static T_Char buf[1] = {0};
77template<
typename T_Char>
80 _ZFP_zfstringH(
void) : d(
zfpoolNew(_ZFP_zfstringD<T_Char>)) {}
83 _ZFP_zfstringD<T_Char> *d;
90template<
typename T_Char>
113 this->
assign(s.cString(), len);
121 if(pos < s.length()) {
122 if(len > s.length() - pos) {
123 len = s.length() - pos;
125 this->
assign(s.cString() + pos, len);
155 this->
assign(s + pos, len);
167 if(--(d->refCount) == 0) {
174 inline operator const T_Char * (void)
const {
175 return this->isEmpty() ?
zfnull : this->cString();
180 _ZFP_zfstringD<T_Char> *dTmp = d;
183 if(--(dTmp->refCount) == 0) {
192 zfbool operator == (
ZF_IN const T_Char *ref)
const {
return this->isEqual(ref);}
193 zfbool operator != (
ZF_IN const T_Char *ref)
const {
return !this->isEqual(ref);}
210 template<
typename T_Int>
212 return this->cString() + offset;
224 _prepareWrite(this->length());
231 return d->d.ptr[pos];
235 template<
typename T_Int>
236 inline T_Char operator [] (
ZF_IN T_Int pos)
const {
237 return this->get(pos);
248 _ZFP_zfstringD<T_Char> *dTmp = d;
256 _prepareWrite(d->length + 1);
257 d->d.buf[d->length] = c;
258 d->d.buf[++(d->length)] =
'\0';
264 _appendImpl(s.cString(), s.length());
273 len = (len <= s.length() ? len : s.length());
275 _appendImpl(s.cString(), len);
285 if(offset > s.length()) {
288 if(len > s.length() - offset) {
289 len = s.length() - offset;
292 _appendImpl(s.cString() + offset, len);
303 len = _ZFP_zfstring_len((
const T_Char *)s);
316 _prepareWrite(d->length + len);
317 zfmemcpy(d->d.buf + d->length, s, len *
sizeof(T_Char));
318 d->d.buf[d->length += (
zfuint)len] =
'\0';
324 this->operator = (s);
332 return this->
assign(s.cString(), len <= s.length() ? len : s.length());
340 if(offset > s.length()) {
343 if(len > s.length() - offset) {
344 len = s.length() - offset;
346 return this->
assign(s.cString() + offset, len);
355 len = _ZFP_zfstring_len((
const T_Char *)s);
362 if(len >= d->capacity || d->refCount > 1
363 || (d->capacity >= 128 && len < d->
capacity / 3)
368 zfmemcpy(d->d.buf, s, len *
sizeof(T_Char));
369 d->d.buf[len] =
'\0';
388 return this->
insert(insertAt, s.cString(), s.length());
393 ,
ZF_IN const void *s
396 if(insertAt >= this->length()) {
401 len = _ZFP_zfstring_len((
const T_Char *)s);
404 zfindex lenTmp = this->length();
405 _prepareWrite(lenTmp + len);
406 d->length = (
zfuint)(lenTmp + len);
407 zfmemmove(d->d.buf + insertAt + len, d->d.buf + insertAt, (lenTmp - insertAt) *
sizeof(T_Char));
408 zfmemcpy(d->d.buf + insertAt, s, len *
sizeof(T_Char));
409 d->d.buf[d->length] =
'\0';
422 return this->
replace(replacePos, replaceLen, s.cString(), s.length());
428 ,
ZF_IN const void *s
431 if(replacePos >= this->length()) {
435 zfindex lenTmp = this->length();
436 if(replaceLen > lenTmp - replacePos) {
437 replaceLen = lenTmp - replacePos;
440 len = _ZFP_zfstring_len((
const T_Char *)s);
442 if(len > replaceLen) {
443 _prepareWrite(lenTmp + len - replaceLen);
446 _prepareWrite(lenTmp);
448 zfmemmove(d->d.buf + replacePos + len, d->d.buf + replacePos + replaceLen, (lenTmp - replacePos - replaceLen) *
sizeof(T_Char));
449 zfmemcpy(d->d.buf + replacePos, s, len *
sizeof(T_Char));
450 d->length = (
zfuint)(lenTmp + len - replaceLen);
451 d->d.buf[d->length] =
'\0';
467 return d->length == 0;
471 return d == ref.d || (this->length() == ref.length() && this->
compare(ref) == 0);
475 return 0 == _ZFP_zfstring_cmp(this->
cString(), this->
cString() + this->length(), s, s + (s ? _ZFP_zfstring_len(s) : 0));
494 if(d->capacity >= 128 && d->length < d->capacity / 3) {
495 _capacityChange(this->length(),
zftrue);
503 zfindex lenTmp = this->length();
505 if(len > lenTmp - pos) {
509 _prepareWrite(lenTmp);
510 zfmemmove(d->d.buf + pos, d->d.buf + pos + len, (lenTmp - pos - len) *
sizeof(T_Char));
512 d->d.buf[d->length] =
'\0';
520 if(d->refCount == 1) {
521 if(d->capacity >= 128) {
522 if(--(d->refCount) == 0) {
528 else if(d->capacity > 0) {
533 d->d.ptr = _ZFP_zfstringD<T_Char>::Empty();
538 if(--(d->refCount) == 0) {
550 return d == s.d ? 0 : _ZFP_zfstring_cmp(this->
cString(), this->
cString() + this->length(), s.cString(), s.cString() + s.length());
554 ZF_IN const T_Char *s
558 len = s ? _ZFP_zfstring_len(s) : 0;
560 return _ZFP_zfstring_cmp(this->
cString(), this->
cString() + this->length(), s, s + (s ? _ZFP_zfstring_len(s) : 0));
577 _prepareWrite(this->length());
578 ret = (
void *)d->d.buf;
583 d->d.ptr = _ZFP_zfstringD<T_Char>::Empty();
600 _prepareWrite(this->length());
607 _prepareWrite(this->length());
612 _ZFP_zfstringD<T_Char> *d;
625 ZF_IN const void *sLiteral
628 _ZFP_zfstringD<T_Char> *d =
zfpoolNew(_ZFP_zfstringD<T_Char>);
629 d->d.ptr = (
const T_Char *)sLiteral;
639 static _ZFP_zfstringD<T_Char> *_ZFP_Empty(
void) {
640 static _ZFP_zfstringH<T_Char> d;
645 capacity = ((capacity / 16) + 1) * 16;
647 else if(capacity < 64) {
648 capacity = ((capacity / 32) + 1) * 32;
652 capacity |= capacity >> 1;
653 capacity |= capacity >> 2;
654 capacity |= capacity >> 4;
655 capacity |= capacity >> 8;
656 capacity |= capacity >> 16;
663 _capacityOptimize(capacity);
665 if(d->refCount == 1) {
666 if(d->capacity > 0) {
667 T_Char *buf = (T_Char *)
zfpoolRealloc(d->d.buf, capacity *
sizeof(T_Char));
674 const T_Char *ptr = d->d.ptr;
675 T_Char *buf = (T_Char *)
zfpoolMalloc(capacity *
sizeof(T_Char));
680 if(ptr && keepContents) {
681 zfmemcpy(d->d.buf, ptr, capacity *
sizeof(T_Char));
689 T_Char *buf = (T_Char *)
zfpoolMalloc(capacity *
sizeof(T_Char));
693 _ZFP_zfstringD<T_Char> *dTmp = d;
695 d->length = dTmp->length;
697 if(dTmp->length > 0 && keepContents) {
698 zfmemcpy(d->d.buf, dTmp->d.ptr, dTmp->length *
sizeof(T_Char));
699 d->d.buf[dTmp->length] =
'\0';
705 d->capacity = (
zfuint)capacity;
712 if(len >= d->capacity || d->refCount > 1) {
713 _capacityChange(len,
zftrue);
722 #define zftext(s) zfstring::shared(s)
#define ZFCoreMutexLocker()
util method to lock current block
Definition ZFCoreMutex.h:95
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
#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 ZF_IN
dummy macro that shows the param used as required input
Definition ZFCoreTypeDef_ClassType.h:191
#define ZF_IN_OPT
dummy macro that shows the param used as optional input
Definition ZFCoreTypeDef_ClassType.h:195
void * zfmemmove(void *dst, const void *src, zfindex size)
wrapper to memmove
Definition ZFCoreTypeDef_ClassType.h:153
#define ZF_OUT
dummy macro that shows the param used as required output
Definition ZFCoreTypeDef_ClassType.h:199
#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:207
void * zfmemcpy(void *dst, const void *src, zfindex size)
wrapper to memcpy
Definition ZFCoreTypeDef_ClassType.h:151
#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
#define zfpoolDelete(obj)
see zfpoolNew
Definition ZFMemPool.h:36
#define zfpoolRealloc(p, size)
see zfpoolMalloc
Definition ZFMemPool.h:57
#define zfpoolFree(p)
see zfpoolMalloc
Definition ZFMemPool.h:58
#define zfpoolNew(T_Type,...)
internal use only, for allocating internal types for performance
Definition ZFMemPool.h:35
#define zfpoolMalloc(size)
internal use only, for allocating internal types for performance
Definition ZFMemPool.h:56
#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:91
zft_zfstring< T_Char > & assign(const zft_zfstring< T_Char > &s, zfindex len)
replace all content of the string
Definition zfstring.h:328
zfint compare(const zft_zfstring< zfchar > &s) const
Definition zfstring.h:549
zft_zfstring(const zft_zfnullT &dummy)
construct empty string
Definition zfstring.h:159
zfbool capacity(zfindex capacity)
Definition zfstring.h:480
T_Char get(zfindex pos) const
get char at index
Definition zfstring.h:230
void remove(zfindex pos, zfindex len=((zfindex) -1))
remove part of the string
Definition zfstring.h:499
zft_zfstring< T_Char > & assign(const zft_zfstring< T_Char > &s, zfindex offset, zfindex len)
replace all content of the string
Definition zfstring.h:335
zft_zfstring< zfchar > & assign(const zft_zfstring< zfchar > &s)
Definition zfstring.h:323
const T_Char * cString(void) const
access string value
Definition zfstring.h:458
void swap(zft_zfstring< T_Char > &ref)
swap internal data without deep copy, designed for performance
Definition zfstring.h:246
zft_zfstring< T_Char > & append(const void *s, zfindex len=((zfindex) -1))
append string
Definition zfstring.h:297
void zfunsafe_bufferGiveUp(void *&ret, zfindex &length)
give up the buffer's ownership and return the buffer, you must free it manually by zfunsafe_bufferFre...
Definition zfstring.h:575
zft_zfstring< T_Char > & replace(zfindex replacePos, zfindex replaceLen, const void *s, zfindex len=((zfindex) -1))
replace string in range
Definition zfstring.h:425
zfint compare(const T_Char *s, zfindex len=((zfindex) -1)) const
compare with another string
Definition zfstring.h:553
zft_zfstring< T_Char > & append(const zft_zfstring< T_Char > &s)
append string
Definition zfstring.h:262
void zfunsafe_length(zfindex length)
directly modify the string's length
Definition zfstring.h:606
zft_zfstring(const T_Char *s, zfindex len)
copy content from another string
Definition zfstring.h:139
static void zfunsafe_bufferFree(void *buf)
free buffer returned by zfunsafe_bufferGiveUp
Definition zfstring.h:592
zft_zfstring(const T_Char *s)
copy content from another string
Definition zfstring.h:129
static const zft_zfstring< T_Char > & Empty(void)
global null string ref for impl
Definition zfstring.h:615
T_Char * zfunsafe_buffer(void)
directly access internal writable buffer
Definition zfstring.h:599
zft_zfstring(const zft_zfstring< T_Char > &s)
copy content from another string
Definition zfstring.h:101
zft_zfstring< T_Char > & insert(zfindex insertAt, const zft_zfstring< T_Char > &s)
insert string
Definition zfstring.h:384
void set(zfindex pos, T_Char c)
change char at index
Definition zfstring.h:220
zft_zfstring< T_Char > & append(const zft_zfstring< T_Char > &s, zfindex offset, zfindex len)
append string
Definition zfstring.h:280
zft_zfstring< T_Char > & assign(const zft_zfnullT &dummy)
replace all content of the string
Definition zfstring.h:377
zfbool isEqual(const zft_zfstring< T_Char > &ref) const
true if equal
Definition zfstring.h:470
zft_zfstring(const zft_zfstring< T_Char > &s, zfindex pos, zfindex len)
copy content from another string
Definition zfstring.h:116
zfindex length(void) const
length of the string
Definition zfstring.h:462
zfindex capacity(void) const
get current capacity (including tail '\0')
Definition zfstring.h:489
zft_zfstring< T_Char > & assign(const void *s, zfindex len=((zfindex) -1))
replace all content of the string
Definition zfstring.h:349
zft_zfstring< T_Char > & insert(zfindex insertAt, const void *s, zfindex len=((zfindex) -1))
insert string
Definition zfstring.h:391
void capacityTrim(void)
trim to a proper capacity to save memory
Definition zfstring.h:493
zft_zfstring(const T_Char *s, zfindex pos, zfindex len)
copy content from another string
Definition zfstring.h:149
void removeAll(void)
Definition zfstring.h:517
zft_zfstring< T_Char > & append(const zft_zfstring< T_Char > &s, zfindex len)
append string
Definition zfstring.h:269
const void * buffer(void) const
return internal buffer
Definition zfstring.h:567
zft_zfstring(const zft_zfstring< T_Char > &s, zfindex len)
copy content from another string
Definition zfstring.h:108
zfbool isEqual(const T_Char *s) const
true if equal
Definition zfstring.h:474
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:624
zfbool isEmpty(void) const
true if empty
Definition zfstring.h:466
zft_zfstring(void)
construct an empty string
Definition zfstring.h:94
zft_zfstring< T_Char > & replace(zfindex replacePos, zfindex replaceLen, const zft_zfstring< T_Char > &s)
replace string in range
Definition zfstring.h:417
zft_zfstring< T_Char > & append(T_Char c)
append string
Definition zfstring.h:255