⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hxstring.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */ 

#include "hxstring.h"

#include "hlxclib/string.h"
#include "hlxclib/ctype.h"
#include "hxassert.h"

#ifdef HELIX_FEATURE_STR_2X_GROWTH
#define DEFAULT_GROWTH_FUNC CHXString::DoublingGrowth
#else
#define DEFAULT_GROWTH_FUNC CHXString::MinimalGrowth
#endif /* HELIX_FEATURE_STR_2X_GROWTH */


#if !defined(HELIX_CONFIG_NOSTATICS)
const CHXString HXEmptyString;
#else
const char* const _g_emptyString = NULL;
#endif


CHXStringRep::CHXStringRep(INT32 strSize, bool bSetLength) :
    m_refCount(1),
    m_strSize(0),
    m_bufSize((strSize > 0) ? strSize + 1 : 1),
    m_pData(new char[m_bufSize]) // Depends on m_bufSize being initialized
{
    if( m_pData )
    {
        m_pData[0] = '\0';

        if (bSetLength)
        {
	    m_strSize = strSize;
	    m_pData[m_strSize] = '\0';
        }
    }
}

CHXStringRep::CHXStringRep(const char* pStr) :
    m_refCount(1),
    m_strSize((pStr) ? strlen(pStr) : 0),
    m_bufSize(m_strSize + 1),    // Depends on m_strSize being initialized
    m_pData(new char[m_bufSize]) // Depends on m_bufSize being initialized
{
    if( m_pData )
    {
        if (pStr)
            strcpy(m_pData, pStr); /* Flawfinder: ignore */
        else
            m_pData[0] = '\0';
    }
}

CHXStringRep::CHXStringRep(const char* pStr, INT32 strSize) :
    m_refCount(1),
    m_strSize(strSize),
    m_bufSize((strSize > 0) ? strSize + 1: 1),
    m_pData(new char[m_bufSize]) // Depends on m_bufSize being initialized
{
    if( m_pData )
    {
        if (pStr)
	    strncpy(m_pData, pStr, m_strSize); /* Flawfinder: ignore */

        m_pData[m_strSize] = '\0';
    
        m_strSize = strlen(m_pData);
    }
}

CHXStringRep::CHXStringRep(char ch, INT32 count) :
    m_refCount(1),
    m_strSize((ch) ? count : 0),
    m_bufSize(count + 1),
    m_pData(new char[m_bufSize]) // Depends on m_bufSize being initialized
{
    if( m_pData )
    {
        memset(m_pData, ch, count);
        m_pData[m_strSize] = '\0';
    }
}

CHXStringRep::~CHXStringRep()
{
    HX_VECTOR_DELETE(m_pData);
    m_pData = 0;
}

void CHXStringRep::AddRef()
{
    m_refCount++;
}

void CHXStringRep::Release()
{
    if ((--m_refCount) == 0)
	delete this;
}

void CHXStringRep::Resize(INT32 newStrSize)
{
    HX_ASSERT(newStrSize >= 0);

    INT32 newBufSize = newStrSize + 1;

    if (newBufSize != m_bufSize)
    {
	delete [] m_pData;
	m_pData = new char[newBufSize];
	m_bufSize = newBufSize;
    }
}

void CHXStringRep::ResizeAndCopy(INT32 newStrSize, bool bSetLength)
{
    HX_ASSERT(newStrSize >= 0);

    INT32 newBufSize = newStrSize + 1;

    if (newBufSize != m_bufSize)
    {
	char* pNewBuf = new char[newBufSize];
        if( !pNewBuf )
        {
            // It would be swell to be able to notify the caller that we are
            // out of memory.
            return;
        }

	if (newStrSize < m_strSize)
	    m_strSize = newStrSize;

	if (m_pData)
	    strncpy(pNewBuf, m_pData, m_strSize); /* Flawfinder: ignore */

	pNewBuf[m_strSize] = '\0';

	if (bSetLength)
	{
	    m_strSize = newStrSize;
	    pNewBuf[m_strSize] = '\0';
	}

	delete [] m_pData;
	m_pData = pNewBuf;
	m_bufSize = newBufSize;
    }
}

void CHXStringRep::Copy(const char* pStr, INT32 strSize)
{
    HX_ASSERT(strSize >= 0);
    
    if (m_bufSize < (strSize + 1))
	Resize(strSize);

    if( m_pData )
    {
    strncpy(m_pData, pStr, strSize); /* Flawfinder: ignore */
    m_pData[strSize] = '\0';
    m_strSize = strSize;
    }
}

CHXString::CHXString(StringGrowthFunc pGrowthFunc) :
    m_pRep(0),
    m_pGrowthFunc((pGrowthFunc) ? pGrowthFunc : DEFAULT_GROWTH_FUNC)
{}

CHXString::CHXString(const CHXString& rhs) :
    m_pRep(rhs.m_pRep),
    m_pGrowthFunc(rhs.m_pGrowthFunc)
{
    if (m_pRep)
	m_pRep->AddRef();
}

CHXString::CHXString(char ch, int length,
		     StringGrowthFunc pGrowthFunc) :
    m_pRep(new CHXStringRep(ch, length)),
    m_pGrowthFunc((pGrowthFunc) ? pGrowthFunc : DEFAULT_GROWTH_FUNC)
{}

CHXString::CHXString(const char* pStr, 
		     StringGrowthFunc pGrowthFunc) :
    m_pRep(NULL),
    m_pGrowthFunc((pGrowthFunc) ? pGrowthFunc : DEFAULT_GROWTH_FUNC)
{
    if (pStr && *pStr)
    {
	/* Only create a CHXStringRep if the string
	 * is not empty
	 */
	m_pRep = new CHXStringRep(pStr);
    }
}

CHXString::CHXString(const char* pStr, int length,
		     StringGrowthFunc pGrowthFunc) :
    m_pRep(NULL),
    m_pGrowthFunc((pGrowthFunc) ? pGrowthFunc : DEFAULT_GROWTH_FUNC)
{
    if (pStr && (length > 0) && *pStr)
    {
	/* Only create a CHXStringRep if the string
	 * is not empty
	 */
	m_pRep = new CHXStringRep(pStr, length);
    }
}

CHXString::CHXString(const unsigned char* pStr,
		       StringGrowthFunc pGrowthFunc) :
    m_pRep(NULL),
    m_pGrowthFunc((pGrowthFunc) ? pGrowthFunc : DEFAULT_GROWTH_FUNC)
{
    if (pStr && *pStr)
    {
	/* Only create a CHXStringRep if the string
	 * is not empty
	 */
	m_pRep = new CHXStringRep((const char*)pStr);
    }
}

CHXString::~CHXString()
{
    if (m_pRep)
    {
        m_pRep->Release();
        m_pRep = NULL;
    }
}

void CHXString::Empty()
{
    if (m_pRep)
    {
        m_pRep->Release();
        m_pRep = NULL;
    }
}

void CHXString::SetAt(INT32 i, char ch)
{
    HX_ASSERT(m_pRep && (i < m_pRep->GetBufferSize()));

    if (m_pRep)
    {
	EnsureUnique();
	m_pRep->GetBuffer()[i] = ch;
    }
}

const CHXString& CHXString::operator=(const CHXString& rhs)
{
    if (&rhs != this)
    {
	if (m_pRep)
	    m_pRep->Release();

	m_pRep = rhs.m_pRep;
	
	if (m_pRep)
	    m_pRep->AddRef();

	m_pGrowthFunc = rhs.m_pGrowthFunc;
    }

    return *this;
}

const CHXString& CHXString::operator=(char ch)
{
    if (m_pRep)
    {
	EnsureUnique();
	if (m_pRep->GetBufferSize() < 2)
	    m_pRep->Resize(1);
	
	m_pRep->GetBuffer()[0] = ch;
	m_pRep->GetBuffer()[1] = '\0';
	
	if (ch)
	    m_pRep->SetStringSize(1);
	else
	    m_pRep->SetStringSize(0);
    }
    else
	m_pRep = new CHXStringRep(ch, 1);

    return *this;
}

const CHXString& CHXString::operator=(const char* pStr)
{
    if (m_pRep)
    {
	EnsureUnique();
	m_pRep->Copy(pStr, SafeStrlen(pStr));
    }
    else if (pStr && *pStr)
	m_pRep = new CHXStringRep(pStr);

    return *this;
}

const CHXString& CHXString::operator=(const unsigned char* pStr)
{
    if (m_pRep)
    {
	EnsureUnique();
	m_pRep->Copy((const char*)pStr, SafeStrlen((const char*)pStr));
    }
    else if (pStr && *pStr)
	m_pRep = new CHXStringRep((const char*)pStr);

    return *this;
}

const CHXString& CHXString::operator+=(const CHXString& rhs)
{
    // Be careful here. You must make sure that this implementation
    // handles the case where (&rhs == this)

    if (rhs.m_pRep)
	Append(rhs.m_pRep->GetBuffer(), rhs.m_pRep->GetStringSize());
    
    return *this;
}

const CHXString& CHXString::operator+=(char ch)
{
    if (ch)
	Append(&ch, 1);

    return *this;
}

const CHXString& CHXString::operator+=(const char* pStr)
{
    // Make sure that someone is not trying to be tricky and
    // append part of this string to itself.
    HX_ASSERT(!m_pRep ||
	      (pStr < m_pRep->GetBuffer()) ||
	      (pStr > m_pRep->GetBuffer() + m_pRep->GetBufferSize()));

    Append(pStr, SafeStrlen(pStr));

    return *this;
}

CHXString operator+(const CHXString& strA, const CHXString& strB)
{
    CHXString ret(strA);
    ret += strB;
    return ret;
}

CHXString operator+ (const CHXString& str, char ch)
{
    CHXString ret(str);
    ret += ch;
    return ret;
}

CHXString operator+ (char ch , const CHXString& str)
{
    CHXString ret(ch);
    ret += str;
    return ret;
}

CHXString operator+ (const CHXString& strA, const char* pStrB)
{
    CHXString ret(strA);
    ret += pStrB;
    return ret;
}

CHXString operator+ (const char* pStrA, const CHXString& strB)
{
    CHXString ret(pStrA);
    ret += strB;
    return ret;
}

char* CHXString::GetBuffer(INT32 minSize)
{
    // NOTE: minSize is string length, not including ending zero byte...

    HX_ASSERT(minSize >= 0);

    if (m_pRep)
    {
	if (m_pRep->GetBufferSize() < (minSize + 1))
	{
	    EnsureUnique();
	    m_pRep->ResizeAndCopy(minSize);
	}
    }
    else
	m_pRep = new CHXStringRep(minSize);

    return m_pRep->GetBuffer();
}

void CHXString::ReleaseBuffer(INT32 newSize)
{
    // NOTE: newSize is string length, not including ending zero byte...

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -