hxstring.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:20k
源码类别:

Symbian

开发平台:

Visual C++

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