Click here to Skip to main content
12,243,721 members (49,848 online)
Click here to Skip to main content

Stats

174.4K views
19.6K downloads
166 bookmarked
Posted

The Ultimate Toolbox - Updates and User Contributions

, 12 Feb 2013 CPOL
Updates and User Contributions for the Ultimate Toolbox Libraries
Ultimate Grid
Demos
OutlookStyle
OutlookStyle.aps
OutlookStyle.dsp
OutlookStyle.dsw
OutlookStyle.suo
res
bitmap1.bmp
bmattach.bmp
bmp00001.bmp
bmp00002.bmp
bmp00003.bmp
Flags.bmp
OutlookStyle.ico
OutlookStyleDoc.ico
Toolbar.bmp
toolbar1.bmp
toolbar2.bmp
toolbarf.bmp
CellTypes
Include
Source
DataSources
ODBC
OleDB
EditControls
BuildDLL
Build DLL.dsp
Build DLL.dsw
res
BuildLib
ugmfclib.dsp
ugmfclib.dsw
Lib
Skel
Ultimate TCP-IP
Include
Security
Include
Source
source
Examples
Client
Mail
icon1.ico
icon2.ico
MailClientS.suo
test.dsp
test.dsw
Ultimate Toolbox
include
source
lib
Build DLLs
Build Libs
// QuickString.cpp: implementation of the COXQuickString class.
//
//////////////////////////////////////////////////////////////////////
// Version: 9.3


#include "stdafx.h"
#include "OXQuickString.h"

#include "UTBStrOp.h"
#include "UTB64Bit.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

COXQuickString::COXQuickString()
{
    Init();
}

COXQuickString::COXQuickString(LPCTSTR szText)
{
    Init();
    SetString(szText);
}

COXQuickString::COXQuickString(const COXQuickString& str)
{
    Init();
    SetString(str.GetString());
}

COXQuickString::~COXQuickString()
{
    Empty();
}

//////////////////////////////////////////////////////////////////////
// Operations
//////////////////////////////////////////////////////////////////////

void COXQuickString::Empty()
{
    delete [] m_szText;
    
    Init();
}

void COXQuickString::Init()
{
    m_szText      = NULL;
    m_nBufferSize = 0;
    m_nLength     = 0;
    m_nGrowBy     = 10;
}

LPTSTR COXQuickString::AllocBuffer(UINT nBufferSize)
{
    return new TCHAR[nBufferSize];
}

BOOL COXQuickString::IsEmpty() const
{
    return (!m_szText || !(*m_szText));
}

BOOL COXQuickString::SetString(LPCTSTR szText)
{
    // We do a fresh memory allocation when setting the string.
    Empty();

    if (!szText)
        return TRUE;

    m_nLength = PtrToUint(_tcslen(szText));
    m_nBufferSize = m_nLength + 1;

    m_szText = AllocBuffer(m_nBufferSize);
    if (!m_szText)
        return FALSE;

	UTBStr::tcscpy(m_szText, m_nBufferSize, szText);

    return TRUE;
}

BOOL COXQuickString::SetString(LPCTSTR szText, int nCount)
{
    // We do a fresh memory allocation when setting the string.
    Empty();

    if (!szText || nCount <= 0)
        return TRUE;

    m_nLength = min(PtrToUint(_tcslen(szText)), (UINT)nCount);
    m_nBufferSize = m_nLength + 1;

    m_szText = AllocBuffer(m_nBufferSize);
    if (!m_szText)
        return FALSE;

	UTBStr::tcsncpy(m_szText, m_nBufferSize, szText, m_nLength+1);
    m_szText[m_nLength] = TEXT('\0');

    return TRUE;
}

BOOL COXQuickString::Append(TCHAR ch)
{
    UINT nLength = m_nLength + 1;

    // We reuse memory (if possible) when adding to the string.
    if (nLength+1 > m_nBufferSize)
    {   
        LPTSTR tmp = AllocBuffer(nLength+m_nGrowBy);
        if (!tmp)
            return FALSE;
        tmp[0] = TEXT('\0');
        
        m_nBufferSize = m_nLength + m_nGrowBy;
        
        if (m_szText)
        {
			UTBStr::tcscpy(tmp, nLength+m_nGrowBy, m_szText);
            delete [] m_szText;
        }
        m_szText = tmp;
    }

    m_szText[m_nLength++] = ch;
    m_szText[m_nLength] = TEXT('\0');

    return TRUE;
}

BOOL COXQuickString::AddString(LPCTSTR szText)
{
    if (!szText)
        return FALSE;

    UINT nLength = m_nLength + _tcslen(szText);

    // We reuse memory (if possible) when adding to the string.
    if (nLength+1 > m_nBufferSize)
    {   
        LPTSTR tmp = AllocBuffer(nLength+1);
        if (!tmp)
            return FALSE;
        tmp[0] = TEXT('\0');
        
        //m_nBufferSize = m_nLength + 1; // v9.3 Update 01 - Fix by Maurizio Giunti 2008-01-10
        m_nBufferSize = nLength + 1; 
        
        if (m_szText)
        {
			UTBStr::tcscpy(tmp, nLength+1, m_szText);
            delete [] m_szText;
        }
        m_szText = tmp;
    }

	UTBStr::tcscat(m_szText, nLength+1, szText);
  
	m_nLength = nLength;

    return TRUE;
}

BOOL COXQuickString::AddString(LPCTSTR szText, int nCount)
{
    if (!szText)
        return FALSE;

    UINT nLength = m_nLength + min(_tcslen(szText), (UINT)nCount);

    // We reuse memory (if possible) when adding to the string.
    if (nLength+1 > m_nBufferSize)
    {
        LPTSTR tmp = AllocBuffer(nLength+1);
        if (!tmp)
            return FALSE;
        tmp[0] = TEXT('\0');

        m_nBufferSize = nLength + 1;

        if (m_szText)
        {
			UTBStr::tcscpy(tmp, nLength+1, m_szText);
            delete [] m_szText;
        }
        m_szText = tmp;
    }

	UTBStr::tcsncat(m_szText, nLength+1, szText, nCount);
    m_szText[nLength] = TEXT('\0');
    m_nLength     = nLength;

    return TRUE;
}

LPCTSTR COXQuickString::GetString() const
{
    static const char chNull = TEXT('\0');

    if (IsEmpty())
        return (LPCTSTR)&chNull;
    else
        return (LPCTSTR)m_szText;
}

UINT COXQuickString::GetLength() const
{
#ifdef _DEBUG
    UINT nLength = m_szText? PtrToUint(_tcslen(m_szText)) : 0;
    ASSERT(nLength == m_nLength);
#endif
    return m_nLength;
}

BOOL COXQuickString::SetLength(UINT nLength) 
{
    // Do easy cases and return immediately if no problems
    if (nLength == m_nBufferSize)
        return TRUE;

    if (!nLength)
    {
        Empty();
        return TRUE;
    }

    if (nLength < m_nBufferSize)
    {
        m_szText[nLength] = TEXT('\0');
        m_nLength = min(m_nLength, nLength);
        return TRUE;
    }

    // Memory (re)allocation needed

    LPTSTR pBuf = AllocBuffer(nLength);
    if (!pBuf)
        return FALSE;

    m_nBufferSize = nLength;
    if (m_szText) 
    {
		UTBStr::tcscpy(pBuf, nLength, m_szText);
        delete [] m_szText;
    }
    m_szText = pBuf;
    m_szText[m_nLength] = TEXT('\0');

    return TRUE;
}

void COXQuickString::SetGrowBy(UINT nGrowBy)
{
    m_nGrowBy = nGrowBy;
}

UINT COXQuickString::GetGrowBy() const
{
    return m_nGrowBy;
}

BOOL COXQuickString::Compare(LPCTSTR szText, BOOL bCaseSensitive /*=TRUE*/)
{
    if (!szText || IsEmpty())
        return FALSE;

    BOOL bSame = FALSE;
    if (!bCaseSensitive)
        bSame = (_tcsicmp(m_szText, szText) == 0);
    else
        bSame = (_tcscmp(m_szText, szText) == 0);

    return bSame;
}

BOOL COXQuickString::operator==(LPCTSTR szText)
{
    return Compare(szText, TRUE);
}

BOOL COXQuickString::operator==(COXQuickString& str)
{
    return Compare(str.GetString(), TRUE);
}

BOOL COXQuickString::operator!=(LPCTSTR szText)
{
    return !Compare(szText, TRUE);
}

BOOL COXQuickString::operator!=(COXQuickString& str)
{
    return !Compare(str.GetString(), TRUE);
}

COXQuickString::operator LPCTSTR() const
{
    return GetString();
}

void COXQuickString::operator=(LPCTSTR szText)
{
    SetString(szText);
}

void COXQuickString::operator=(COXQuickString& str)
{
    if (this == &str) 
        return;

    SetString(str.GetString());
}

void COXQuickString::operator+=(LPCTSTR szText)
{
    AddString(szText);
}

void COXQuickString::operator+=(COXQuickString& str)
{
    AddString(str.GetString());
}

BOOL COXQuickString::Strip()
{
    const TCHAR chNBSP = TEXT('�');  // This is character 160, NOT character 32

    if (IsEmpty())
        return TRUE;

    int nLength = 0;
    LPTSTR ptr = m_szText;
    if (!ptr || !ptr[0])
        return FALSE;

    // Remove leading whitespace (keep NBSP characters)
    while (_istspace(*ptr) && *ptr != chNBSP)
    {
        ptr++;
        nLength++;
    }

    // Find how many "good" characters we have (good = are not consequetive spaces)
    LPTSTR pStart = ptr;
    int nGoodChars = 0;
    while (*ptr)
    {
        nLength++;
        if (!_istspace(*ptr) || *ptr == chNBSP)
            nGoodChars++;
        else
        {
            if (!_istspace(*(ptr+1)) || *ptr == chNBSP)
                nGoodChars++;
        }
        ptr++;
    }

    // Copy over these "good" chars over to a new buffer
    LPTSTR szNewString = AllocBuffer(nGoodChars+1);
    if (!szNewString)
        return FALSE;

    ptr = pStart;
    int nCount = 0;
    while (*ptr && nCount < nGoodChars)
    {
        if (!_istspace(*ptr) || *ptr == chNBSP)
            szNewString[nCount++] = *ptr;
        else
        {
            if ( (!_istspace(*(ptr+1)) || *ptr == chNBSP) && *(ptr+1))
                szNewString[nCount++] = TEXT(' ');
        }
        ptr++;
    }

    delete [] m_szText;

    // Return the new string
    szNewString[nCount] = TEXT('\0');

    m_szText = szNewString;
    m_nLength = nCount;
    m_nBufferSize = nGoodChars+1;

    return TRUE;
}

BOOL COXQuickString::TrimRight()
{
    if (IsEmpty())
        return TRUE;

    LPTSTR ptr = m_szText+m_nLength-1;

    while (_istspace(*ptr) && ptr >= m_szText)
        ptr--;

    m_nLength = PtrToUint(ptr - m_szText + 1);
    m_szText[m_nLength] = TEXT('\0');

    return TRUE;
}

BOOL COXQuickString::TrimLeft()
{
    if (IsEmpty())
        return TRUE;

    LPTSTR ptr = m_szText;
    while (ptr - m_szText < (int)m_nLength && _istspace(*ptr))
        ptr++;

    if (ptr != m_szText)
    {
        int nLength = m_nLength-(ptr-m_szText);
        LPTSTR szNewString = AllocBuffer(nLength+1);
        if (!szNewString)
            return FALSE;

		UTBStr::tcscpy(szNewString, nLength+1, ptr);
        szNewString[nLength] = TEXT('\0');
        m_nLength = nLength;
        m_nBufferSize = nLength+1;

        delete [] m_szText;
        m_szText = szNewString;
    }

    return TRUE;
}

BOOL COXQuickString::Trim()
{
    return (TrimRight() && TrimLeft());
}

UINT COXQuickString::NumTokens(TCHAR chDelimiter)
{
    if (IsEmpty())
        return 0;

    int nNumTokens = 1;
    for (LPCTSTR ptr = m_szText; *ptr; ptr++)
    {
        if (*ptr == chDelimiter)
            nNumTokens++;
    }

    return nNumTokens;
}

const COXQuickString COXQuickString::GetToken(int nIndex, TCHAR chDelimiter) const
{
    COXQuickString strReturn;

    if (IsEmpty())
        return strReturn;

    LPCTSTR pstrStart  = m_szText;
    LPCTSTR pstrBuffer = pstrStart;

    int nCurrent = 0;
    int nStart = 0;
    int nEnd = 0;
    int nOldStart = 0;

    // Search for token
    while (nCurrent <= nIndex && *pstrBuffer != TEXT('\0'))
    {
        if (*pstrBuffer == chDelimiter)
        {
            nOldStart = nStart;
            nStart = nEnd+1;
            nCurrent++;
        }
        nEnd++;
        pstrBuffer++;
    }

    // May have reached the end of the string
    if (*pstrBuffer == TEXT('\0'))
    {
        nOldStart = nStart;
        nEnd++;
    }

    if (nCurrent < nIndex) 
    {
        //TRACE1("Warning: GetStringField - Couldn't find field %d.\n", nIndex);
        return strReturn;
    }

    strReturn.SetString(m_szText+nOldStart, nEnd-nOldStart-1);

    return strReturn;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

The Ultimate Toolbox
Web Developer
Canada Canada
In January 2005, David Cunningham and Chris Maunder created TheUltimateToolbox.com, a new group dedicated to the continued development, support and growth of Dundas Software’s award winning line of MFC, C++ and ActiveX control products.

Ultimate Grid for MFC, Ultimate Toolbox for MFC, and Ultimate TCP/IP have been stalwarts of C++/MFC development for a decade. Thousands of developers have used these products to speed their time to market, improve the quality of their finished products, and enhance the reliability and flexibility of their software.
Group type: Organisation

421 members


You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160426.1 | Last Updated 13 Feb 2013
Article Copyright 2008 by The Ultimate Toolbox
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid