| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855 |
- /************************************************************************************
- Filename : OVR_String.cpp
- Content : String UTF8 string implementation with copy-on-write semantics
- (thread-safe for assignment but not modification).
- Created : September 19, 2012
- Notes :
- Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
- Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
- you may not use the Oculus VR Rift SDK except in compliance with the License,
- which is provided at the time of installation or download, or which
- otherwise accompanies this software in either electronic or hard copy form.
- You may obtain a copy of the License at
- http://www.oculusvr.com/licenses/LICENSE-3.2
- Unless required by applicable law or agreed to in writing, the Oculus VR SDK
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ************************************************************************************/
- #include "OVR_String.h"
- #include <stdlib.h>
- #include <ctype.h>
- #ifdef OVR_OS_QNX
- # include <strings.h>
- #endif
- namespace OVR {
- #define String_LengthIsSize (size_t(1) << String::Flag_LengthIsSizeShift)
- String::DataDesc String::NullData = {String_LengthIsSize, AtomicInt<int32_t>(1), {0} };
- String::String()
- {
- pData = &NullData;
- pData->AddRef();
- };
- String::String(const char* pdata)
- {
- // Obtain length in bytes; it doesn't matter if _data is UTF8.
- size_t size = pdata ? OVR_strlen(pdata) : 0;
- pData = AllocDataCopy1(size, 0, pdata, size);
- };
- String::String(const char* pdata1, const char* pdata2, const char* pdata3)
- {
- // Obtain length in bytes; it doesn't matter if _data is UTF8.
- size_t size1 = pdata1 ? OVR_strlen(pdata1) : 0;
- size_t size2 = pdata2 ? OVR_strlen(pdata2) : 0;
- size_t size3 = pdata3 ? OVR_strlen(pdata3) : 0;
- DataDesc *pdataDesc = AllocDataCopy2(size1 + size2 + size3, 0,
- pdata1, size1, pdata2, size2);
- memcpy(pdataDesc->Data + size1 + size2, pdata3, size3);
- pData = pdataDesc;
- }
- String::String(const char* pdata, size_t size)
- {
- OVR_ASSERT((size == 0) || (pdata != 0));
- pData = AllocDataCopy1(size, 0, pdata, size);
- };
- String::String(const InitStruct& src, size_t size)
- {
- pData = AllocData(size, 0);
- src.InitString(GetData()->Data, size);
- }
- String::String(const String& src)
- {
- pData = src.GetData();
- pData->AddRef();
- }
- String::String(const StringBuffer& src)
- {
- pData = AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize());
- }
- String::String(const wchar_t* data)
- {
- pData = &NullData;
- pData->AddRef();
- // Simplified logic for wchar_t constructor.
- if (data)
- *this = data;
- }
- String::DataDesc* String::AllocData(size_t size, size_t lengthIsSize)
- {
- String::DataDesc* pdesc;
- if (size == 0)
- {
- pdesc = &NullData;
- pdesc->AddRef();
- return pdesc;
- }
- pdesc = (DataDesc*)OVR_ALLOC(sizeof(DataDesc)+ size);
- pdesc->Data[size] = 0;
- pdesc->RefCount = 1;
- pdesc->Size = size | lengthIsSize;
- return pdesc;
- }
- String::DataDesc* String::AllocDataCopy1(size_t size, size_t lengthIsSize,
- const char* pdata, size_t copySize)
- {
- String::DataDesc* pdesc = AllocData(size, lengthIsSize);
- memcpy(pdesc->Data, pdata, copySize);
- return pdesc;
- }
- String::DataDesc* String::AllocDataCopy2(size_t size, size_t lengthIsSize,
- const char* pdata1, size_t copySize1,
- const char* pdata2, size_t copySize2)
- {
- String::DataDesc* pdesc = AllocData(size, lengthIsSize);
- memcpy(pdesc->Data, pdata1, copySize1);
- memcpy(pdesc->Data + copySize1, pdata2, copySize2);
- return pdesc;
- }
- size_t String::GetLength() const
- {
- // Optimize length accesses for non-UTF8 character strings.
- DataDesc* pdata = GetData();
- size_t length, size = pdata->GetSize();
-
- if (pdata->LengthIsSize())
- return size;
-
- length = (size_t)UTF8Util::GetLength(pdata->Data, (size_t)size);
-
- if (length == size)
- pdata->Size |= String_LengthIsSize;
-
- return length;
- }
- //static uint32_t String_CharSearch(const char* buf, )
- uint32_t String::GetCharAt(size_t index) const
- {
- intptr_t i = (intptr_t) index;
- DataDesc* pdata = GetData();
- const char* buf = pdata->Data;
- uint32_t c;
-
- if (pdata->LengthIsSize())
- {
- OVR_ASSERT(index < pdata->GetSize());
- buf += i;
- return UTF8Util::DecodeNextChar_Advance0(&buf);
- }
- c = UTF8Util::GetCharAt(index, buf, pdata->GetSize());
- return c;
- }
- uint32_t String::GetFirstCharAt(size_t index, const char** offset) const
- {
- DataDesc* pdata = GetData();
- intptr_t i = (intptr_t) index;
- const char* buf = pdata->Data;
- const char* end = buf + pdata->GetSize();
- uint32_t c;
- do
- {
- c = UTF8Util::DecodeNextChar_Advance0(&buf);
- i--;
- if (buf >= end)
- {
- // We've hit the end of the string; don't go further.
- OVR_ASSERT(i == 0);
- return c;
- }
- } while (i >= 0);
- *offset = buf;
- return c;
- }
- uint32_t String::GetNextChar(const char** offset) const
- {
- return UTF8Util::DecodeNextChar(offset);
- }
- void String::AppendChar(uint32_t ch)
- {
- DataDesc* pdata = GetData();
- size_t size = pdata->GetSize();
- char buff[8];
- intptr_t encodeSize = 0;
- // Converts ch into UTF8 string and fills it into buff.
- UTF8Util::EncodeChar(buff, &encodeSize, ch);
- OVR_ASSERT(encodeSize >= 0);
- SetData(AllocDataCopy2(size + (size_t)encodeSize, 0,
- pdata->Data, size, buff, (size_t)encodeSize));
- pdata->Release();
- }
- void String::AppendString(const wchar_t* pstr, intptr_t len)
- {
- if (!pstr)
- return;
- DataDesc* pdata = GetData();
- size_t oldSize = pdata->GetSize();
- size_t encodeSize = (size_t)UTF8Util::GetEncodeStringSize(pstr, len);
- DataDesc* pnewData = AllocDataCopy1(oldSize + (size_t)encodeSize, 0,
- pdata->Data, oldSize);
- UTF8Util::EncodeString(pnewData->Data + oldSize, pstr, len);
- SetData(pnewData);
- pdata->Release();
- }
- void String::AppendString(const char* putf8str, intptr_t utf8StrSz)
- {
- if (!putf8str || !utf8StrSz)
- return;
- if (utf8StrSz == -1)
- utf8StrSz = (intptr_t)OVR_strlen(putf8str);
- DataDesc* pdata = GetData();
- size_t oldSize = pdata->GetSize();
- SetData(AllocDataCopy2(oldSize + (size_t)utf8StrSz, 0,
- pdata->Data, oldSize, putf8str, (size_t)utf8StrSz));
- pdata->Release();
- }
- void String::AssignString(const InitStruct& src, size_t size)
- {
- DataDesc* poldData = GetData();
- DataDesc* pnewData = AllocData(size, 0);
- src.InitString(pnewData->Data, size);
- SetData(pnewData);
- poldData->Release();
- }
- void String::AssignString(const char* putf8str, size_t size)
- {
- DataDesc* poldData = GetData();
- SetData(AllocDataCopy1(size, 0, putf8str, size));
- poldData->Release();
- }
- void String::operator = (const char* pstr)
- {
- AssignString(pstr, pstr ? OVR_strlen(pstr) : 0);
- }
- void String::operator = (const wchar_t* pwstr)
- {
- pwstr = pwstr ? pwstr : L"";
- DataDesc* poldData = GetData();
- size_t size = (size_t)UTF8Util::GetEncodeStringSize(pwstr);
- DataDesc* pnewData = AllocData(size, 0);
- UTF8Util::EncodeString(pnewData->Data, pwstr);
- SetData(pnewData);
- poldData->Release();
- }
- void String::operator = (const String& src)
- {
- DataDesc* psdata = src.GetData();
- DataDesc* pdata = GetData();
- SetData(psdata);
- psdata->AddRef();
- pdata->Release();
- }
- void String::operator = (const StringBuffer& src)
- {
- DataDesc* polddata = GetData();
- SetData(AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize()));
- polddata->Release();
- }
- void String::operator += (const String& src)
- {
- DataDesc *pourData = GetData(),
- *psrcData = src.GetData();
- size_t ourSize = pourData->GetSize(),
- srcSize = psrcData->GetSize();
- size_t lflag = pourData->GetLengthFlag() & psrcData->GetLengthFlag();
- SetData(AllocDataCopy2(ourSize + srcSize, lflag,
- pourData->Data, ourSize, psrcData->Data, srcSize));
- pourData->Release();
- }
- String String::operator + (const char* str) const
- {
- String tmp1(*this);
- tmp1 += (str ? str : "");
- return tmp1;
- }
- String String::operator + (const String& src) const
- {
- String tmp1(*this);
- tmp1 += src;
- return tmp1;
- }
- void String::Remove(size_t posAt, intptr_t removeLength)
- {
- DataDesc* pdata = GetData();
- size_t oldSize = pdata->GetSize();
- // Length indicates the number of characters to remove.
- size_t length = GetLength();
- // If index is past the string, nothing to remove.
- if (posAt >= length)
- return;
- // Otherwise, cap removeLength to the length of the string.
- if ((posAt + removeLength) > length)
- removeLength = length - posAt;
- // Get the byte position of the UTF8 char at position posAt.
- intptr_t bytePos = UTF8Util::GetByteIndex(posAt, pdata->Data, oldSize);
- intptr_t removeSize = UTF8Util::GetByteIndex(removeLength, pdata->Data + bytePos, oldSize-bytePos);
- SetData(AllocDataCopy2(oldSize - removeSize, pdata->GetLengthFlag(),
- pdata->Data, bytePos,
- pData->Data + bytePos + removeSize, (oldSize - bytePos - removeSize)));
- pdata->Release();
- }
- String String::Substring(size_t start, size_t end) const
- {
- size_t length = GetLength();
- if ((start >= length) || (start >= end))
- return String();
- DataDesc* pdata = GetData();
-
- // If size matches, we know the exact index range.
- if (pdata->LengthIsSize())
- return String(pdata->Data + start, end - start);
-
- // Get position of starting character.
- intptr_t byteStart = UTF8Util::GetByteIndex(start, pdata->Data, pdata->GetSize());
- intptr_t byteSize = UTF8Util::GetByteIndex(end - start, pdata->Data + byteStart, pdata->GetSize()-byteStart);
- return String(pdata->Data + byteStart, (size_t)byteSize);
- }
- void String::Clear()
- {
- NullData.AddRef();
- GetData()->Release();
- SetData(&NullData);
- }
- String String::ToUpper() const
- {
- uint32_t c;
- const char* psource = GetData()->Data;
- const char* pend = psource + GetData()->GetSize();
- String str;
- intptr_t bufferOffset = 0;
- char buffer[512];
-
- while(psource < pend)
- {
- do {
- c = UTF8Util::DecodeNextChar_Advance0(&psource);
- UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towupper(wchar_t(c)));
- } while ((psource < pend) && (bufferOffset < intptr_t(sizeof(buffer)-8)));
- // Append string a piece at a time.
- str.AppendString(buffer, bufferOffset);
- bufferOffset = 0;
- }
- return str;
- }
- String String::ToLower() const
- {
- uint32_t c;
- const char* psource = GetData()->Data;
- const char* pend = psource + GetData()->GetSize();
- String str;
- intptr_t bufferOffset = 0;
- char buffer[512];
- while(psource < pend)
- {
- do {
- c = UTF8Util::DecodeNextChar_Advance0(&psource);
- UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towlower(wchar_t(c)));
- } while ((psource < pend) && (bufferOffset < intptr_t(sizeof(buffer)-8)));
- // Append string a piece at a time.
- str.AppendString(buffer, bufferOffset);
- bufferOffset = 0;
- }
- return str;
- }
- String& String::Insert(const char* substr, size_t posAt, intptr_t strSize)
- {
- DataDesc* poldData = GetData();
- size_t oldSize = poldData->GetSize();
- size_t insertSize = (strSize < 0) ? OVR_strlen(substr) : (size_t)strSize;
- size_t byteIndex = (poldData->LengthIsSize()) ?
- posAt : (size_t)UTF8Util::GetByteIndex(posAt, poldData->Data, oldSize);
- OVR_ASSERT(byteIndex <= oldSize);
-
- DataDesc* pnewData = AllocDataCopy2(oldSize + insertSize, 0,
- poldData->Data, byteIndex, substr, insertSize);
- memcpy(pnewData->Data + byteIndex + insertSize,
- poldData->Data + byteIndex, oldSize - byteIndex);
- SetData(pnewData);
- poldData->Release();
- return *this;
- }
- /*
- String& String::Insert(const uint32_t* substr, size_t posAt, intptr_t len)
- {
- for (intptr_t i = 0; i < len; ++i)
- {
- size_t charw = InsertCharAt(substr[i], posAt);
- posAt += charw;
- }
- return *this;
- }
- */
- size_t String::InsertCharAt(uint32_t c, size_t posAt)
- {
- char buf[8];
- intptr_t index = 0;
- UTF8Util::EncodeChar(buf, &index, c);
- OVR_ASSERT(index >= 0);
- buf[(size_t)index] = 0;
- Insert(buf, posAt, index);
- return (size_t)index;
- }
- int String::CompareNoCase(const char* a, const char* b)
- {
- return OVR_stricmp(a, b);
- }
- int String::CompareNoCase(const char* a, const char* b, intptr_t len)
- {
- if (len)
- {
- intptr_t f,l;
- intptr_t slen = len;
- const char *s = b;
- do {
- f = (intptr_t)OVR_tolower((int)(*(a++)));
- l = (intptr_t)OVR_tolower((int)(*(b++)));
- } while (--len && f && (f == l) && *b != 0);
- if (f == l && (len != 0 || *b != 0))
- {
- f = (intptr_t)slen;
- l = (intptr_t)OVR_strlen(s);
- return int(f - l);
- }
- return int(f - l);
- }
- else
- return (0-(int)OVR_strlen(b));
- }
- // ***** Implement hash static functions
- // Hash function
- size_t String::BernsteinHashFunction(const void* pdataIn, size_t size, size_t seed)
- {
- const uint8_t* pdata = (const uint8_t*) pdataIn;
- size_t h = seed;
- while (size > 0)
- {
- size--;
- h = ((h << 5) + h) ^ (unsigned) pdata[size];
- }
- return h;
- }
- // Hash function, case-insensitive
- size_t String::BernsteinHashFunctionCIS(const void* pdataIn, size_t size, size_t seed)
- {
- const uint8_t* pdata = (const uint8_t*) pdataIn;
- size_t h = seed;
- while (size > 0)
- {
- size--;
- h = ((h << 5) + h) ^ OVR_tolower(pdata[size]);
- }
- // Alternative: "sdbm" hash function, suggested at same web page above.
- // h = 0;
- // for bytes { h = (h << 16) + (h << 6) - hash + *p; }
- return h;
- }
- // ***** String Buffer used for Building Strings
- #define OVR_SBUFF_DEFAULT_GROW_SIZE 512
- // Constructors / Destructor.
- StringBuffer::StringBuffer()
- : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
- {
- }
- StringBuffer::StringBuffer(size_t growSize)
- : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
- {
- SetGrowSize(growSize);
- }
- StringBuffer::StringBuffer(const char* data)
- : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
- {
- AppendString(data);
- }
- StringBuffer::StringBuffer(const char* data, size_t dataSize)
- : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
- {
- AppendString(data, dataSize);
- }
- StringBuffer::StringBuffer(const String& src)
- : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
- {
- AppendString(src.ToCStr(), src.GetSize());
- }
- StringBuffer::StringBuffer(const StringBuffer& src)
- : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
- {
- AppendString(src.ToCStr(), src.GetSize());
- }
- StringBuffer::StringBuffer(const wchar_t* data)
- : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
- {
- *this = data;
- }
- StringBuffer::~StringBuffer()
- {
- if (pData)
- OVR_FREE(pData);
- }
- void StringBuffer::SetGrowSize(size_t growSize)
- {
- if (growSize <= 16)
- GrowSize = 16;
- else
- {
- uint8_t bits = Alg::UpperBit(uint32_t(growSize-1));
- size_t size = (size_t)1 << bits;
- GrowSize = size == growSize ? growSize : size;
- }
- }
- size_t StringBuffer::GetLength() const
- {
- size_t length, size = GetSize();
- if (LengthIsSize)
- return size;
- length = (size_t)UTF8Util::GetLength(pData, (size_t)GetSize());
- if (length == GetSize())
- LengthIsSize = true;
- return length;
- }
- void StringBuffer::Reserve(size_t _size)
- {
- if (_size >= BufferSize) // >= because of trailing zero! (!AB)
- {
- BufferSize = (_size + 1 + GrowSize - 1)& ~(GrowSize-1);
- if (!pData)
- pData = (char*)OVR_ALLOC(BufferSize);
- else
- pData = (char*)OVR_REALLOC(pData, BufferSize);
- }
- }
- void StringBuffer::Resize(size_t _size)
- {
- Reserve(_size);
- LengthIsSize = false;
- Size = _size;
- if (pData)
- pData[Size] = 0;
- }
- void StringBuffer::Clear()
- {
- Resize(0);
- /*
- if (pData != pEmptyNullData)
- {
- OVR_FREE(pHeap, pData);
- pData = pEmptyNullData;
- Size = BufferSize = 0;
- LengthIsSize = false;
- }
- */
- }
- // Appends a character
- void StringBuffer::AppendChar(uint32_t ch)
- {
- char buff[8];
- size_t origSize = GetSize();
- // Converts ch into UTF8 string and fills it into buff. Also increments index according to the number of bytes
- // in the UTF8 string.
- intptr_t srcSize = 0;
- UTF8Util::EncodeChar(buff, &srcSize, ch);
- OVR_ASSERT(srcSize >= 0);
-
- size_t size = origSize + srcSize;
- Resize(size);
- OVR_ASSERT(pData != NULL);
- memcpy(pData + origSize, buff, srcSize);
- }
- // Append a string
- void StringBuffer::AppendString(const wchar_t* pstr, intptr_t len)
- {
- if (!pstr || !len)
- return;
- intptr_t srcSize = UTF8Util::GetEncodeStringSize(pstr, len);
- size_t origSize = GetSize();
- size_t size = srcSize + origSize;
- Resize(size);
- OVR_ASSERT(pData != NULL);
- UTF8Util::EncodeString(pData + origSize, pstr, len);
- }
- void StringBuffer::AppendString(const char* putf8str, intptr_t utf8StrSz)
- {
- if (!putf8str || !utf8StrSz)
- return;
- if (utf8StrSz == -1)
- utf8StrSz = (intptr_t)OVR_strlen(putf8str);
- size_t origSize = GetSize();
- size_t size = utf8StrSz + origSize;
- Resize(size);
- OVR_ASSERT(pData != NULL);
- memcpy(pData + origSize, putf8str, utf8StrSz);
- }
- // If pstr is NULL then the StringBuffer is cleared.
- void StringBuffer::operator = (const char* pstr)
- {
- pstr = pstr ? pstr : "";
- size_t size = OVR_strlen(pstr);
- Resize(size);
- OVR_ASSERT((pData != NULL) || (size == 0));
- memcpy(pData, pstr, size);
- }
- // If pstr is NULL then the StringBuffer is cleared.
- void StringBuffer::operator = (const wchar_t* pstr)
- {
- pstr = pstr ? pstr : L"";
- size_t size = (size_t)UTF8Util::GetEncodeStringSize(pstr);
- Resize(size);
- OVR_ASSERT((pData != NULL) || (size == 0));
- UTF8Util::EncodeString(pData, pstr);
- }
- void StringBuffer::operator = (const String& src)
- {
- const size_t size = src.GetSize();
- Resize(size);
- OVR_ASSERT((pData != NULL) || (size == 0));
- memcpy(pData, src.ToCStr(), size);
- }
- void StringBuffer::operator = (const StringBuffer& src)
- {
- Clear();
- AppendString(src.ToCStr(), src.GetSize());
- }
- // Inserts substr at posAt
- void StringBuffer::Insert(const char* substr, size_t posAt, intptr_t len)
- {
- size_t oldSize = Size;
- size_t insertSize = (len < 0) ? OVR_strlen(substr) : (size_t)len;
- size_t byteIndex = LengthIsSize ? posAt :
- (size_t)UTF8Util::GetByteIndex(posAt, pData, (intptr_t)Size);
- OVR_ASSERT(byteIndex <= oldSize);
- Reserve(oldSize + insertSize);
- OVR_ASSERT(pData != NULL); // pData is unilaterally written to below.
- memmove(pData + byteIndex + insertSize, pData + byteIndex, oldSize - byteIndex + 1);
- memcpy (pData + byteIndex, substr, insertSize);
- LengthIsSize = false;
- Size = oldSize + insertSize;
- pData[Size] = 0;
- }
- // Inserts character at posAt
- size_t StringBuffer::InsertCharAt(uint32_t c, size_t posAt)
- {
- char buf[8];
- intptr_t len = 0;
- UTF8Util::EncodeChar(buf, &len, c);
- OVR_ASSERT(len >= 0);
- buf[(size_t)len] = 0;
- Insert(buf, posAt, len);
- return (size_t)len;
- }
- std::wstring UTF8StringToUCSString(const char* pUTF8, size_t length)
- {
- if(length == (size_t)-1)
- length = strlen(pUTF8);
- std::wstring returnValue(length, wchar_t(0)); // We'll possibly trim this value below.
- // Note that DecodeString doesn't handle UTF8 encoding errors.
- size_t decodedLength = OVR::UTF8Util::DecodeString(&returnValue[0], pUTF8, (intptr_t)length);
- OVR_ASSERT(decodedLength <= length);
- returnValue.resize(decodedLength);
- return returnValue;
- }
- std::wstring UTF8StringToUCSString(const std::string& sUTF8)
- {
- return UTF8StringToUCSString(sUTF8.data(), sUTF8.size());
- }
- std::wstring OVRStringToUCSString(const OVR::String& sOVRUTF8)
- {
- return UTF8StringToUCSString(sOVRUTF8.ToCStr(), sOVRUTF8.GetSize());
- }
- std::string UCSStringToUTF8String(const wchar_t* pUCS, size_t length)
- {
- if(length == (size_t)-1)
- length = wcslen(pUCS);
- std::string sUTF8;
- intptr_t requiredUTF8Length = OVR::UTF8Util::GetEncodeStringSize(pUCS, length); // GetEncodeStringSize returns required strlen. We assume it returns an error if < 0.
- if (requiredUTF8Length >= 0)
- {
- sUTF8.resize(requiredUTF8Length);
- OVR::UTF8Util::EncodeString(&sUTF8[0], pUCS, length);
- }
- return sUTF8;
- }
- std::string UCSStringToUTF8String(const std::wstring& sUCS)
- {
- return UCSStringToUTF8String(sUCS.data(), sUCS.size());
- }
- OVR::String UCSStringToOVRString(const wchar_t* pUCS, size_t length)
- {
- if(length == (size_t)-1)
- length = wcslen(pUCS);
- // We use a std::string intermediate because OVR::String doesn't support resize or assignment without preallocated data.
- const std::string sUTF8 = UCSStringToUTF8String(pUCS, length);
- const OVR::String sOVRUTF8(sUTF8.data(), sUTF8.size());
- return sOVRUTF8;
- }
- OVR::String UCSStringToOVRString(const std::wstring& sUCS)
- {
- return UCSStringToOVRString(sUCS.data(), sUCS.length());
- }
- } // OVR
|