xmlstring.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,907 行 · 第 1/4 页

CPP
1,907
字号
/* * Copyright 1999-2004 The Apache Software Foundation. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: XMLString.cpp,v 1.37 2004/09/28 09:35:05 amassari Exp $ */// ---------------------------------------------------------------------------//  Includes// ---------------------------------------------------------------------------#include <string.h>#include <ctype.h>#include <stdlib.h>#include <errno.h>#include <xercesc/util/XMLString.hpp>#include <xercesc/util/ArrayIndexOutOfBoundsException.hpp>#include <xercesc/util/IllegalArgumentException.hpp>#include <xercesc/util/NumberFormatException.hpp>#include <xercesc/util/OutOfMemoryException.hpp>#include <xercesc/util/RuntimeException.hpp>#include <xercesc/util/TranscodingException.hpp>#include <xercesc/util/Janitor.hpp>#include <xercesc/util/PlatformUtils.hpp>#include <xercesc/util/RefArrayVectorOf.hpp>#include <xercesc/util/TransService.hpp>#include <xercesc/util/XMLUniDefs.hpp>#include <xercesc/util/XMLUni.hpp>#include <xercesc/util/XMLUri.hpp>#include <xercesc/internal/XMLReader.hpp>XERCES_CPP_NAMESPACE_BEGIN// ---------------------------------------------------------------------------//  Local static data////  gConverter//      This is initialized when the user calls the platform init method,//      which calls our init method. This is the converter used for default//      conversion to/from the local code page.// ---------------------------------------------------------------------------static XMLLCPTranscoder*    gTranscoder = 0;static XMLCh                gNullStr[] ={    chOpenCurly, chLatin_n, chLatin_u, chLatin_l, chLatin_l, chCloseCurly, chNull};MemoryManager* XMLString::fgMemoryManager = 0;// ---------------------------------------------------------------------------//  XMLString: Public static methods// ---------------------------------------------------------------------------void XMLString::binToText(  const   unsigned long   toFormat                            ,       char* const     toFill                            , const unsigned int    maxChars                            , const unsigned int    radix                            , MemoryManager* const  manager){    static const char digitList[16] =    {          '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'        , 'A', 'B', 'C', 'D', 'E', 'F'    };    if (!maxChars)        ThrowXMLwithMemMgr(IllegalArgumentException, XMLExcepts::Str_ZeroSizedTargetBuf, manager);    // Handle special case    if (!toFormat)    {        toFill[0] = '0';        toFill[1] = 0;        return;    }    // This is used to fill the temp buffer    unsigned int tmpIndex = 0;    // A copy of the conversion value that we can modify    unsigned int tmpVal = toFormat;    //    //  Convert into a temp buffer that we know is large enough. This avoids    //  having to check for overflow in the inner loops, and we have to flip    //  the resulting XMLString anyway.    //    char   tmpBuf[128];    //    //  For each radix, do the optimal thing. For bin and hex, we can special    //  case them and do shift and mask oriented stuff. For oct and decimal    //  there isn't much to do but bull through it with divides.    //    if (radix == 2)    {        while (tmpVal)        {            if (tmpVal & 0x1UL)                tmpBuf[tmpIndex++] = '1';            else                tmpBuf[tmpIndex++] = '0';            tmpVal >>= 1;        }    }     else if (radix == 16)    {        while (tmpVal)        {            const unsigned int charInd = (tmpVal & 0xFUL);            tmpBuf[tmpIndex++] = digitList[charInd];            tmpVal >>= 4;        }    }     else if ((radix == 8) || (radix == 10))    {        while (tmpVal)        {            const unsigned int charInd = (tmpVal % radix);            tmpBuf[tmpIndex++] = digitList[charInd];            tmpVal /= radix;        }    }    else    {        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::Str_UnknownRadix, manager);    }    // See if have enough room in the caller's buffer    if (tmpIndex > maxChars)    {        ThrowXMLwithMemMgr(IllegalArgumentException, XMLExcepts::Str_TargetBufTooSmall, manager);    }    // Reverse the tmp buffer into the caller's buffer    unsigned int outIndex = 0;    for (; tmpIndex > 0; tmpIndex--)        toFill[outIndex++] = tmpBuf[tmpIndex-1];    // And cap off the caller's buffer    toFill[outIndex] = char(0);}void XMLString::binToText(  const   unsigned int    toFormat                            ,       char* const     toFill                            , const unsigned int    maxChars                            , const unsigned int    radix                            , MemoryManager* const  manager){    // Just call the unsigned long version    binToText((unsigned long)toFormat, toFill, maxChars, radix, manager);}void XMLString::binToText(  const   long            toFormat                            ,       char* const     toFill                            , const unsigned int    maxChars                            , const unsigned int    radix                            , MemoryManager* const  manager){    //    //  If its negative, then put a negative sign into the output and flip    //  the sign of the local temp value.    //    unsigned int startInd = 0;    unsigned long actualVal;    if (toFormat < 0)    {        toFill[0] = '-';        startInd++;        actualVal = (unsigned long)(toFormat * -1);    }     else    {        actualVal = (unsigned long)(toFormat);    }    // And now call the unsigned long version    binToText(actualVal, &toFill[startInd], maxChars, radix, manager);}void XMLString::binToText(  const   int             toFormat                            ,       char* const     toFill                            , const unsigned int    maxChars                            , const unsigned int    radix                            , MemoryManager* const  manager){    //    //  If its negative, then put a negative sign into the output and flip    //  the sign of the local temp value.    //    unsigned int startInd = 0;    unsigned long actualVal;    if (toFormat < 0)    {        toFill[0] = '-';        startInd++;        actualVal = (unsigned long)(toFormat * -1);    }     else    {        actualVal = (unsigned long)(toFormat);    }    // And now call the unsigned long version    binToText(actualVal, &toFill[startInd], maxChars, radix, manager);}void XMLString::catString(char* const target, const char* const src){    strcat(target, src);}int XMLString::compareIString(const char* const str1, const char* const str2){    return stricmp(str1, str2);}int XMLString::compareNString(  const   char* const     str1                                , const char* const     str2                                , const unsigned int    count){    // Watch for pathological secenario    if (!count)        return 0;    return strncmp(str1, str2, count);}int XMLString::compareNIString( const   char* const     str1                                , const char* const     str2                                , const unsigned int    count){    if (!count)        return 0;    return strnicmp(str1, str2, count);}int XMLString::compareString(   const   char* const    str1                                , const char* const    str2){    return strcmp(str1, str2);}void XMLString::copyString(         char* const    target                            , const char* const    src){    strcpy(target, src);}void XMLString::cut(        XMLCh* const    toCutFrom                    , const unsigned int    count){    #if defined(XML_DEBUG)    if (count > stringLen(toCutFrom))    {        // <TBD> This is bad of course    }    #endif    // If count is zero, then nothing to do    if (!count)        return;    XMLCh* targetPtr = toCutFrom;    XMLCh* srcPtr = toCutFrom + count;    while (*srcPtr)        *targetPtr++ = *srcPtr++;    // Cap it off at the new end    *targetPtr = 0;}unsigned int XMLString::hash(   const   char* const     tohash                                , const unsigned int    hashModulus                                , MemoryManager* const  manager){        if (!hashModulus)        ThrowXMLwithMemMgr(IllegalArgumentException, XMLExcepts::Pool_ZeroModulus, manager);    unsigned int hashVal = 0;    if (tohash) {        const char* curCh = tohash;        while (*curCh)        {            unsigned int top = hashVal >> 24;            hashVal += (hashVal * 37) + top + (unsigned int)(*curCh);            curCh++;        }    }    // Divide by modulus    return hashVal % hashModulus;}int XMLString::indexOf(const char* const toSearch, const char ch){    const unsigned int len = strlen(toSearch);    for (unsigned int i = 0; i < len; i++)    {        if (toSearch[i] == ch)            return i;    }    return -1;}int XMLString::indexOf( const   char* const     toSearch                        , const char            ch                        , const unsigned int    fromIndex                        , MemoryManager* const  manager){    const unsigned int len = strlen(toSearch);    // Make sure the start index is within the XMLString bounds	if ((int)fromIndex > ((int)len)-1)        ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Str_StartIndexPastEnd, manager);    for (unsigned int i = fromIndex; i < len; i++)    {        if (toSearch[i] == ch)            return i;    }    return -1;}int XMLString::lastIndexOf(const char* const toSearch, const char ch){    const int len = strlen(toSearch);    for (int i = len-1; i >= 0; i--)    {        if (toSearch[i] == ch)            return i;    }    return -1;}int XMLString::lastIndexOf( const   char* const     toSearch                            , const char            ch                            , const unsigned int    fromIndex                            , MemoryManager* const  manager){    const int len = strlen(toSearch);    // Make sure the start index is within the XMLString bounds	if ((int)fromIndex > len-1)        ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Str_StartIndexPastEnd, manager);    for (int i = (int)fromIndex; i >= 0; i--)    {        if (toSearch[i] == ch)            return i;    }    return -1;}unsigned int XMLString::replaceTokens(          XMLCh* const    errText                                        , const unsigned int    maxChars                                        , const XMLCh* const    text1                                        , const XMLCh* const    text2                                        , const XMLCh* const    text3                                        , const XMLCh* const    text4                                        , MemoryManager* const  manager){    //    //  We have to build the string back into the source string, so allocate    //  a temp string and copy the orignal text to it. We'll then treat the    //  incoming buffer as a target buffer. Put a janitor on it to make sure    //  it gets cleaned up.    //    XMLCh* orgText = replicate(errText, manager);    ArrayJanitor<XMLCh> janText(orgText, manager);    XMLCh* pszSrc = orgText;    unsigned int curOutInd = 0;    while (*pszSrc && (curOutInd < maxChars))    {        //        //  Loop until we see a { character. Until we do, just copy chars        //  from src to target, being sure not to overrun the output buffer.        //        while ((*pszSrc != chOpenCurly) && (curOutInd < maxChars))        {            if (!*pszSrc)                break;            errText[curOutInd++] = *pszSrc++;        }        // If we did not find a curly, then we are done        if (*pszSrc != chOpenCurly)            break;        //        //  Probe this one to see if it matches our pattern of {x}. If not        //  then copy over those chars and go back to the first loop.        //        if ((*(pszSrc+1) >= chDigit_0)        &&  (*(pszSrc+1) <= chDigit_3)        &&  (*(pszSrc+2) == chCloseCurly))        {            //            //  Its one of our guys, so move the source pointer up past the            //  token we are replacing. First though get out the token number            //  character.            //            XMLCh tokCh = *(pszSrc+1);            pszSrc += 3;            // Now copy over the replacement text            const XMLCh* repText = 0;            if (tokCh == chDigit_0)                repText = text1;            else if (tokCh == chDigit_1)                repText = text2;            else if (tokCh == chDigit_2)                repText = text3;            else if (tokCh == chDigit_3)                repText = text4;            // If this one is null, copy over a null string            if (!repText)                repText = gNullStr;            while (*repText && (curOutInd < maxChars))                errText[curOutInd++] = *repText++;        }         else        {            // Escape the curly brace character and continue            errText[curOutInd++] = *pszSrc++;        }    }    // Copy over a null terminator    errText[curOutInd] = 0;    // And return the count of chars we output    return curOutInd;}XMLCh* XMLString::replicate(const XMLCh* const toRep){    // If a null string, return a null string!    XMLCh* ret = 0;    if (toRep)    {        const unsigned int len = stringLen(toRep);        ret = new XMLCh[len + 1];        memcpy(ret, toRep, (len + 1) * sizeof(XMLCh));    }

⌨️ 快捷键说明

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