?? xmlstring.cpp
字號:
/* * 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 + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -