OVR_String.cpp
Go to the documentation of this file.
00001 /************************************************************************************
00002 
00003 Filename    :   OVR_String.cpp
00004 Content     :   String UTF8 string implementation with copy-on-write semantics
00005                 (thread-safe for assignment but not modification).
00006 Created     :   September 19, 2012
00007 Notes       : 
00008 
00009 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
00010 
00011 Use of this software is subject to the terms of the Oculus license
00012 agreement provided at the time of installation or download, or which
00013 otherwise accompanies this software in either electronic or hard copy form.
00014 
00015 ************************************************************************************/
00016 
00017 #include "OVR_String.h"
00018 
00019 #include <stdlib.h>
00020 #include <ctype.h>
00021 
00022 #ifdef OVR_OS_QNX
00023 # include <strings.h>
00024 #endif
00025 
00026 namespace OVR {
00027 
00028 #define String_LengthIsSize (UPInt(1) << String::Flag_LengthIsSizeShift)
00029 
00030 String::DataDesc String::NullData = {String_LengthIsSize, 1, {0} };
00031 
00032 
00033 String::String()
00034 {
00035     pData = &NullData;
00036     pData->AddRef();
00037 };
00038 
00039 String::String(const char* pdata)
00040 {
00041     // Obtain length in bytes; it doesn't matter if _data is UTF8.
00042     UPInt size = pdata ? OVR_strlen(pdata) : 0; 
00043     pData = AllocDataCopy1(size, 0, pdata, size);
00044 };
00045 
00046 String::String(const char* pdata1, const char* pdata2, const char* pdata3)
00047 {
00048     // Obtain length in bytes; it doesn't matter if _data is UTF8.
00049     UPInt size1 = pdata1 ? OVR_strlen(pdata1) : 0; 
00050     UPInt size2 = pdata2 ? OVR_strlen(pdata2) : 0; 
00051     UPInt size3 = pdata3 ? OVR_strlen(pdata3) : 0; 
00052 
00053     DataDesc *pdataDesc = AllocDataCopy2(size1 + size2 + size3, 0,
00054                                          pdata1, size1, pdata2, size2);
00055     memcpy(pdataDesc->Data + size1 + size2, pdata3, size3);   
00056     pData = pdataDesc;    
00057 }
00058 
00059 String::String(const char* pdata, UPInt size)
00060 {
00061     OVR_ASSERT((size == 0) || (pdata != 0));
00062     pData = AllocDataCopy1(size, 0, pdata, size);
00063 };
00064 
00065 
00066 String::String(const InitStruct& src, UPInt size)
00067 {
00068     pData = AllocData(size, 0);
00069     src.InitString(GetData()->Data, size);
00070 }
00071 
00072 String::String(const String& src)
00073 {    
00074     pData = src.GetData();
00075     pData->AddRef();
00076 }
00077 
00078 String::String(const StringBuffer& src)
00079 {
00080     pData = AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize());
00081 }
00082 
00083 String::String(const wchar_t* data)
00084 {
00085     pData = &NullData;
00086     pData->AddRef();
00087     // Simplified logic for wchar_t constructor.
00088     if (data)    
00089         *this = data;    
00090 }
00091 
00092 
00093 String::DataDesc* String::AllocData(UPInt size, UPInt lengthIsSize)
00094 {
00095     String::DataDesc* pdesc;
00096 
00097     if (size == 0)
00098     {
00099         pdesc = &NullData;
00100         pdesc->AddRef();
00101         return pdesc;
00102     }
00103 
00104     pdesc = (DataDesc*)OVR_ALLOC(sizeof(DataDesc)+ size);
00105     pdesc->Data[size] = 0;
00106     pdesc->RefCount = 1;
00107     pdesc->Size     = size | lengthIsSize;  
00108     return pdesc;
00109 }
00110 
00111 
00112 String::DataDesc* String::AllocDataCopy1(UPInt size, UPInt lengthIsSize,
00113                                          const char* pdata, UPInt copySize)
00114 {
00115     String::DataDesc* pdesc = AllocData(size, lengthIsSize);
00116     memcpy(pdesc->Data, pdata, copySize);
00117     return pdesc;
00118 }
00119 
00120 String::DataDesc* String::AllocDataCopy2(UPInt size, UPInt lengthIsSize,
00121                                          const char* pdata1, UPInt copySize1,
00122                                          const char* pdata2, UPInt copySize2)
00123 {
00124     String::DataDesc* pdesc = AllocData(size, lengthIsSize);
00125     memcpy(pdesc->Data, pdata1, copySize1);
00126     memcpy(pdesc->Data + copySize1, pdata2, copySize2);
00127     return pdesc;
00128 }
00129 
00130 
00131 UPInt String::GetLength() const 
00132 {
00133     // Optimize length accesses for non-UTF8 character strings. 
00134     DataDesc* pdata = GetData();
00135     UPInt     length, size = pdata->GetSize();
00136     
00137     if (pdata->LengthIsSize())
00138         return size;    
00139     
00140     length = (UPInt)UTF8Util::GetLength(pdata->Data, (UPInt)size);
00141     
00142     if (length == size)
00143         pdata->Size |= String_LengthIsSize;
00144     
00145     return length;
00146 }
00147 
00148 
00149 //static UInt32 String_CharSearch(const char* buf, )
00150 
00151 
00152 UInt32 String::GetCharAt(UPInt index) const 
00153 {  
00154     SPInt       i = (SPInt) index;
00155     DataDesc*   pdata = GetData();
00156     const char* buf = pdata->Data;
00157     UInt32      c;
00158     
00159     if (pdata->LengthIsSize())
00160     {
00161         OVR_ASSERT(index < pdata->GetSize());
00162         buf += i;
00163         return UTF8Util::DecodeNextChar_Advance0(&buf);
00164     }
00165 
00166     c = UTF8Util::GetCharAt(index, buf, pdata->GetSize());
00167     return c;
00168 }
00169 
00170 UInt32 String::GetFirstCharAt(UPInt index, const char** offset) const
00171 {
00172     DataDesc*   pdata = GetData();
00173     SPInt       i = (SPInt) index;
00174     const char* buf = pdata->Data;
00175     const char* end = buf + pdata->GetSize();
00176     UInt32      c;
00177 
00178     do 
00179     {
00180         c = UTF8Util::DecodeNextChar_Advance0(&buf);
00181         i--;
00182 
00183         if (buf >= end)
00184         {
00185             // We've hit the end of the string; don't go further.
00186             OVR_ASSERT(i == 0);
00187             return c;
00188         }
00189     } while (i >= 0);
00190 
00191     *offset = buf;
00192 
00193     return c;
00194 }
00195 
00196 UInt32 String::GetNextChar(const char** offset) const
00197 {
00198     return UTF8Util::DecodeNextChar(offset);
00199 }
00200 
00201 
00202 
00203 void String::AppendChar(UInt32 ch)
00204 {
00205     DataDesc*   pdata = GetData();
00206     UPInt       size = pdata->GetSize();
00207     char        buff[8];
00208     SPInt       encodeSize = 0;
00209 
00210     // Converts ch into UTF8 string and fills it into buff.   
00211     UTF8Util::EncodeChar(buff, &encodeSize, ch);
00212     OVR_ASSERT(encodeSize >= 0);
00213 
00214     SetData(AllocDataCopy2(size + (UPInt)encodeSize, 0,
00215                            pdata->Data, size, buff, (UPInt)encodeSize));
00216     pdata->Release();
00217 }
00218 
00219 
00220 void String::AppendString(const wchar_t* pstr, SPInt len)
00221 {
00222     if (!pstr)
00223         return;
00224 
00225     DataDesc*   pdata = GetData();
00226     UPInt       oldSize = pdata->GetSize();    
00227     UPInt       encodeSize = (UPInt)UTF8Util::GetEncodeStringSize(pstr, len);
00228 
00229     DataDesc*   pnewData = AllocDataCopy1(oldSize + (UPInt)encodeSize, 0,
00230                                           pdata->Data, oldSize);
00231     UTF8Util::EncodeString(pnewData->Data + oldSize,  pstr, len);
00232 
00233     SetData(pnewData);
00234     pdata->Release();
00235 }
00236 
00237 
00238 void String::AppendString(const char* putf8str, SPInt utf8StrSz)
00239 {
00240     if (!putf8str || !utf8StrSz)
00241         return;
00242     if (utf8StrSz == -1)
00243         utf8StrSz = (SPInt)OVR_strlen(putf8str);
00244 
00245     DataDesc*   pdata = GetData();
00246     UPInt       oldSize = pdata->GetSize();
00247 
00248     SetData(AllocDataCopy2(oldSize + (UPInt)utf8StrSz, 0,
00249                            pdata->Data, oldSize, putf8str, (UPInt)utf8StrSz));
00250     pdata->Release();
00251 }
00252 
00253 void    String::AssignString(const InitStruct& src, UPInt size)
00254 {
00255     DataDesc*   poldData = GetData();
00256     DataDesc*   pnewData = AllocData(size, 0);
00257     src.InitString(pnewData->Data, size);
00258     SetData(pnewData);
00259     poldData->Release();
00260 }
00261 
00262 void    String::AssignString(const char* putf8str, UPInt size)
00263 {
00264     DataDesc* poldData = GetData();
00265     SetData(AllocDataCopy1(size, 0, putf8str, size));
00266     poldData->Release();
00267 }
00268 
00269 void    String::operator = (const char* pstr)
00270 {
00271     AssignString(pstr, pstr ? OVR_strlen(pstr) : 0);
00272 }
00273 
00274 void    String::operator = (const wchar_t* pwstr)
00275 {
00276     DataDesc*   poldData = GetData();
00277     UPInt       size = pwstr ? (UPInt)UTF8Util::GetEncodeStringSize(pwstr) : 0;
00278 
00279     DataDesc*   pnewData = AllocData(size, 0);
00280     UTF8Util::EncodeString(pnewData->Data, pwstr);
00281     SetData(pnewData);
00282     poldData->Release();
00283 }
00284 
00285 
00286 void    String::operator = (const String& src)
00287 {     
00288     DataDesc*    psdata = src.GetData();
00289     DataDesc*    pdata = GetData();    
00290 
00291     SetData(psdata);
00292     psdata->AddRef();
00293     pdata->Release();
00294 }
00295 
00296 
00297 void    String::operator = (const StringBuffer& src)
00298 { 
00299     DataDesc* polddata = GetData();    
00300     SetData(AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize()));
00301     polddata->Release();
00302 }
00303 
00304 void    String::operator += (const String& src)
00305 {
00306     DataDesc   *pourData = GetData(),
00307                *psrcData = src.GetData();
00308     UPInt       ourSize  = pourData->GetSize(),
00309                 srcSize  = psrcData->GetSize();
00310     UPInt       lflag    = pourData->GetLengthFlag() & psrcData->GetLengthFlag();
00311 
00312     SetData(AllocDataCopy2(ourSize + srcSize, lflag,
00313                            pourData->Data, ourSize, psrcData->Data, srcSize));
00314     pourData->Release();
00315 }
00316 
00317 
00318 String   String::operator + (const char* str) const
00319 {   
00320     String tmp1(*this);
00321     tmp1 += (str ? str : "");
00322     return tmp1;
00323 }
00324 
00325 String   String::operator + (const String& src) const
00326 { 
00327     String tmp1(*this);
00328     tmp1 += src;
00329     return tmp1;
00330 }
00331 
00332 void    String::Remove(UPInt posAt, SPInt removeLength)
00333 {
00334     DataDesc*   pdata = GetData();
00335     UPInt       oldSize = pdata->GetSize();    
00336     // Length indicates the number of characters to remove. 
00337     UPInt       length = GetLength();
00338 
00339     // If index is past the string, nothing to remove.
00340     if (posAt >= length)
00341         return;
00342     // Otherwise, cap removeLength to the length of the string.
00343     if ((posAt + removeLength) > length)
00344         removeLength = length - posAt;
00345 
00346     // Get the byte position of the UTF8 char at position posAt.
00347     SPInt bytePos    = UTF8Util::GetByteIndex(posAt, pdata->Data, oldSize);
00348     SPInt removeSize = UTF8Util::GetByteIndex(removeLength, pdata->Data + bytePos, oldSize-bytePos);
00349 
00350     SetData(AllocDataCopy2(oldSize - removeSize, pdata->GetLengthFlag(),
00351                            pdata->Data, bytePos,
00352                            pData->Data + bytePos + removeSize, (oldSize - bytePos - removeSize)));
00353     pdata->Release();
00354 }
00355 
00356 
00357 String   String::Substring(UPInt start, UPInt end) const
00358 {
00359     UPInt length = GetLength();
00360     if ((start >= length) || (start >= end))
00361         return String();   
00362 
00363     DataDesc* pdata = GetData();
00364     
00365     // If size matches, we know the exact index range.
00366     if (pdata->LengthIsSize())
00367         return String(pdata->Data + start, end - start);
00368     
00369     // Get position of starting character.
00370     SPInt byteStart = UTF8Util::GetByteIndex(start, pdata->Data, pdata->GetSize());
00371     SPInt byteSize  = UTF8Util::GetByteIndex(end - start, pdata->Data + byteStart, pdata->GetSize()-byteStart);
00372     return String(pdata->Data + byteStart, (UPInt)byteSize);
00373 }
00374 
00375 void String::Clear()
00376 {   
00377     NullData.AddRef();
00378     GetData()->Release();
00379     SetData(&NullData);
00380 }
00381 
00382 
00383 String   String::ToUpper() const 
00384 {       
00385     UInt32      c;
00386     const char* psource = GetData()->Data;
00387     const char* pend = psource + GetData()->GetSize();
00388     String      str;
00389     SPInt       bufferOffset = 0;
00390     char        buffer[512];
00391     
00392     while(psource < pend)
00393     {
00394         do {            
00395             c = UTF8Util::DecodeNextChar_Advance0(&psource);
00396             UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towupper(wchar_t(c)));
00397         } while ((psource < pend) && (bufferOffset < SPInt(sizeof(buffer)-8)));
00398 
00399         // Append string a piece at a time.
00400         str.AppendString(buffer, bufferOffset);
00401         bufferOffset = 0;
00402     }
00403 
00404     return str;
00405 }
00406 
00407 String   String::ToLower() const 
00408 {
00409     UInt32      c;
00410     const char* psource = GetData()->Data;
00411     const char* pend = psource + GetData()->GetSize();
00412     String      str;
00413     SPInt       bufferOffset = 0;
00414     char        buffer[512];
00415 
00416     while(psource < pend)
00417     {
00418         do {
00419             c = UTF8Util::DecodeNextChar_Advance0(&psource);
00420             UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towlower(wchar_t(c)));
00421         } while ((psource < pend) && (bufferOffset < SPInt(sizeof(buffer)-8)));
00422 
00423         // Append string a piece at a time.
00424         str.AppendString(buffer, bufferOffset);
00425         bufferOffset = 0;
00426     }
00427 
00428     return str;
00429 }
00430 
00431 
00432 
00433 String& String::Insert(const char* substr, UPInt posAt, SPInt strSize)
00434 {
00435     DataDesc* poldData   = GetData();
00436     UPInt     oldSize    = poldData->GetSize();
00437     UPInt     insertSize = (strSize < 0) ? OVR_strlen(substr) : (UPInt)strSize;    
00438     UPInt     byteIndex  =  (poldData->LengthIsSize()) ?
00439                             posAt : (UPInt)UTF8Util::GetByteIndex(posAt, poldData->Data, oldSize);
00440 
00441     OVR_ASSERT(byteIndex <= oldSize);
00442     
00443     DataDesc* pnewData = AllocDataCopy2(oldSize + insertSize, 0,
00444                                         poldData->Data, byteIndex, substr, insertSize);
00445     memcpy(pnewData->Data + byteIndex + insertSize,
00446            poldData->Data + byteIndex, oldSize - byteIndex);
00447     SetData(pnewData);
00448     poldData->Release();
00449     return *this;
00450 }
00451 
00452 /*
00453 String& String::Insert(const UInt32* substr, UPInt posAt, SPInt len)
00454 {
00455     for (SPInt i = 0; i < len; ++i)
00456     {
00457         UPInt charw = InsertCharAt(substr[i], posAt);
00458         posAt += charw;
00459     }
00460     return *this;
00461 }
00462 */
00463 
00464 UPInt String::InsertCharAt(UInt32 c, UPInt posAt)
00465 {
00466     char    buf[8];
00467     SPInt   index = 0;
00468     UTF8Util::EncodeChar(buf, &index, c);
00469     OVR_ASSERT(index >= 0);
00470     buf[(UPInt)index] = 0;
00471 
00472     Insert(buf, posAt, index);
00473     return (UPInt)index;
00474 }
00475 
00476 
00477 int String::CompareNoCase(const char* a, const char* b)
00478 {
00479     return OVR_stricmp(a, b);
00480 }
00481 
00482 int String::CompareNoCase(const char* a, const char* b, SPInt len)
00483 {
00484     if (len)
00485     {
00486         SPInt f,l;
00487         SPInt slen = len;
00488         const char *s = b;
00489         do {
00490             f = (SPInt)OVR_tolower((int)(*(a++)));
00491             l = (SPInt)OVR_tolower((int)(*(b++)));
00492         } while (--len && f && (f == l) && *b != 0);
00493 
00494         if (f == l && (len != 0 || *b != 0))
00495         {
00496             f = (SPInt)slen;
00497             l = (SPInt)OVR_strlen(s);
00498             return int(f - l);
00499         }
00500 
00501         return int(f - l);
00502     }
00503     else
00504         return (0-(int)OVR_strlen(b));
00505 }
00506 
00507 // ***** Implement hash static functions
00508 
00509 // Hash function
00510 UPInt String::BernsteinHashFunction(const void* pdataIn, UPInt size, UPInt seed)
00511 {
00512     const UByte*    pdata   = (const UByte*) pdataIn;
00513     UPInt           h       = seed;
00514     while (size > 0)
00515     {
00516         size--;
00517         h = ((h << 5) + h) ^ (unsigned) pdata[size];
00518     }
00519 
00520     return h;
00521 }
00522 
00523 // Hash function, case-insensitive
00524 UPInt String::BernsteinHashFunctionCIS(const void* pdataIn, UPInt size, UPInt seed)
00525 {
00526     const UByte*    pdata = (const UByte*) pdataIn;
00527     UPInt           h = seed;
00528     while (size > 0)
00529     {
00530         size--;
00531         h = ((h << 5) + h) ^ OVR_tolower(pdata[size]);
00532     }
00533 
00534     // Alternative: "sdbm" hash function, suggested at same web page above.
00535     // h = 0;
00536     // for bytes { h = (h << 16) + (h << 6) - hash + *p; }
00537     return h;
00538 }
00539 
00540 
00541 
00542 // ***** String Buffer used for Building Strings
00543 
00544 
00545 #define OVR_SBUFF_DEFAULT_GROW_SIZE 512
00546 // Constructors / Destructor.
00547 StringBuffer::StringBuffer()
00548     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
00549 {
00550 }
00551 
00552 StringBuffer::StringBuffer(UPInt growSize)
00553     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
00554 {
00555     SetGrowSize(growSize);
00556 }
00557 
00558 StringBuffer::StringBuffer(const char* data)
00559     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
00560 {
00561     *this = data;
00562 }
00563 
00564 StringBuffer::StringBuffer(const char* data, UPInt dataSize)
00565     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
00566 {
00567     AppendString(data, dataSize);
00568 }
00569 
00570 StringBuffer::StringBuffer(const String& src)
00571     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
00572 {
00573     AppendString(src.ToCStr(), src.GetSize());
00574 }
00575 
00576 StringBuffer::StringBuffer(const StringBuffer& src)
00577     : pData(NULL), Size(0), BufferSize(src.GetGrowSize()), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
00578 {
00579     AppendString(src.ToCStr(), src.GetSize());
00580     LengthIsSize = src.LengthIsSize;
00581 }
00582 
00583 StringBuffer::StringBuffer(const wchar_t* data)
00584     : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false)
00585 {
00586     *this = data;
00587 }
00588 
00589 StringBuffer::~StringBuffer()
00590 {
00591     if (pData)
00592         OVR_FREE(pData);
00593 }
00594 void StringBuffer::SetGrowSize(UPInt growSize) 
00595 { 
00596     if (growSize <= 16)
00597         GrowSize = 16;
00598     else
00599     {
00600         UByte bits = Alg::UpperBit(UInt32(growSize-1));
00601         UPInt size = 1<<bits;
00602         GrowSize = size == growSize ? growSize : size;
00603     }
00604 }
00605 
00606 UPInt StringBuffer::GetLength() const
00607 {
00608     UPInt length, size = GetSize();
00609     if (LengthIsSize)
00610         return size;
00611 
00612     length = (UPInt)UTF8Util::GetLength(pData, (UPInt)GetSize());
00613 
00614     if (length == GetSize())
00615         LengthIsSize = true;
00616     return length;
00617 }
00618 
00619 void    StringBuffer::Reserve(UPInt _size)
00620 {
00621     if (_size >= BufferSize) // >= because of trailing zero! (!AB)
00622     {
00623         BufferSize = (_size + 1 + GrowSize - 1)& ~(GrowSize-1);
00624         if (!pData)
00625             pData = (char*)OVR_ALLOC(BufferSize);
00626         else 
00627             pData = (char*)OVR_REALLOC(pData, BufferSize);
00628     }
00629 }
00630 void    StringBuffer::Resize(UPInt _size)
00631 {
00632     Reserve(_size);
00633     LengthIsSize = false;
00634     Size = _size;
00635     if (pData)
00636         pData[Size] = 0;
00637 }
00638 
00639 void StringBuffer::Clear()
00640 {
00641     Resize(0);
00642     /*
00643     if (pData != pEmptyNullData)
00644     {
00645         OVR_FREE(pHeap, pData);
00646         pData = pEmptyNullData;
00647         Size = BufferSize = 0;
00648         LengthIsSize = false;
00649     }
00650     */
00651 }
00652 // Appends a character
00653 void     StringBuffer::AppendChar(UInt32 ch)
00654 {
00655     char    buff[8];
00656     UPInt   origSize = GetSize();
00657 
00658     // Converts ch into UTF8 string and fills it into buff. Also increments index according to the number of bytes
00659     // in the UTF8 string.
00660     SPInt   srcSize = 0;
00661     UTF8Util::EncodeChar(buff, &srcSize, ch);
00662     OVR_ASSERT(srcSize >= 0);
00663     
00664     UPInt size = origSize + srcSize;
00665     Resize(size);
00666     memcpy(pData + origSize, buff, srcSize);
00667 }
00668 
00669 // Append a string
00670 void     StringBuffer::AppendString(const wchar_t* pstr, SPInt len)
00671 {
00672     if (!pstr)
00673         return;
00674 
00675     SPInt   srcSize     = UTF8Util::GetEncodeStringSize(pstr, len);
00676     UPInt   origSize    = GetSize();
00677     UPInt   size        = srcSize + origSize;
00678 
00679     Resize(size);
00680     UTF8Util::EncodeString(pData + origSize,  pstr, len);
00681 }
00682 
00683 void      StringBuffer::AppendString(const char* putf8str, SPInt utf8StrSz)
00684 {
00685     if (!putf8str || !utf8StrSz)
00686         return;
00687     if (utf8StrSz == -1)
00688         utf8StrSz = (SPInt)OVR_strlen(putf8str);
00689 
00690     UPInt   origSize    = GetSize();
00691     UPInt   size        = utf8StrSz + origSize;
00692 
00693     Resize(size);
00694     memcpy(pData + origSize, putf8str, utf8StrSz);
00695 }
00696 
00697 
00698 void      StringBuffer::operator = (const char* pstr)
00699 {
00700     pstr = pstr ? pstr : "";
00701     UPInt size = OVR_strlen(pstr);
00702     Resize(size);
00703     memcpy(pData, pstr, size);
00704 }
00705 
00706 void      StringBuffer::operator = (const wchar_t* pstr)
00707 {
00708     pstr = pstr ? pstr : L"";
00709     UPInt size = (UPInt)UTF8Util::GetEncodeStringSize(pstr);
00710     Resize(size);
00711     UTF8Util::EncodeString(pData, pstr);
00712 }
00713 
00714 void      StringBuffer::operator = (const String& src)
00715 {
00716     Resize(src.GetSize());
00717     memcpy(pData, src.ToCStr(), src.GetSize());
00718 }
00719 
00720 
00721 // Inserts substr at posAt
00722 void      StringBuffer::Insert(const char* substr, UPInt posAt, SPInt len)
00723 {
00724     UPInt     oldSize    = Size;
00725     UPInt     insertSize = (len < 0) ? OVR_strlen(substr) : (UPInt)len;    
00726     UPInt     byteIndex  = LengthIsSize ? posAt : 
00727                            (UPInt)UTF8Util::GetByteIndex(posAt, pData, (SPInt)Size);
00728 
00729     OVR_ASSERT(byteIndex <= oldSize);
00730     Reserve(oldSize + insertSize);
00731 
00732     memmove(pData + byteIndex + insertSize, pData + byteIndex, oldSize - byteIndex + 1);
00733     memcpy (pData + byteIndex, substr, insertSize);
00734     LengthIsSize = false;
00735     Size = oldSize + insertSize;
00736     pData[Size] = 0;
00737 }
00738 
00739 // Inserts character at posAt
00740 UPInt     StringBuffer::InsertCharAt(UInt32 c, UPInt posAt)
00741 {
00742     char    buf[8];
00743     SPInt   len = 0;
00744     UTF8Util::EncodeChar(buf, &len, c);
00745     OVR_ASSERT(len >= 0);
00746     buf[(UPInt)len] = 0;
00747 
00748     Insert(buf, posAt, len);
00749     return (UPInt)len;
00750 }
00751 
00752 } // OVR


oculus_sdk
Author(s):
autogenerated on Mon Oct 6 2014 03:01:19