Annotation of mstools/mfc/src/string.cpp, revision 1.1

1.1     ! root        1: // This is a part of the Microsoft Foundation Classes C++ library. 
        !             2: // Copyright (C) 1992 Microsoft Corporation 
        !             3: // All rights reserved. 
        !             4: //  
        !             5: // This source code is only intended as a supplement to the 
        !             6: // Microsoft Foundation Classes Reference and Microsoft 
        !             7: // QuickHelp documentation provided with the library. 
        !             8: // See these sources for detailed information regarding the 
        !             9: // Microsoft Foundation Classes product. 
        !            10: 
        !            11: 
        !            12: #include "afx.h"
        !            13: #pragma hdrstop
        !            14: #include <limits.h>
        !            15: 
        !            16: #ifdef AFX_CORE_SEG
        !            17: #pragma code_seg(AFX_CORE_SEG)
        !            18: #endif
        !            19: 
        !            20: #ifdef _DEBUG
        !            21: #undef THIS_FILE
        !            22: static char BASED_CODE THIS_FILE[] = __FILE__;
        !            23: #endif
        !            24: 
        !            25: #define new DEBUG_NEW
        !            26: 
        !            27: /////////////////////////////////////////////////////////////////////////////
        !            28: // static class data, special inlines
        !            29: 
        !            30: char _afxChNil = '\0';
        !            31: 
        !            32: // For an empty string, m_???Data will point here
        !            33: // (note: avoids a lot of NULL pointer tests when we call standard
        !            34: //  C runtime libraries
        !            35: 
        !            36: extern const CString NEAR afxEmptyString;
        !            37: const CString NEAR afxEmptyString;
        !            38: 
        !            39: void CString::Init()
        !            40: {
        !            41:        m_nDataLength = m_nAllocLength = 0;
        !            42:        m_pchData = &_afxChNil;
        !            43: }
        !            44: 
        !            45: //////////////////////////////////////////////////////////////////////////////
        !            46: // Construction/Destruction
        !            47: 
        !            48: CString::CString()
        !            49: {
        !            50:        Init();
        !            51: }
        !            52: 
        !            53: CString::CString(const CString& stringSrc)
        !            54: {
        !            55:        // if constructing a CString from another CString, we make a copy of the
        !            56:        // original string data to enforce value semantics (i.e. each string
        !            57:        // gets a copy of it's own
        !            58: 
        !            59:        stringSrc.AllocCopy(*this, stringSrc.m_nDataLength, 0, 0);
        !            60: }
        !            61: 
        !            62: void CString::AllocBuffer(int nLen)
        !            63:  // always allocate one extra character for '\0' termination
        !            64:  // assumes [optimistically] that data length will equal allocation length
        !            65: {
        !            66:        ASSERT(nLen >= 0);
        !            67:        ASSERT(nLen < INT_MAX - 1); // max size (enough room for 1 extra)
        !            68: 
        !            69:        if (nLen == 0)
        !            70:        {
        !            71:                Init();
        !            72:        }
        !            73:        else
        !            74:        {
        !            75:                m_pchData = new char[nLen+1];       // may throw an exception
        !            76:                m_pchData[nLen] = '\0';
        !            77:                m_nDataLength = nLen;
        !            78:                m_nAllocLength = nLen;
        !            79:        }
        !            80: }
        !            81: 
        !            82: void CString::Empty()
        !            83: {
        !            84:        if (m_pchData != &_afxChNil)
        !            85:        {
        !            86:                delete [] m_pchData;
        !            87:                Init();
        !            88:        }
        !            89:        ASSERT(m_nDataLength == 0);
        !            90:        ASSERT(m_nAllocLength == 0);
        !            91: }
        !            92: 
        !            93: CString::~CString()
        !            94:  //  free any attached data
        !            95: {
        !            96:        if (m_pchData != &_afxChNil)
        !            97:                delete [] m_pchData;        // NOTE: not type safe
        !            98: }
        !            99: 
        !           100: //////////////////////////////////////////////////////////////////////////////
        !           101: // Helpers for the rest of the implementation
        !           102: 
        !           103: static inline int SafeStrlen(const char* psz)
        !           104:        { return (psz == NULL) ? NULL : strlen(psz); }
        !           105: 
        !           106: void CString::AllocCopy(CString& dest, int nCopyLen, int nCopyIndex,
        !           107:         int nExtraLen) const
        !           108: {
        !           109:        // will clone the data attached to this string
        !           110:        // allocating 'nExtraLen' characters
        !           111:        // Places results in uninitialized string 'dest'
        !           112:        // Will copy the part or all of original data to start of new string
        !           113: 
        !           114:        int nNewLen = nCopyLen + nExtraLen;
        !           115: 
        !           116:        if (nNewLen == 0)
        !           117:        {
        !           118:                dest.Init();
        !           119:        }
        !           120:        else
        !           121:        {
        !           122:                dest.AllocBuffer(nNewLen);
        !           123:                memcpy(dest.m_pchData, &m_pchData[nCopyIndex], nCopyLen);
        !           124:        }
        !           125: }
        !           126: 
        !           127: //////////////////////////////////////////////////////////////////////////////
        !           128: // More sophisticated construction
        !           129: 
        !           130: CString::CString(const char* psz)
        !           131: {
        !           132:        int nLen;
        !           133:        if ((nLen = SafeStrlen(psz)) == 0)
        !           134:                Init();
        !           135:        else
        !           136:        {
        !           137:                AllocBuffer(nLen);
        !           138:                memcpy(m_pchData, psz, nLen);
        !           139:        }
        !           140: }
        !           141: 
        !           142: //////////////////////////////////////////////////////////////////////////////
        !           143: // Diagnostic support
        !           144: 
        !           145: #ifdef _DEBUG 
        !           146: 
        !           147: CDumpContext&
        !           148: operator <<(CDumpContext& dc, const CString& string)
        !           149: {
        !           150:        dc << string.m_pchData;
        !           151:        return dc;
        !           152: }
        !           153: 
        !           154: #endif //_DEBUG
        !           155: 
        !           156: //////////////////////////////////////////////////////////////////////////////
        !           157: // Assignment operators
        !           158: //  All assign a new value to the string
        !           159: //      (a) first see if the buffer is big enough
        !           160: //      (b) if enough room, copy on top of old buffer, set size and type
        !           161: //      (c) otherwise free old string data, and create a new one
        !           162: //
        !           163: //  All routines return the new string (but as a 'const CString&' so that
        !           164: //      assigning it again will cause a copy, eg: s1 = s2 = "hi there".
        !           165: //
        !           166: 
        !           167: void CString::AssignCopy(int nSrcLen, const char* pszSrcData)
        !           168: {
        !           169:        // check if it will fit
        !           170:        if (nSrcLen > m_nAllocLength)
        !           171:        {
        !           172:                // it won't fit, allocate another one
        !           173:                Empty();
        !           174:                AllocBuffer(nSrcLen);
        !           175:        }
        !           176:        if (nSrcLen != 0)
        !           177:                memcpy(m_pchData, pszSrcData, nSrcLen);
        !           178:        m_nDataLength = nSrcLen;
        !           179:        m_pchData[nSrcLen] = '\0';
        !           180: }
        !           181: 
        !           182: const CString&
        !           183: CString::operator =(const CString& stringSrc)
        !           184: {
        !           185:        AssignCopy(stringSrc.m_nDataLength, stringSrc.m_pchData);
        !           186:        return *this;
        !           187: }
        !           188: 
        !           189: const CString&
        !           190: CString::operator =(const char* psz)
        !           191: {
        !           192:        AssignCopy(SafeStrlen(psz), psz);
        !           193:        return *this;
        !           194: }
        !           195: 
        !           196: 
        !           197: //////////////////////////////////////////////////////////////////////////////
        !           198: // concatenation
        !           199: 
        !           200: // NOTE: "operator +" is done as friend functions for simplicity
        !           201: //      There are three variants:
        !           202: //          CString + CString
        !           203: // and for ? = char, const char*
        !           204: //          CString + ?
        !           205: //          ? + CString
        !           206: 
        !           207: void
        !           208: CString::ConcatCopy(int nSrc1Len, const char* pszSrc1Data,
        !           209:                int nSrc2Len, const char* pszSrc2Data)
        !           210: {
        !           211:   // -- master concatenation routine
        !           212:   // Concatenate two sources
        !           213:   // -- assume that 'this' is a new CString object
        !           214: 
        !           215:        int nNewLen = nSrc1Len + nSrc2Len;
        !           216:        AllocBuffer(nNewLen);
        !           217:        memcpy(m_pchData, pszSrc1Data, nSrc1Len);
        !           218:        memcpy(&m_pchData[nSrc1Len], pszSrc2Data, nSrc2Len);
        !           219: }
        !           220: 
        !           221: CString
        !           222: operator +(const CString& string1, const CString& string2)
        !           223: {
        !           224:        CString s;
        !           225:        s.ConcatCopy(string1.m_nDataLength, string1.m_pchData,
        !           226:                string2.m_nDataLength, string2.m_pchData);
        !           227:        return s;
        !           228: }
        !           229: 
        !           230: CString
        !           231: operator +(const CString& string, const char* psz)
        !           232: {
        !           233:        CString s;
        !           234:        s.ConcatCopy(string.m_nDataLength, string.m_pchData, SafeStrlen(psz), psz);
        !           235:        return s;
        !           236: }
        !           237: 
        !           238: 
        !           239: CString
        !           240: operator +(const char* psz, const CString& string)
        !           241: {
        !           242:        CString s;
        !           243:        s.ConcatCopy(SafeStrlen(psz), psz, string.m_nDataLength, string.m_pchData);
        !           244:        return s;
        !           245: }
        !           246: 
        !           247: //////////////////////////////////////////////////////////////////////////////
        !           248: // concatenate in place
        !           249: 
        !           250: void
        !           251: CString::ConcatInPlace(int nSrcLen, const char* pszSrcData)
        !           252: {
        !           253:        //  -- the main routine for += operators
        !           254: 
        !           255:        // if the buffer is too small, or we have a width mis-match, just
        !           256:        //   allocate a new buffer (slow but sure)
        !           257:        if (m_nDataLength + nSrcLen > m_nAllocLength)
        !           258:        {
        !           259:                // we have to grow the buffer, use the Concat in place routine
        !           260:                char* pszOldData = m_pchData;
        !           261:                ConcatCopy(m_nDataLength, pszOldData, nSrcLen, pszSrcData);
        !           262:                ASSERT(pszOldData != NULL);
        !           263:                if (pszOldData != &_afxChNil)
        !           264:                        delete [] pszOldData;
        !           265:        }
        !           266:        else
        !           267:        {
        !           268:                // fast concatenation when buffer big enough
        !           269:                memcpy(&m_pchData[m_nDataLength], pszSrcData, nSrcLen);
        !           270:                m_nDataLength += nSrcLen;
        !           271:        }
        !           272:        ASSERT(m_nDataLength <= m_nAllocLength);
        !           273:        m_pchData[m_nDataLength] = '\0';
        !           274: }
        !           275: 
        !           276: const CString&
        !           277: CString::operator +=(const char* psz)
        !           278: {
        !           279:        ConcatInPlace(SafeStrlen(psz), psz);
        !           280:        return *this;
        !           281: }
        !           282: 
        !           283: const CString&
        !           284: CString::operator +=(const CString& string)
        !           285: {
        !           286:        ConcatInPlace(string.m_nDataLength, string.m_pchData);
        !           287:        return *this;
        !           288: }
        !           289: 
        !           290: 
        !           291: ///////////////////////////////////////////////////////////////////////////////

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.