19 #ifndef INC_KY_Kernel_String_H
20 #define INC_KY_Kernel_String_H
62 friend class StringLH;
63 friend class StringDH;
72 Flag_LengthIsSizeShift = (
sizeof(UPInt)*8 - 1)
82 volatile SInt32 RefCount;
87 AtomicOps<SInt32>::ExchangeAdd_NoSync(&RefCount, 1);
101 if ((AtomicOps<SInt32>::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0)
105 static UPInt GetLengthFlagBit() {
return UPInt(1) << Flag_LengthIsSizeShift; }
106 UPInt GetSize()
const {
return Size & ~GetLengthFlagBit() ; }
107 UPInt GetLengthFlag()
const {
return Size & GetLengthFlagBit(); }
108 bool LengthIsSize()
const {
return GetLengthFlag() != 0; }
129 inline HeapType GetHeapType()
const {
return (HeapType) (HeapTypeBits & HT_Mask); }
131 inline DataDesc* GetData()
const
135 u.HeapTypeBits = (u.HeapTypeBits & ~(UPInt)HT_Mask);
139 inline void SetData(DataDesc* pdesc)
141 HeapType ht = GetHeapType();
143 KY_ASSERT((HeapTypeBits & HT_Mask) == 0);
148 DataDesc* AllocData(MemoryHeap* pheap, UPInt size, UPInt lengthIsSize);
149 DataDesc* AllocDataCopy1(MemoryHeap* pheap, UPInt size, UPInt lengthIsSize,
150 const char* pdata, UPInt copySize);
151 DataDesc* AllocDataCopy2(MemoryHeap* pheap, UPInt size, UPInt lengthIsSize,
152 const char* pdata1, UPInt copySize1,
153 const char* pdata2, UPInt copySize2);
156 struct NoConstructor { };
157 String(
const NoConstructor&) { }
164 virtual ~InitStruct() { }
165 virtual void InitString(
char* pbuffer, UPInt size)
const = 0;
171 String(
const char* data);
172 String(
const char* data1,
const char* pdata2,
const char* pdata3 = 0);
173 String(
const char* data, UPInt buflen);
174 String(
const String& src);
175 String(
const StringBuffer& src);
176 String(
const StringDataPtr src);
177 String(
const InitStruct& src, UPInt size);
178 explicit String(
const wchar_t* data);
183 GetData()->Release();
187 static DataDesc NullData;
189 MemoryHeap* GetHeap()
const;
197 operator const char*()
const {
return GetData()->Data; }
199 const char* ToCStr()
const {
return GetData()->Data; }
202 UPInt GetSize()
const {
return GetData()->GetSize() ; }
204 bool IsEmpty()
const {
return GetSize() == 0; }
207 UPInt GetLength()
const;
210 UInt32 GetCharAt(UPInt index)
const;
211 UInt32 GetFirstCharAt(UPInt index,
const char** offset)
const;
212 UInt32 GetNextChar(
const char** offset)
const;
215 void AppendChar(UInt32 ch);
218 void AppendString(
const wchar_t* pstr, SPInt len = -1);
219 void AppendString(
const char* putf8str, SPInt utf8StrSz = -1);
222 void AssignString(
const InitStruct& src, UPInt size);
224 void AssignString(
const char* putf8str, UPInt size);
230 void Remove(UPInt posAt, SPInt len = 1);
235 String Substring(UPInt start, UPInt end)
const;
238 String ToUpper()
const;
239 String ToLower()
const;
242 String& Insert (
const char* substr, UPInt posAt, SPInt len = -1);
245 UPInt InsertCharAt(UInt32 c, UPInt posAt);
252 UPInt GetByteIndex(UPInt index)
const {
return (UPInt)UTF8Util::GetByteIndex(index, GetData()->Data); }
256 static int KY_STDCALL CompareNoCase(
const char* a,
const char* b);
257 static int KY_STDCALL CompareNoCase(
const char* a,
const char* b, SPInt len);
260 static UPInt KY_STDCALL BernsteinHashFunctionCIS(
const void* pdataIn, UPInt size, UPInt seed = 5381);
263 static UPInt KY_STDCALL BernsteinHashFunction(
const void* pdataIn, UPInt size, UPInt seed = 5381);
266 static void KY_STDCALL EscapeSpecialHTML(
const char* psrc, UPInt length, String* pescapedStr);
267 static void KY_STDCALL UnescapeSpecialHTML(
const char* psrc, UPInt length, String* punescapedStr);
278 static bool HasAbsolutePath(
const char* path);
279 static bool HasExtension(
const char* path);
280 static bool HasProtocol(
const char* path);
282 bool HasAbsolutePath()
const {
return HasAbsolutePath(ToCStr()); }
283 bool HasExtension()
const {
return HasExtension(ToCStr()); }
284 bool HasProtocol()
const {
return HasProtocol(ToCStr()); }
286 String GetProtocol()
const;
287 String GetPath()
const;
288 String GetFilename()
const;
289 String GetExtension()
const;
291 String& StripProtocol();
292 String& StripExtension();
297 void operator = (
const char* str);
298 void operator = (
const wchar_t* str);
299 void operator = (
const String& src);
300 void operator = (
const StringBuffer& src);
303 void operator += (
const String& src);
304 void operator += (
const char* psrc) { AppendString(psrc); }
305 void operator += (
const wchar_t* psrc) { AppendString(psrc); }
306 void operator += (
char ch) { AppendChar(ch); }
307 String operator + (
const char* str)
const;
308 String operator + (
const String& src)
const;
311 bool operator == (
const String& str)
const
313 return (SFstrcmp(GetData()->Data, str.GetData()->Data)== 0);
316 bool operator != (
const String& str)
const
318 return !operator == (str);
321 bool operator == (
const char* str)
const
323 return SFstrcmp(GetData()->Data, str) == 0;
326 bool operator != (
const char* str)
const
328 return !operator == (str);
331 bool operator < (
const char* pstr)
const
333 return SFstrcmp(GetData()->Data, pstr) < 0;
336 bool operator < (
const String& str)
const
338 return *
this < str.GetData()->Data;
341 bool operator > (
const char* pstr)
const
343 return SFstrcmp(GetData()->Data, pstr) > 0;
346 bool operator > (
const String& str)
const
348 return *
this > str.GetData()->Data;
351 int CompareNoCase(
const char* pstr)
const
353 return CompareNoCase(GetData()->Data, pstr);
355 int CompareNoCase(
const String& str)
const
357 return CompareNoCase(GetData()->Data, str.ToCStr());
361 const char& operator [] (
int index)
const
363 KY_ASSERT(index >= 0 && (UPInt)index < GetSize());
364 return GetData()->Data[index];
366 const char& operator [] (UPInt index)
const
368 KY_ASSERT(index < GetSize());
369 return GetData()->Data[index];
378 NoCaseKey(
const String &str) : pStr(&str){};
381 bool operator == (
const NoCaseKey& strKey)
const
383 return (CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0);
385 bool operator != (
const NoCaseKey& strKey)
const
387 return !(CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0);
393 UPInt operator()(
const String& data)
const
395 UPInt size = data.GetSize();
396 return String::BernsteinHashFunction((
const char*)data, size);
401 struct NoCaseHashFunctor
403 UPInt operator()(
const String& data)
const
405 UPInt size = data.GetSize();
406 return String::BernsteinHashFunctionCIS((
const char*)data, size);
408 UPInt operator()(
const NoCaseKey& data)
const
410 UPInt size = data.pStr->GetSize();
411 return String::BernsteinHashFunctionCIS((
const char*)data.pStr->ToCStr(), size);
426 class StringLH :
public String
429 void SetDataLcl(DataDesc* pdesc)
432 KY_ASSERT((HeapTypeBits & HT_Mask) == 0);
433 HeapTypeBits |= HT_Local;
436 void CopyConstructHelper(
const String& src);
441 StringLH(
const char* data);
442 StringLH(
const char* data, UPInt buflen);
444 StringLH(
const StringLH& src) : String(NoConstructor()) { CopyConstructHelper(src); }
445 explicit StringLH(
const String& src) : String(NoConstructor()) { CopyConstructHelper(src); }
446 explicit StringLH(
const InitStruct& src, UPInt size);
447 explicit StringLH(
const wchar_t* data);
450 void operator = (
const char* str) { String::operator = (str); }
451 void operator = (
const wchar_t* str) { String::operator = (str); }
452 void operator = (
const String& src) { String::operator = (src); }
453 void operator = (
const StringBuffer& src) { String::operator = (src); }
462 class StringDH :
public String
467 void SetDataLcl(DataDesc* pdesc)
470 KY_ASSERT((HeapTypeBits & HT_Mask) == 0);
471 HeapTypeBits |= HT_Dynamic;
474 void CopyConstructHelper(
const String& src, MemoryHeap* pheap);
478 StringDH(MemoryHeap* pheap = Memory::GetGlobalHeap());
479 StringDH(MemoryHeap* pheap,
const char* data);
480 StringDH(MemoryHeap* pheap,
const char* data1,
const char* pdata2,
const char* pdata3 = 0);
481 StringDH(MemoryHeap* pheap,
const char* data, UPInt buflen);
482 StringDH(
const StringDH& src) : String(NoConstructor()) { CopyConstructHelper(src, src.GetHeap()); }
483 explicit StringDH(
const String& src) : String(NoConstructor()) { CopyConstructHelper(src, 0); }
484 explicit StringDH(MemoryHeap* pheap,
const String& src) : String(NoConstructor()) { CopyConstructHelper(src, pheap); }
485 explicit StringDH(MemoryHeap* pheap,
const InitStruct& src, UPInt size);
486 explicit StringDH(MemoryHeap* pheap,
const wchar_t* data);
488 void operator = (
const char* str) { String::operator = (str); }
489 void operator = (
const wchar_t* str) { String::operator = (str); }
490 void operator = (
const String& src) { String::operator = (src); }
491 void operator = (
const StringBuffer& src) { String::operator = (src); }
493 MemoryHeap* GetHeap()
const {
return pHeap; }
507 mutable bool LengthIsSize;
513 StringBuffer(MemoryHeap* pheap = Memory::GetGlobalHeap());
514 explicit StringBuffer(UPInt growSize, MemoryHeap* pheap = Memory::GetGlobalHeap());
515 StringBuffer(
const char* data, MemoryHeap* pheap = Memory::GetGlobalHeap());
516 StringBuffer(
const char* data, UPInt buflen, MemoryHeap* pheap = Memory::GetGlobalHeap());
517 StringBuffer(
const String& src, MemoryHeap* pheap = Memory::GetGlobalHeap());
518 StringBuffer(
const StringBuffer& src, MemoryHeap* pheap = Memory::GetGlobalHeap());
519 explicit StringBuffer(
const wchar_t* data, MemoryHeap* pheap = Memory::GetGlobalHeap());
523 MemoryHeap* GetHeap()
const {
return pHeap; }
526 UPInt GetGrowSize()
const {
return GrowSize; }
527 void SetGrowSize(UPInt growSize);
535 operator const char*()
const {
return (pData) ? pData :
""; }
537 const char* ToCStr()
const {
return (pData) ? pData :
""; }
540 UPInt GetSize()
const {
return Size ; }
542 bool IsEmpty()
const {
return GetSize() == 0; }
545 UPInt GetLength()
const;
548 UInt32 GetCharAt(UPInt index)
const;
549 UInt32 GetFirstCharAt(UPInt index,
const char** offset)
const;
550 UInt32 GetNextChar(
const char** offset)
const;
554 void Resize(UPInt _size);
555 void Reserve(UPInt _size);
558 void AppendChar(UInt32 ch);
561 void AppendString(
const wchar_t* pstr, SPInt len = -1);
562 void AppendString(
const char* putf8str, SPInt utf8StrSz = -1);
568 void Insert (
const char* substr, UPInt posAt, SPInt len = -1);
570 UPInt InsertCharAt(UInt32 c, UPInt posAt);
573 void operator = (
const char* str);
574 void operator = (
const wchar_t* str);
575 void operator = (
const String& src);
576 void operator = (
const StringBuffer& src);
579 void operator += (
const StringBuffer& buff) { AppendString(buff.ToCStr(), buff.GetSize()); }
580 void operator += (
const String& src) { AppendString(src.ToCStr(),src.GetSize()); }
581 void operator += (
const char* psrc) { AppendString(psrc); }
582 void operator += (
const wchar_t* psrc) { AppendString(psrc); }
583 void operator += (
char ch) { AppendChar(ch); }
588 char& operator [] (
int index)
590 KY_ASSERT(((UPInt)index) < GetSize());
593 char& operator [] (UPInt index)
595 KY_ASSERT(index < GetSize());
599 const char& operator [] (
int index)
const
601 KY_ASSERT(((UPInt)index) < GetSize());
604 const char& operator [] (UPInt index)
const
606 KY_ASSERT(index < GetSize());
620 StringDataPtr() : pStr(NULL), Size(0) {}
621 StringDataPtr(
const StringDataPtr& p)
622 : pStr(p.pStr), Size(p.Size) {}
623 StringDataPtr(
const char* pstr, UPInt sz)
624 : pStr(pstr), Size(sz) {}
625 StringDataPtr(
const char* pstr)
626 : pStr(pstr), Size((pstr != NULL) ? SFstrlen(pstr) : 0) {}
627 explicit StringDataPtr(
const String& str)
628 : pStr(str.ToCStr()), Size(str.GetSize()) {}
629 template <
typename T,
int N>
630 StringDataPtr(
const T (&v)[N])
631 : pStr(v), Size(N) {}
635 char operator [] (UPInt index)
const
637 KY_ASSERT(index < GetSize());
641 const char* ToCStr()
const {
return pStr; }
642 UPInt GetSize()
const {
return Size; }
643 bool IsEmpty()
const {
return GetSize() == 0; }
647 bool IsPrefix(
const StringDataPtr& value)
const
649 return ToCStr() == value.ToCStr() && GetSize() >= value.GetSize();
653 bool IsSuffix(
const StringDataPtr& value)
const
655 return ToCStr() <= value.ToCStr() && (End()) == (value.End());
660 SPInt FindChar(
char c, UPInt init_ind = 0)
const
662 for (UPInt i = init_ind; i < GetSize(); ++i)
664 return static_cast<SPInt
>(i);
671 SPInt FindLastChar(
char c, UPInt init_ind = ~0)
const;
674 SPInt FindSubstring(
const StringDataPtr& s, UPInt init_ind = 0)
const;
677 StringDataPtr GetTrimLeft(UPInt size)
const
680 size = Alg::PMin(GetSize(), size);
682 return StringDataPtr(ToCStr() + size, GetSize() - size);
685 StringDataPtr GetTrimRight(UPInt size)
const
688 size = Alg::PMin(GetSize(), size);
690 return StringDataPtr(ToCStr(), GetSize() - size);
695 StringDataPtr GetNextToken(
char separator =
':')
const;
698 StringDataPtr& TrimLeft(UPInt size)
701 size = Alg::PMin(GetSize(), size);
708 StringDataPtr& TrimRight(UPInt size)
711 size = Alg::PMin(GetSize(), size);
718 StringDataPtr GetPrefix(UPInt size)
const
721 size = Alg::PMin(GetSize(), size);
723 return StringDataPtr(ToCStr(), size);
726 StringDataPtr GetSuffix(UPInt size)
const
729 size = Alg::PMin(GetSize(), size);
731 return StringDataPtr(ToCStr() + GetSize() - size, size);
735 StringDataPtr& Prefix(UPInt size)
738 Size = Alg::PMin(GetSize(), size);
743 StringDataPtr& Suffix(UPInt size)
746 size = Alg::PMin(GetSize(), size);
748 pStr = ToCStr() + GetSize() - size;
754 static bool IsWhiteSpace(UInt32 c);
756 StringDataPtr GetTruncateWhitespace()
const;
757 StringDataPtr& TruncateWhitespace()
759 *
this = GetTruncateWhitespace();
763 const char* Begin()
const {
return ToCStr(); }
764 const char* End()
const {
return ToCStr() + GetSize(); }
769 UPInt operator()(
const StringDataPtr& data)
const
771 return String::BernsteinHashFunction(data.ToCStr(), data.GetSize());
775 bool operator==(
const StringDataPtr& other)
const
777 return (other.Size == Size &&
778 (other.pStr == pStr ||
779 (pStr && other.pStr && SFstrncmp(pStr, other.pStr, Size) == 0)));
781 bool operator!=(
const StringDataPtr& other)
const
783 return !operator==(other);
787 static StringDataPtr Null;
Definition: gamekitcrowddispersion.h:20