49 friend class StringLH;
50 friend class StringDH;
58 Flag_LengthIsSizeShift = (
sizeof(UPInt) * 8 - 1)
65 DataDesc(
const DataDesc&);
71 Size = (UPInt(1) << String::Flag_LengthIsSizeShift);
79 std::atomic<SInt32> RefCount;
82 void AddRef() { RefCount.fetch_add(1); }
86 if (RefCount.fetch_add(-1) - 1 == 0)
90 static UPInt GetLengthFlagBit() {
return UPInt(1) << Flag_LengthIsSizeShift; }
91 UPInt GetSize()
const {
return Size & ~GetLengthFlagBit(); }
92 UPInt GetLengthFlag()
const {
return Size & GetLengthFlagBit(); }
93 bool LengthIsSize()
const {
return GetLengthFlag() != 0; }
114 inline HeapType GetHeapType()
const {
return (HeapType)(HeapTypeBits & HT_Mask); }
116 inline DataDesc* GetData()
const
120 u.HeapTypeBits = (u.HeapTypeBits & ~(UPInt)HT_Mask);
124 inline void SetData(DataDesc* pdesc)
126 HeapType ht = GetHeapType();
128 KY_ASSERT((HeapTypeBits & HT_Mask) == 0);
132 DataDesc* AllocData(MemoryHeap* pheap, UPInt size, UPInt lengthIsSize);
133 DataDesc* AllocDataCopy1(MemoryHeap* pheap, UPInt size, UPInt lengthIsSize,
const char* pdata, UPInt copySize);
134 DataDesc* AllocDataCopy2(MemoryHeap* pheap, UPInt size, UPInt lengthIsSize,
const char* pdata1, UPInt copySize1,
const char* pdata2, UPInt copySize2);
140 String(
const NoConstructor&) {}
143 static DataDesc& NullData();
148 virtual ~InitStruct() {}
149 virtual void InitString(
char* pbuffer, UPInt size)
const = 0;
154 String(
const char* data);
155 String(
const char* data1,
const char* pdata2,
const char* pdata3 = 0);
156 String(
const char* data, UPInt buflen);
157 String(
const String& src);
158 String(
const StringBuffer& src);
159 String(
const StringDataPtr src);
160 String(
const InitStruct& src, UPInt size);
161 explicit String(
const wchar_t* data);
164 ~String() { GetData()->Release(); }
166 MemoryHeap* GetHeap()
const;
173 operator const char*()
const {
return GetData()->Data; }
175 const char* ToCStr()
const {
return GetData()->Data; }
178 UPInt GetSize()
const {
return GetData()->GetSize(); }
180 bool IsEmpty()
const {
return GetSize() == 0; }
183 UPInt GetLength()
const;
186 UInt32 GetCharAt(UPInt index)
const;
187 UInt32 GetFirstCharAt(UPInt index,
const char** offset)
const;
188 UInt32 GetNextChar(
const char** offset)
const;
191 void AppendChar(
UInt32 ch);
194 void AppendString(
const wchar_t* pstr, SPInt len = -1);
195 void AppendString(
const char* putf8str, SPInt utf8StrSz = -1);
198 void AssignString(
const InitStruct& src, UPInt size);
201 void AssignString(
const char* putf8str, UPInt size);
207 void Remove(UPInt posAt, SPInt len = 1);
212 String Substring(UPInt start, UPInt end)
const;
215 String ToUpper()
const;
216 String ToLower()
const;
219 String& Insert(
const char* substr, UPInt posAt, SPInt len = -1);
222 UPInt InsertCharAt(
UInt32 c, UPInt posAt);
225 UPInt GetByteIndex(UPInt index)
const {
return (UPInt)UTF8Util::GetByteIndex(index, GetData()->Data); }
229 static int CompareNoCase(
const char* a,
const char* b);
230 static int CompareNoCase(
const char* a,
const char* b, SPInt len);
233 static UPInt BernsteinHashFunctionCIS(
const void* pdataIn, UPInt size, UPInt seed = 5381);
236 static UPInt BernsteinHashFunction(
const void* pdataIn, UPInt size, UPInt seed = 5381);
239 static void EscapeSpecialHTML(
const char* psrc, UPInt length, String* pescapedStr);
240 static void UnescapeSpecialHTML(
const char* psrc, UPInt length, String* punescapedStr);
250 static bool HasAbsolutePath(
const char* path);
251 static bool HasExtension(
const char* path);
252 static bool HasProtocol(
const char* path);
254 bool HasAbsolutePath()
const {
return HasAbsolutePath(ToCStr()); }
255 bool HasExtension()
const {
return HasExtension(ToCStr()); }
256 bool HasProtocol()
const {
return HasProtocol(ToCStr()); }
258 String GetProtocol()
const;
259 String GetPath()
const;
260 String GetFilename()
const;
261 String GetExtension()
const;
263 String& StripProtocol();
264 String& StripExtension();
268 void operator=(
const char* str);
269 void operator=(
const wchar_t* str);
270 void operator=(
const String& src);
271 void operator=(
const StringBuffer& src);
274 void operator+=(
const String& src);
275 void operator+=(
const char* psrc) { AppendString(psrc); }
276 void operator+=(
const wchar_t* psrc) { AppendString(psrc); }
277 void operator+=(
char ch) { AppendChar(ch); }
278 String operator+(
const char* str)
const;
279 String operator+(
const String& src)
const;
282 bool operator==(
const String& str)
const {
return (SFstrcmp(GetData()->Data, str.GetData()->Data) == 0); }
283 bool operator!=(
const String& str)
const {
return !operator==(str); }
284 bool operator==(
const char* str)
const {
return SFstrcmp(GetData()->Data, str) == 0; }
285 bool operator!=(
const char* str)
const {
return !operator==(str); }
286 bool operator<(
const char* pstr)
const {
return SFstrcmp(GetData()->Data, pstr) < 0; }
287 bool operator<(
const String& str)
const {
return *
this < str.GetData()->Data; }
288 bool operator>(
const char* pstr)
const {
return SFstrcmp(GetData()->Data, pstr) > 0; }
289 bool operator>(
const String& str)
const {
return *
this > str.GetData()->Data; }
291 int CompareNoCase(
const char* pstr)
const {
return CompareNoCase(GetData()->Data, pstr); }
292 int CompareNoCase(
const String& str)
const {
return CompareNoCase(GetData()->Data, str.ToCStr()); }
295 const char& operator[](
int index)
const
297 KY_ASSERT(index >= 0 && (UPInt)index < GetSize());
298 return GetData()->Data[index];
300 const char& operator[](UPInt index)
const
302 KY_ASSERT(index < GetSize());
303 return GetData()->Data[index];
311 NoCaseKey(
const String& str) : pStr(&str){};
314 bool operator==(
const NoCaseKey& strKey)
const {
return (CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0); }
315 bool operator!=(
const NoCaseKey& strKey)
const {
return !(CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0); }
320 UPInt operator()(
const String& data)
const
322 UPInt size = data.GetSize();
323 return String::BernsteinHashFunction((
const char*)data, size);
329 struct NoCaseHashFunctor
331 UPInt operator()(
const String& data)
const
333 UPInt size = data.GetSize();
334 return String::BernsteinHashFunctionCIS((
const char*)data, size);
336 UPInt operator()(
const NoCaseKey& data)
const
338 UPInt size = data.pStr->GetSize();
339 return String::BernsteinHashFunctionCIS((
const char*)data.pStr->ToCStr(), size);
350 class StringLH :
public String
353 void SetDataLcl(DataDesc* pdesc)
356 KY_ASSERT((HeapTypeBits & HT_Mask) == 0);
357 HeapTypeBits |= HT_Local;
360 void CopyConstructHelper(
const String& src);
365 StringLH(
const char* data);
366 StringLH(
const char* data, UPInt buflen);
368 StringLH(
const StringLH& src) : String(NoConstructor()) { CopyConstructHelper(src); }
369 explicit StringLH(
const String& src) : String(NoConstructor()) { CopyConstructHelper(src); }
370 explicit StringLH(
const InitStruct& src, UPInt size);
371 explicit StringLH(
const wchar_t* data);
374 void operator=(
const char* str) { String::operator=(str); }
375 void operator=(
const wchar_t* str) { String::operator=(str); }
376 void operator=(
const String& src) { String::operator=(src); }
377 void operator=(
const StringBuffer& src) { String::operator=(src); }
384 class StringDH :
public String
389 void SetDataLcl(DataDesc* pdesc)
392 KY_ASSERT((HeapTypeBits & HT_Mask) == 0);
393 HeapTypeBits |= HT_Dynamic;
396 void CopyConstructHelper(
const String& src, MemoryHeap* pheap);
400 StringDH(MemoryHeap* pheap = Memory::GetGlobalHeap());
401 StringDH(MemoryHeap* pheap,
const char* data);
402 StringDH(MemoryHeap* pheap,
const char* data1,
const char* pdata2,
const char* pdata3 = 0);
403 StringDH(MemoryHeap* pheap,
const char* data, UPInt buflen);
404 StringDH(
const StringDH& src) : String(NoConstructor()) { CopyConstructHelper(src, src.GetHeap()); }
405 explicit StringDH(
const String& src) : String(NoConstructor()) { CopyConstructHelper(src, 0); }
406 explicit StringDH(MemoryHeap* pheap,
const String& src) : String(NoConstructor()) { CopyConstructHelper(src, pheap); }
407 explicit StringDH(MemoryHeap* pheap,
const InitStruct& src, UPInt size);
408 explicit StringDH(MemoryHeap* pheap,
const wchar_t* data);
410 void operator=(
const char* str) { String::operator=(str); }
411 void operator=(
const wchar_t* str) { String::operator=(str); }
412 void operator=(
const String& src) { String::operator=(src); }
413 void operator=(
const StringBuffer& src) { String::operator=(src); }
415 MemoryHeap* GetHeap()
const {
return pHeap; }
426 mutable bool LengthIsSize;
431 StringBuffer(MemoryHeap* pheap = Memory::GetGlobalHeap());
432 explicit StringBuffer(UPInt growSize, MemoryHeap* pheap = Memory::GetGlobalHeap());
433 StringBuffer(
const char* data, MemoryHeap* pheap = Memory::GetGlobalHeap());
434 StringBuffer(
const char* data, UPInt buflen, MemoryHeap* pheap = Memory::GetGlobalHeap());
435 StringBuffer(
const String& src, MemoryHeap* pheap = Memory::GetGlobalHeap());
436 StringBuffer(
const StringBuffer& src, MemoryHeap* pheap = Memory::GetGlobalHeap());
437 explicit StringBuffer(
const wchar_t* data, MemoryHeap* pheap = Memory::GetGlobalHeap());
440 MemoryHeap* GetHeap()
const {
return pHeap; }
443 UPInt GetGrowSize()
const {
return GrowSize; }
444 void SetGrowSize(UPInt growSize);
452 operator const char*()
const {
return (pData) ? pData :
""; }
455 const char* ToCStr()
const {
return (pData) ? pData :
""; }
458 UPInt GetSize()
const {
return Size; }
460 bool IsEmpty()
const {
return GetSize() == 0; }
463 UPInt GetLength()
const;
466 UInt32 GetCharAt(UPInt index)
const;
467 UInt32 GetFirstCharAt(UPInt index,
const char** offset)
const;
468 UInt32 GetNextChar(
const char** offset)
const;
471 void Resize(UPInt _size);
472 void Reserve(UPInt _size);
475 void AppendChar(
UInt32 ch);
478 void AppendString(
const wchar_t* pstr, SPInt len = -1);
479 void AppendString(
const char* putf8str, SPInt utf8StrSz = -1);
482 void Insert(
const char* substr, UPInt posAt, SPInt len = -1);
484 UPInt InsertCharAt(
UInt32 c, UPInt posAt);
487 void operator=(
const char* str);
488 void operator=(
const wchar_t* str);
489 void operator=(
const String& src);
490 void operator=(
const StringBuffer& src);
493 void operator+=(
const StringBuffer& buff) { AppendString(buff.ToCStr(), buff.GetSize()); }
494 void operator+=(
const String& src) { AppendString(src.ToCStr(), src.GetSize()); }
495 void operator+=(
const char* psrc) { AppendString(psrc); }
496 void operator+=(
const wchar_t* psrc) { AppendString(psrc); }
497 void operator+=(
char ch) { AppendChar(ch); }
500 char& operator[](
int index)
502 KY_ASSERT(((UPInt)index) < GetSize());
505 char& operator[](UPInt index)
507 KY_ASSERT(index < GetSize());
511 const char& operator[](
int index)
const
513 KY_ASSERT(((UPInt)index) < GetSize());
516 const char& operator[](UPInt index)
const
518 KY_ASSERT(index < GetSize());
529 StringDataPtr() : pStr(NULL), Size(0) {}
530 StringDataPtr(
const StringDataPtr& p) : pStr(p.pStr), Size(p.Size) {}
531 StringDataPtr(
const char* pstr, UPInt sz) : pStr(pstr), Size(sz) {}
532 StringDataPtr(
const char* pstr) : pStr(pstr), Size((pstr != NULL) ? SFstrlen(pstr) : 0) {}
533 explicit StringDataPtr(
const String& str) : pStr(str.ToCStr()), Size(str.GetSize()) {}
534 template <
typename T,
int N>
535 StringDataPtr(
const T (&v)[N]) : pStr(v), Size(N) {}
539 char operator[](UPInt index)
const
541 KY_ASSERT(index < GetSize());
545 const char* ToCStr()
const {
return pStr; }
546 UPInt GetSize()
const {
return Size; }
547 bool IsEmpty()
const {
return GetSize() == 0; }
551 bool IsPrefix(
const StringDataPtr& value)
const {
return ToCStr() == value.ToCStr() && GetSize() >= value.GetSize(); }
555 bool IsSuffix(
const StringDataPtr& value)
const {
return ToCStr() <= value.ToCStr() && (End()) == (value.End()); }
559 SPInt FindChar(
char c, UPInt init_ind = 0)
const
561 for (UPInt i = init_ind; i < GetSize(); ++i)
563 return static_cast<SPInt
>(i);
570 SPInt FindLastChar(
char c, UPInt init_ind = ~0)
const;
573 SPInt FindSubstring(
const StringDataPtr& s, UPInt init_ind = 0)
const;
576 StringDataPtr GetTrimLeft(UPInt size)
const
578 size = Alg::PMin(GetSize(), size);
579 return StringDataPtr(ToCStr() + size, GetSize() - size);
582 StringDataPtr GetTrimRight(UPInt size)
const
584 size = Alg::PMin(GetSize(), size);
585 return StringDataPtr(ToCStr(), GetSize() - size);
589 StringDataPtr GetNextToken(
char separator =
':')
const;
592 StringDataPtr& TrimLeft(UPInt size)
594 size = Alg::PMin(GetSize(), size);
601 StringDataPtr& TrimRight(UPInt size)
603 size = Alg::PMin(GetSize(), size);
609 StringDataPtr GetPrefix(UPInt size)
const
611 size = Alg::PMin(GetSize(), size);
612 return StringDataPtr(ToCStr(), size);
616 StringDataPtr GetSuffix(UPInt size)
const
618 size = Alg::PMin(GetSize(), size);
619 return StringDataPtr(ToCStr() + GetSize() - size, size);
623 StringDataPtr& Prefix(UPInt size)
625 Size = Alg::PMin(GetSize(), size);
629 StringDataPtr& Suffix(UPInt size)
632 size = Alg::PMin(GetSize(), size);
633 pStr = ToCStr() + GetSize() - size;
638 static bool IsWhiteSpace(
UInt32 c);
640 StringDataPtr GetTruncateWhitespace()
const;
642 StringDataPtr& TruncateWhitespace()
644 *
this = GetTruncateWhitespace();
648 const char* Begin()
const {
return ToCStr(); }
649 const char* End()
const {
return ToCStr() + GetSize(); }
654 UPInt operator()(
const StringDataPtr& data)
const {
return String::BernsteinHashFunction(data.ToCStr(), data.GetSize()); }
657 bool operator==(
const StringDataPtr& other)
const {
return (other.Size == Size && (other.pStr == pStr || (pStr && other.pStr && SFstrncmp(pStr, other.pStr, Size) == 0))); }
658 bool operator!=(
const StringDataPtr& other)
const {
return !operator==(other); }
661 static StringDataPtr Null;
std::uint32_t UInt32
uint32_t
Definition: SF_Types.h:137
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17