hxstring.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:19k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hxstring.h"
  36. #include "hlxclib/string.h"
  37. #include "hlxclib/ctype.h"
  38. #include "hxassert.h"
  39. #ifdef HELIX_FEATURE_STR_2X_GROWTH
  40. #define DEFAULT_GROWTH_FUNC CHXString::DoublingGrowth
  41. #else
  42. #define DEFAULT_GROWTH_FUNC CHXString::MinimalGrowth
  43. #endif /* HELIX_FEATURE_STR_2X_GROWTH */
  44. #if !defined(HELIX_CONFIG_NOSTATICS)
  45. const CHXString HXEmptyString;
  46. #else
  47. const char* const _g_emptyString = NULL;
  48. #endif
  49. CHXStringRep::CHXStringRep(INT32 strSize, bool bSetLength) :
  50.     m_refCount(1),
  51.     m_strSize(0),
  52.     m_bufSize((strSize > 0) ? strSize + 1 : 1),
  53.     m_pData(new char[m_bufSize]) // Depends on m_bufSize being initialized
  54. {
  55.     if( m_pData )
  56.     {
  57.         m_pData[0] = '';
  58.         if (bSetLength)
  59.         {
  60.     m_strSize = strSize;
  61.     m_pData[m_strSize] = '';
  62.         }
  63.     }
  64. }
  65. CHXStringRep::CHXStringRep(const char* pStr) :
  66.     m_refCount(1),
  67.     m_strSize((pStr) ? strlen(pStr) : 0),
  68.     m_bufSize(m_strSize + 1),    // Depends on m_strSize being initialized
  69.     m_pData(new char[m_bufSize]) // Depends on m_bufSize being initialized
  70. {
  71.     if( m_pData )
  72.     {
  73.         if (pStr)
  74.             strcpy(m_pData, pStr); /* Flawfinder: ignore */
  75.         else
  76.             m_pData[0] = '';
  77.     }
  78. }
  79. CHXStringRep::CHXStringRep(const char* pStr, INT32 strSize) :
  80.     m_refCount(1),
  81.     m_strSize(strSize),
  82.     m_bufSize((strSize > 0) ? strSize + 1: 1),
  83.     m_pData(new char[m_bufSize]) // Depends on m_bufSize being initialized
  84. {
  85.     if( m_pData )
  86.     {
  87.         if (pStr)
  88.     strncpy(m_pData, pStr, m_strSize); /* Flawfinder: ignore */
  89.         m_pData[m_strSize] = '';
  90.     
  91.         m_strSize = strlen(m_pData);
  92.     }
  93. }
  94. CHXStringRep::CHXStringRep(char ch, INT32 count) :
  95.     m_refCount(1),
  96.     m_strSize((ch) ? count : 0),
  97.     m_bufSize(count + 1),
  98.     m_pData(new char[m_bufSize]) // Depends on m_bufSize being initialized
  99. {
  100.     if( m_pData )
  101.     {
  102.         memset(m_pData, ch, count);
  103.         m_pData[m_strSize] = '';
  104.     }
  105. }
  106. CHXStringRep::~CHXStringRep()
  107. {
  108.     HX_VECTOR_DELETE(m_pData);
  109.     m_pData = 0;
  110. }
  111. void CHXStringRep::AddRef()
  112. {
  113.     m_refCount++;
  114. }
  115. void CHXStringRep::Release()
  116. {
  117.     if ((--m_refCount) == 0)
  118. delete this;
  119. }
  120. void CHXStringRep::Resize(INT32 newStrSize)
  121. {
  122.     HX_ASSERT(newStrSize >= 0);
  123.     INT32 newBufSize = newStrSize + 1;
  124.     if (newBufSize != m_bufSize)
  125.     {
  126. delete [] m_pData;
  127. m_pData = new char[newBufSize];
  128. m_bufSize = newBufSize;
  129.     }
  130. }
  131. void CHXStringRep::ResizeAndCopy(INT32 newStrSize, bool bSetLength)
  132. {
  133.     HX_ASSERT(newStrSize >= 0);
  134.     INT32 newBufSize = newStrSize + 1;
  135.     if (newBufSize != m_bufSize)
  136.     {
  137. char* pNewBuf = new char[newBufSize];
  138.         if( !pNewBuf )
  139.         {
  140.             // It would be swell to be able to notify the caller that we are
  141.             // out of memory.
  142.             return;
  143.         }
  144. if (newStrSize < m_strSize)
  145.     m_strSize = newStrSize;
  146. if (m_pData)
  147.     strncpy(pNewBuf, m_pData, m_strSize); /* Flawfinder: ignore */
  148. pNewBuf[m_strSize] = '';
  149. if (bSetLength)
  150. {
  151.     m_strSize = newStrSize;
  152.     pNewBuf[m_strSize] = '';
  153. }
  154. delete [] m_pData;
  155. m_pData = pNewBuf;
  156. m_bufSize = newBufSize;
  157.     }
  158. }
  159. void CHXStringRep::Copy(const char* pStr, INT32 strSize)
  160. {
  161.     HX_ASSERT(strSize >= 0);
  162.     
  163.     if (m_bufSize < (strSize + 1))
  164. Resize(strSize);
  165.     if( m_pData )
  166.     {
  167.     strncpy(m_pData, pStr, strSize); /* Flawfinder: ignore */
  168.     m_pData[strSize] = '';
  169.     m_strSize = strSize;
  170.     }
  171. }
  172. CHXString::CHXString(StringGrowthFunc pGrowthFunc) :
  173.     m_pRep(0),
  174.     m_pGrowthFunc((pGrowthFunc) ? pGrowthFunc : DEFAULT_GROWTH_FUNC)
  175. {}
  176. CHXString::CHXString(const CHXString& rhs) :
  177.     m_pRep(rhs.m_pRep),
  178.     m_pGrowthFunc(rhs.m_pGrowthFunc)
  179. {
  180.     if (m_pRep)
  181. m_pRep->AddRef();
  182. }
  183. CHXString::CHXString(char ch, int length,
  184.      StringGrowthFunc pGrowthFunc) :
  185.     m_pRep(new CHXStringRep(ch, length)),
  186.     m_pGrowthFunc((pGrowthFunc) ? pGrowthFunc : DEFAULT_GROWTH_FUNC)
  187. {}
  188. CHXString::CHXString(const char* pStr, 
  189.      StringGrowthFunc pGrowthFunc) :
  190.     m_pRep(NULL),
  191.     m_pGrowthFunc((pGrowthFunc) ? pGrowthFunc : DEFAULT_GROWTH_FUNC)
  192. {
  193.     if (pStr && *pStr)
  194.     {
  195. /* Only create a CHXStringRep if the string
  196.  * is not empty
  197.  */
  198. m_pRep = new CHXStringRep(pStr);
  199.     }
  200. }
  201. CHXString::CHXString(const char* pStr, int length,
  202.      StringGrowthFunc pGrowthFunc) :
  203.     m_pRep(NULL),
  204.     m_pGrowthFunc((pGrowthFunc) ? pGrowthFunc : DEFAULT_GROWTH_FUNC)
  205. {
  206.     if (pStr && (length > 0) && *pStr)
  207.     {
  208. /* Only create a CHXStringRep if the string
  209.  * is not empty
  210.  */
  211. m_pRep = new CHXStringRep(pStr, length);
  212.     }
  213. }
  214. CHXString::CHXString(const unsigned char* pStr,
  215.        StringGrowthFunc pGrowthFunc) :
  216.     m_pRep(NULL),
  217.     m_pGrowthFunc((pGrowthFunc) ? pGrowthFunc : DEFAULT_GROWTH_FUNC)
  218. {
  219.     if (pStr && *pStr)
  220.     {
  221. /* Only create a CHXStringRep if the string
  222.  * is not empty
  223.  */
  224. m_pRep = new CHXStringRep((const char*)pStr);
  225.     }
  226. }
  227. CHXString::~CHXString()
  228. {
  229.     if (m_pRep)
  230.     {
  231.         m_pRep->Release();
  232.         m_pRep = NULL;
  233.     }
  234. }
  235. void CHXString::Empty()
  236. {
  237.     if (m_pRep)
  238.     {
  239.         m_pRep->Release();
  240.         m_pRep = NULL;
  241.     }
  242. }
  243. void CHXString::SetAt(INT32 i, char ch)
  244. {
  245.     HX_ASSERT(m_pRep && (i < m_pRep->GetBufferSize()));
  246.     if (m_pRep)
  247.     {
  248. EnsureUnique();
  249. m_pRep->GetBuffer()[i] = ch;
  250.     }
  251. }
  252. const CHXString& CHXString::operator=(const CHXString& rhs)
  253. {
  254.     if (&rhs != this)
  255.     {
  256. if (m_pRep)
  257.     m_pRep->Release();
  258. m_pRep = rhs.m_pRep;
  259. if (m_pRep)
  260.     m_pRep->AddRef();
  261. m_pGrowthFunc = rhs.m_pGrowthFunc;
  262.     }
  263.     return *this;
  264. }
  265. const CHXString& CHXString::operator=(char ch)
  266. {
  267.     if (m_pRep)
  268.     {
  269. EnsureUnique();
  270. if (m_pRep->GetBufferSize() < 2)
  271.     m_pRep->Resize(1);
  272. m_pRep->GetBuffer()[0] = ch;
  273. m_pRep->GetBuffer()[1] = '';
  274. if (ch)
  275.     m_pRep->SetStringSize(1);
  276. else
  277.     m_pRep->SetStringSize(0);
  278.     }
  279.     else
  280. m_pRep = new CHXStringRep(ch, 1);
  281.     return *this;
  282. }
  283. const CHXString& CHXString::operator=(const char* pStr)
  284. {
  285.     if (m_pRep)
  286.     {
  287. EnsureUnique();
  288. m_pRep->Copy(pStr, SafeStrlen(pStr));
  289.     }
  290.     else if (pStr && *pStr)
  291. m_pRep = new CHXStringRep(pStr);
  292.     return *this;
  293. }
  294. const CHXString& CHXString::operator=(const unsigned char* pStr)
  295. {
  296.     if (m_pRep)
  297.     {
  298. EnsureUnique();
  299. m_pRep->Copy((const char*)pStr, SafeStrlen((const char*)pStr));
  300.     }
  301.     else if (pStr && *pStr)
  302. m_pRep = new CHXStringRep((const char*)pStr);
  303.     return *this;
  304. }
  305. const CHXString& CHXString::operator+=(const CHXString& rhs)
  306. {
  307.     // Be careful here. You must make sure that this implementation
  308.     // handles the case where (&rhs == this)
  309.     if (rhs.m_pRep)
  310. Append(rhs.m_pRep->GetBuffer(), rhs.m_pRep->GetStringSize());
  311.     
  312.     return *this;
  313. }
  314. const CHXString& CHXString::operator+=(char ch)
  315. {
  316.     if (ch)
  317. Append(&ch, 1);
  318.     return *this;
  319. }
  320. const CHXString& CHXString::operator+=(const char* pStr)
  321. {
  322.     // Make sure that someone is not trying to be tricky and
  323.     // append part of this string to itself.
  324.     HX_ASSERT(!m_pRep ||
  325.       (pStr < m_pRep->GetBuffer()) ||
  326.       (pStr > m_pRep->GetBuffer() + m_pRep->GetBufferSize()));
  327.     Append(pStr, SafeStrlen(pStr));
  328.     return *this;
  329. }
  330. CHXString operator+(const CHXString& strA, const CHXString& strB)
  331. {
  332.     CHXString ret(strA);
  333.     ret += strB;
  334.     return ret;
  335. }
  336. CHXString operator+ (const CHXString& str, char ch)
  337. {
  338.     CHXString ret(str);
  339.     ret += ch;
  340.     return ret;
  341. }
  342. CHXString operator+ (char ch , const CHXString& str)
  343. {
  344.     CHXString ret(ch);
  345.     ret += str;
  346.     return ret;
  347. }
  348. CHXString operator+ (const CHXString& strA, const char* pStrB)
  349. {
  350.     CHXString ret(strA);
  351.     ret += pStrB;
  352.     return ret;
  353. }
  354. CHXString operator+ (const char* pStrA, const CHXString& strB)
  355. {
  356.     CHXString ret(pStrA);
  357.     ret += strB;
  358.     return ret;
  359. }
  360. char* CHXString::GetBuffer(INT32 minSize)
  361. {
  362.     // NOTE: minSize is string length, not including ending zero byte...
  363.     HX_ASSERT(minSize >= 0);
  364.     if (m_pRep)
  365.     {
  366. if (m_pRep->GetBufferSize() < (minSize + 1))
  367. {
  368.     EnsureUnique();
  369.     m_pRep->ResizeAndCopy(minSize);
  370. }
  371.     }
  372.     else
  373. m_pRep = new CHXStringRep(minSize);
  374.     return m_pRep->GetBuffer();
  375. }
  376. void CHXString::ReleaseBuffer(INT32 newSize)
  377. {
  378.     // NOTE: newSize is string length, not including ending zero byte...
  379.     if (m_pRep)
  380.     {
  381.         // Update the string size since the caller could've changed the
  382.         // internal data (the whole point of this GetBuffer()/ReleaseBuffer()
  383.         // stuff).
  384.         char* pBuf = m_pRep->GetBuffer();
  385.         if (newSize >= m_pRep->GetBufferSize())
  386.         {
  387.             HX_ASSERT(newSize < m_pRep->GetBufferSize());
  388.             // ...so if it's too big, clamp it to the max available.
  389.             newSize = m_pRep->GetBufferSize() - 1;
  390.         }
  391.         if (newSize >= 0)
  392.             pBuf[newSize] = '';
  393.         else
  394.             newSize = strlen(pBuf);
  395.         if (newSize > 0)
  396.         {
  397.             m_pRep->SetStringSize(newSize);
  398.             m_pRep->ResizeAndCopy(newSize);
  399.         }
  400.         else
  401.         {
  402.             if (m_pRep)
  403.             {
  404.                 m_pRep->Release();
  405.                 m_pRep = NULL;
  406.             }
  407.         }
  408.     }
  409.     else
  410.     {
  411.         HX_ASSERT(!"Shouldn't call ReleaseBuffer() without GetBuffer()");
  412.         if (newSize > 0)
  413.             m_pRep = new CHXStringRep(newSize);
  414.     }
  415. }
  416. char* CHXString::GetBufferSetLength(INT32 newSize)
  417. {
  418.     // NOTE : newSize is a string length, not including ending zero byte...
  419.     HX_ASSERT(newSize >= 0);
  420.     if (m_pRep)
  421.     {
  422. EnsureUnique();
  423.         m_pRep->ResizeAndCopy(newSize, true);
  424.     }
  425.     else if (newSize > 0)
  426. m_pRep = new CHXStringRep(newSize, true);
  427.     return m_pRep->GetBuffer();
  428. }
  429. void CHXString::FreeExtra()
  430. {
  431.     if (m_pRep)
  432.     {
  433.         INT32 newSize = GetLength();
  434.         if (newSize > 0)
  435. {
  436.     EnsureUnique();
  437.             m_pRep->ResizeAndCopy(newSize);
  438. }
  439.         else
  440.         {
  441.             if (m_pRep)
  442.             {
  443.                 m_pRep->Release();
  444.                 m_pRep = NULL;
  445.             }
  446.         }
  447.     }
  448. }
  449. INT32 CHXString::GetAllocLength() const
  450. {
  451.     return GetLength();
  452. }
  453. INT32 CHXString::SetMinBufSize(INT32 minSize)
  454. {
  455.     // NOTE: minSize is a string length, not including ending zero byte...
  456.     HX_ASSERT(minSize >= 0);
  457.     INT32 ret = 0;
  458.     if (m_pRep)
  459.     {
  460. if (minSize >= m_pRep->GetStringSize())
  461. {
  462.     if (minSize)
  463.     {
  464. EnsureUnique();
  465. m_pRep->ResizeAndCopy(minSize);
  466.     }
  467.     else
  468.             {
  469.                 if (m_pRep)
  470.                 {
  471.                     m_pRep->Release();
  472.                     m_pRep = NULL;
  473.                 }
  474.             }
  475. }
  476. if (m_pRep)
  477.     ret = m_pRep->GetBufferSize() - 1;
  478.     }
  479.     else if (minSize > 0)
  480.     {
  481. m_pRep = new CHXStringRep(minSize);
  482. ret = minSize;
  483.     }
  484.     return ret;
  485. }
  486. #if defined(_MACINTOSH) || defined(_MAC_UNIX)
  487. #include "platform/mac/fullpathname.h"
  488. #include "platform/mac/cfwrappers.h"
  489. const CHXString& CHXString::SetFromStr255(const Str255 src)
  490. {
  491.     char temp[256]; /* Flawfinder: ignore */
  492.     
  493.     if (src==NULL)
  494.     {
  495.         Empty();
  496.     }
  497.     else
  498.     {
  499.         memcpy (temp, &src[1], src[0]); /* Flawfinder: ignore */
  500.         temp[src[0]] = 0;
  501.         *this = CHXString( temp, src[0]);
  502.     }
  503.     
  504.     return *this;
  505. }
  506. const CHXString& CHXString::AppendFromStr255(const Str255 src)
  507. {
  508.     char temp[256]; /* Flawfinder: ignore */
  509.     
  510.     if (src!=NULL)
  511.     {
  512.         memcpy (temp, &src[1], src[0]); /* Flawfinder: ignore */
  513.         temp[src[0]] = 0;
  514.         CHXString tempS;
  515.         tempS = temp;
  516.         *this = *this + tempS;
  517.     }
  518.     return *this;
  519. }
  520. const CHXString& CHXString::InsertFromStr255(const Str255 src)
  521. {
  522.     char temp[256]; /* Flawfinder: ignore */
  523.     
  524.     if (src!=NULL)
  525.     {
  526.         memcpy (temp, &src[1], src[0]); /* Flawfinder: ignore */
  527.         temp[src[0]] = 0;
  528. CHXString tempS;
  529. tempS = temp;
  530. *this = tempS + *this;
  531.     }
  532.     
  533.     return *this;
  534. }
  535.     
  536. const CHXString& CHXString::SetFromIndString(short strlist, short item)
  537. {
  538.     Str255 theStr;
  539.     GetIndString(theStr,strlist,item);
  540.     SetFromStr255(theStr);
  541.     return *this;
  542. }
  543. const CHXString& CHXString::operator =(FSSpec spec)
  544. {
  545.     CHXString temp;
  546.     
  547.     PathNameFromFSSpec(&spec, temp);
  548.     *this=temp;
  549.     return *this;
  550. }
  551. CHXString::operator const FSSpec(void)
  552. {
  553.     FSSpec spec;
  554.     (void) FSSpecFromPathName((const char*)(*this), &spec);
  555.     return spec;
  556. }
  557. HX_RESULT CHXString::MakeStr255(Str255& outPascalString) const
  558. {
  559.     UINT32 len = GetLength();
  560.     if (m_pRep)
  561. c2pstrcpy(outPascalString, m_pRep->GetBuffer());
  562.     
  563.     return (len <= 255 ? HXR_OK : HXR_FAIL);
  564. }
  565. #if !defined(_CARBON) && !defined(_MAC_UNIX)
  566. CHXString::operator Str255* (void)
  567. {
  568. #error "Not Implemented"
  569. }
  570. CHXString::operator const Str255* (void) const
  571. {
  572. #error "Not Implemented"
  573. }
  574. CHXString::operator ConstStr255Param (void) const
  575. {
  576. #error "Not Implemented"
  577. }
  578. #else
  579. const CHXString& CHXString::operator =(const FSRef& ref)
  580. {
  581.     CHXString temp;
  582.     
  583.     (void) PathFromFSRef(&ref, temp);
  584.     *this = temp;
  585.     return *this;
  586. }
  587. CHXString::operator const FSRef(void)
  588. {
  589.     FSRef ref;
  590.     ZeroInit(&ref);
  591.     (void) FSRefFromPath((const char*)(*this), &ref);
  592.     
  593.     return ref;
  594. }
  595. const CHXString& CHXString::operator =(CFStringRef ref)
  596. {
  597. #ifdef _MAC_CFM
  598. CFStringEncoding encoding = CFStringGetSystemEncoding();
  599. #else
  600. CFStringEncoding encoding = kCFStringEncodingUTF8;
  601. #endif
  602. // we need the string to be canonically decomposed Unicode in case it'll be used as a path on
  603. // an HFS disk, so we'll make a mutable copy of the string, normalize it, and then encode that as UTF-8
  604. const CFIndex kNoMaxLength = 0;
  605. CFMutableStringRef mutableRef = CFStringCreateMutableCopy(kCFAllocatorDefault, kNoMaxLength, ref);
  606. #ifndef __MWERKS__
  607. // our version of CodeWarrior doesn't have CFStringNormalize in the headers since they are pre-10.2 headers, alas
  608. CFStringNormalize(mutableRef, kCFStringNormalizationFormD);
  609. #endif
  610.     (void) SetFromCFString(mutableRef, encoding);
  611. CFRelease(mutableRef);
  612.     return *this;
  613. }
  614. HX_RESULT CHXString::SetFromCFString(CFStringRef ref, CFStringEncoding encoding)
  615. {
  616.     CHXString strTemp;
  617.     char * pBuffer;
  618.     BOOL bSuccess;
  619.     CFIndex buffSize;
  620.     bSuccess = FALSE;
  621.     //const CFStringEncoding kEncoding = kCFStringEncodingUTF8;
  622.     buffSize = 1 + CFStringGetMaximumSizeForEncoding(CFStringGetLength(ref), encoding);
  623.     pBuffer = strTemp.GetBuffer(buffSize);
  624.     if (pBuffer)
  625.     {
  626. bSuccess = CFStringGetCString(ref, pBuffer, buffSize, encoding);
  627. strTemp.ReleaseBuffer();
  628.     }
  629.     *this = strTemp;
  630.     return bSuccess ? HXR_OK : HXR_FAIL;
  631. }
  632. HX_RESULT CHXString::SetFromHFSUniStr255(const HFSUniStr255& uniName, 
  633.  CFStringEncoding encoding)
  634. {
  635.     CHXCFString cfs(uniName);
  636.     if (cfs.IsSet())
  637.     {
  638. SetFromCFString(cfs, encoding);
  639. return HXR_OK;
  640.     }
  641.     return HXR_FAIL;
  642. }
  643. HX_RESULT CHXString::MakeHFSUniStr255(HFSUniStr255& outUniName, CFStringEncoding encoding) const
  644. {
  645.     if (GetLength() < 256)
  646.     {
  647. CHXCFString cfs((const char*)(*this), encoding);
  648. if (cfs.IsSet())
  649. {
  650.     outUniName = (HFSUniStr255) cfs;
  651.     return HXR_OK;
  652. }
  653.     }
  654.     return HXR_FAIL;
  655. }
  656. #endif /* _CARBON || _MAC_UNIX */
  657. #endif /* _MACINTOSH || _MAC_UNIX */
  658. void CHXString::Init(const char* pStr, UINT32 size)
  659. {
  660.     if (size == UINT_MAX)
  661. size = (UINT32)SafeStrlen(pStr);
  662.     if (m_pRep)
  663.     {
  664. if ((UINT32)m_pRep->GetBufferSize() < (size + 1))
  665.     m_pRep->Resize(size);
  666. strncpy(m_pRep->GetBuffer(), pStr, size); /* Flawfinder: ignore */
  667. m_pRep->GetBuffer()[size] = '';
  668. m_pRep->SetStringSize(SafeStrlen(m_pRep->GetBuffer()));
  669.     }
  670.     else
  671. m_pRep = new CHXStringRep(pStr, size);
  672. }
  673. void CHXString::Nuke()
  674. {
  675.     if (m_pRep)
  676.     {
  677. m_pRep->Release();
  678. m_pRep = 0;
  679.     }
  680. }
  681. void CHXString::ConcatInPlace(const char* pStr, const UINT32 size)
  682. {
  683.     Append(pStr, (INT32)size);
  684. }
  685. void CHXString::EnsureUnique()
  686. {
  687.     if (m_pRep && m_pRep->IsShared())
  688.     {
  689. // m_pRep is being shared. Time to copy it so that we
  690. // have our own copy.
  691. CHXStringRep* pOld = m_pRep;
  692. m_pRep = new CHXStringRep(pOld->GetBuffer(), 
  693.   pOld->GetStringSize());
  694. pOld->Release();
  695.     }
  696. }
  697. void CHXString::Release()
  698. {
  699. }
  700. INT32 CHXString::MinimalGrowth(INT32 currentSize, INT32 sizeNeeded)
  701. {
  702.     return sizeNeeded;
  703. }
  704. INT32 CHXString::DoublingGrowth(INT32 currentSize, INT32 sizeNeeded)
  705. {
  706.     INT32 ret = currentSize;
  707.     while (ret < sizeNeeded)
  708. ret *= 2;
  709.     return ret;
  710. }
  711. void CHXString::Append(const char* pStr, INT32 size)
  712. {
  713.     HX_ASSERT(size >= 0);
  714.     if (size)
  715.     {
  716. if (m_pRep)
  717. {
  718.     EnsureUnique();
  719.     
  720.     int newSize = m_pRep->GetStringSize() + size;
  721.     Grow(newSize + 1);
  722.     strncpy(m_pRep->GetBuffer() + m_pRep->GetStringSize(), pStr, size); /* Flawfinder: ignore */
  723.     m_pRep->GetBuffer()[newSize] = '';
  724.     m_pRep->SetStringSize(newSize);
  725. }
  726. else
  727.     m_pRep = new CHXStringRep(pStr, size);
  728.     }
  729. }
  730. void CHXString::Grow(INT32 newSize)
  731. {
  732.     HX_ASSERT(m_pRep);
  733.     HX_ASSERT(newSize >= 0);
  734.     if (newSize > m_pRep->GetBufferSize())
  735.     {
  736. INT32 growSize = m_pGrowthFunc(m_pRep->GetBufferSize(), newSize);
  737. // Protect ourselves from bad grow functions
  738. if (growSize < newSize)
  739.     growSize = newSize;
  740.     
  741. m_pRep->ResizeAndCopy(growSize - 1);
  742.     }
  743. }