| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * |
| * Copyright (c) 1999-2002 The Apache Software Foundation. All rights |
| * reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * 3. The end-user documentation included with the redistribution, |
| * if any, must include the following acknowledgment: |
| * "This product includes software developed by the |
| * Apache Software Foundation (http://www.apache.org/)." |
| * Alternately, this acknowledgment may appear in the software itself, |
| * if and wherever such third-party acknowledgments normally appear. |
| * |
| * 4. The names "Xalan" and "Apache Software Foundation" must |
| * not be used to endorse or promote products derived from this |
| * software without prior written permission. For written |
| * permission, please contact apache@apache.org. |
| * |
| * 5. Products derived from this software may not be called "Apache", |
| * nor may "Apache" appear in their name, without prior written |
| * permission of the Apache Software Foundation. |
| * |
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR |
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation and was |
| * originally based on software copyright (c) 1999, International |
| * Business Machines, Inc., http://www.ibm.com. For more |
| * information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| */ |
| |
| #include "XalanDOMString.hpp" |
| |
| |
| |
| #include <cassert> |
| |
| |
| |
| #include <Include/XalanAutoPtr.hpp> |
| |
| |
| |
| #include <cstdlib> |
| |
| |
| |
| const XalanDOMChar XalanDOMString::s_empty = 0; |
| |
| |
| |
| XalanDOMString::XalanDOMString() : |
| m_data(), |
| m_size(0) |
| { |
| } |
| |
| |
| |
| XalanDOMString::XalanDOMString( |
| const XalanDOMString& theSource, |
| size_type theStartPosition, |
| size_type theCount) : |
| m_data(), |
| m_size(0) |
| { |
| if (theSource.length() != 0) |
| { |
| append(theSource, theStartPosition, theCount); |
| } |
| } |
| |
| |
| |
| XalanDOMString::XalanDOMString( |
| const XalanDOMChar* theString, |
| size_type theCount) : |
| m_data(), |
| m_size(0) |
| { |
| assert(theString != 0); |
| |
| if (*theString != 0) |
| { |
| append(theString, theCount); |
| } |
| } |
| |
| |
| |
| XalanDOMString::XalanDOMString( |
| const char* theString, |
| size_type theCount) : |
| m_data(), |
| m_size(0) |
| { |
| assert(theString != 0); |
| |
| if (*theString != 0) |
| { |
| append(theString, theCount); |
| } |
| |
| invariants(); |
| } |
| |
| |
| |
| XalanDOMString::XalanDOMString( |
| size_type theCount, |
| XalanDOMChar theChar) : |
| m_data(), |
| m_size(0) |
| { |
| if (theCount != 0) |
| { |
| XalanDOMCharVectorType(theCount + 1, theChar).swap(m_data); |
| |
| // Null-terminate it... |
| m_data.back() = 0; |
| |
| m_size = theCount; |
| } |
| |
| invariants(); |
| } |
| |
| |
| |
| void |
| XalanDOMString::resize( |
| size_type theCount, |
| XalanDOMChar theChar) |
| { |
| invariants(); |
| |
| const size_type theOldSize = size(); |
| |
| if (theCount != theOldSize) |
| { |
| if (theOldSize == 0) |
| { |
| // If the string is of 0 length, resize but add an |
| // extra byte for the terminating byte. |
| m_data.resize(theCount + 1, theChar); |
| } |
| else |
| { |
| // If the string is not of 0 length, resize but |
| // put a copy of theChar where the terminating |
| // byte used to be. |
| m_data.resize(theCount + 1, theChar); |
| } |
| |
| m_size = theCount; |
| |
| // Terminate... |
| m_data.back() = 0; |
| } |
| |
| invariants(); |
| } |
| |
| |
| |
| void |
| XalanDOMString::erase( |
| size_type theStartPosition, |
| size_type theCount) |
| { |
| invariants(); |
| |
| const size_type theActualCount = |
| theCount == size_type(npos) ? length() : theCount; |
| |
| if (theStartPosition == 0 && theCount >= size()) |
| { |
| m_data.erase(m_data.begin(), m_data.end()); |
| |
| m_size = 0; |
| } |
| else |
| { |
| const iterator i = getIteratorForPosition(theStartPosition); |
| |
| m_data.erase(i, i + (theActualCount)); |
| |
| const size_type theNewSize = m_data.size(); |
| |
| if (theNewSize < 2) |
| { |
| m_size = 0; |
| } |
| else |
| { |
| m_size = theNewSize - 1; |
| } |
| } |
| |
| invariants(); |
| } |
| |
| |
| |
| XalanDOMString& |
| XalanDOMString::assign( |
| const XalanDOMString& theSource, |
| size_type thePosition, |
| size_type theCount) |
| { |
| invariants(); |
| |
| assert(thePosition < theSource.size() && thePosition + theCount <= theSource.size()); |
| |
| if (&theSource != this) |
| { |
| erase(); |
| |
| append(theSource, thePosition, theCount); |
| } |
| else |
| { |
| if (thePosition == 0) |
| { |
| // See if we're being asked to |
| // assign everything to ourself, |
| // which is a noop... |
| if (theCount != m_size) |
| { |
| // We're being asked to truncate... |
| resize(theCount); |
| } |
| } |
| else |
| { |
| // Yuck. We have to move data... |
| #if defined(XALAN_STRICT_ANSI_HEADERS) |
| std::memmove(&*begin(), &*begin() + thePosition, theCount * sizeof(XalanDOMChar)); |
| #else |
| memmove(&*begin(), &*begin() + thePosition, theCount * sizeof(XalanDOMChar)); |
| #endif |
| |
| resize(theCount); |
| } |
| } |
| |
| invariants(); |
| |
| return *this; |
| } |
| |
| |
| |
| XalanDOMString& |
| XalanDOMString::assign( |
| const_iterator theFirstPosition, |
| const_iterator theLastPosition) |
| { |
| invariants(); |
| |
| #if __SGI_STL_PORT <= 0x400 |
| XalanDOMString temp; |
| |
| temp.reserve(theLastPosition - theFirstPosition + 1); |
| |
| while(theFirstPosition != theLastPosition) |
| { |
| temp.push_back(*theFirstPosition); |
| |
| ++theFirstPosition; |
| } |
| |
| temp.m_data.push_back(XalanDOMChar(0)); |
| |
| temp.m_size = temp.m_data.size() - 1; |
| |
| swap(temp); |
| #else |
| m_data.assign(theFirstPosition, theLastPosition); |
| |
| m_data.push_back(XalanDOMChar(0)); |
| |
| m_size = m_data.size() - 1; |
| #endif |
| |
| invariants(); |
| |
| return *this; |
| } |
| |
| |
| |
| XalanDOMString& |
| XalanDOMString::append( |
| const XalanDOMChar* theString, |
| size_type theCount) |
| { |
| const size_type theLength = |
| theCount == size_type(npos) ? length(theString) : theCount; |
| |
| if (theLength != 0) |
| { |
| if (m_data.size() == 0) |
| { |
| m_data.reserve(theLength + 1); |
| |
| m_data.insert(m_data.end(), theString, theString + theLength); |
| |
| m_data.push_back(0); |
| |
| m_size = theLength; |
| |
| assert(length() == theLength); |
| } |
| else |
| { |
| m_data.insert(getBackInsertIterator(), theString, theString + theLength); |
| |
| m_size += theCount; |
| } |
| } |
| |
| invariants(); |
| |
| return *this; |
| } |
| |
| |
| |
| static inline void |
| doTranscode( |
| const char* theString, |
| XalanDOMString::size_type theCount, |
| XalanDOMCharVectorType& theVector, |
| bool fTerminate) |
| { |
| assert(theString != 0); |
| |
| if (theCount == XalanDOMString::size_type(XalanDOMString::npos)) |
| { |
| if (TranscodeFromLocalCodePage(theString, theVector, fTerminate) == false) |
| { |
| throw XalanDOMString::TranscodingError(); |
| } |
| } |
| else |
| { |
| if (TranscodeFromLocalCodePage(theString, theCount, theVector, fTerminate) == false) |
| { |
| throw XalanDOMString::TranscodingError(); |
| } |
| } |
| } |
| |
| |
| |
| XalanDOMString& |
| XalanDOMString::append( |
| const char* theString, |
| size_type theCount) |
| { |
| invariants(); |
| |
| const size_type theLength = |
| theCount == size_type(npos) ? length(theString) : theCount; |
| |
| if (theLength != 0) |
| { |
| if (size() == 0) |
| { |
| doTranscode(theString, theLength, m_data, true); |
| } |
| else |
| { |
| XalanDOMCharVectorType theTempVector; |
| |
| doTranscode(theString, theLength, theTempVector, false); |
| |
| append(&*theTempVector.begin(), size_type(theTempVector.size())); |
| } |
| |
| m_size = m_data.size() - 1; |
| } |
| |
| invariants(); |
| |
| return *this; |
| } |
| |
| |
| XalanDOMString& |
| XalanDOMString::append( |
| size_type theCount, |
| XalanDOMChar theChar) |
| { |
| invariants(); |
| |
| if (m_data.size() == 0) |
| { |
| m_data.insert(m_data.end(), theCount + 1, theChar); |
| |
| m_data.back() = 0; |
| |
| m_size = theCount; |
| |
| assert(length() == theCount); |
| } |
| else |
| { |
| m_data.insert(getBackInsertIterator(), theCount, theChar); |
| |
| m_size += theCount; |
| } |
| |
| invariants(); |
| |
| return *this; |
| } |
| |
| |
| |
| XalanDOMString& |
| XalanDOMString::insert( |
| size_type thePosition, |
| const XalanDOMChar* theString, |
| size_type theCount) |
| { |
| invariants(); |
| |
| m_data.insert(getIteratorForPosition(thePosition), theString, theString + theCount); |
| |
| m_size += theCount; |
| |
| invariants(); |
| |
| return *this; |
| } |
| |
| |
| |
| XalanDOMString& |
| XalanDOMString::insert( |
| size_type thePosition, |
| size_type theCount, |
| XalanDOMChar theChar) |
| { |
| invariants(); |
| |
| m_data.insert(getIteratorForPosition(thePosition), theCount, theChar); |
| |
| m_size += theCount; |
| |
| invariants(); |
| |
| return *this; |
| } |
| |
| |
| |
| XalanDOMString::iterator |
| XalanDOMString::insert( |
| iterator thePosition, |
| XalanDOMChar theChar) |
| { |
| invariants(); |
| |
| m_data.insert(thePosition, theChar); |
| |
| ++m_size; |
| |
| invariants(); |
| |
| return thePosition; |
| } |
| |
| |
| |
| void |
| XalanDOMString::insert( |
| iterator thePosition, |
| size_type theCount, |
| XalanDOMChar theChar) |
| { |
| invariants(); |
| |
| m_data.insert(thePosition, theCount, theChar); |
| |
| m_size += theCount; |
| |
| invariants(); |
| } |
| |
| |
| |
| void |
| XalanDOMString::insert( |
| iterator theInsertPosition, |
| const_iterator theFirstPosition, |
| const_iterator theLastPosition) |
| { |
| invariants(); |
| |
| m_data.insert(theInsertPosition, theFirstPosition, theLastPosition); |
| |
| m_size = m_data.size() - 1; |
| |
| assert(m_size == m_data.size() - 1); |
| |
| invariants(); |
| } |
| |
| |
| |
| template <class Type, class SizeType> |
| int |
| doCompare( |
| const Type* theLHS, |
| SizeType theLHSLength, |
| const Type* theRHS, |
| SizeType theRHSLength) |
| { |
| int theResult = 0; |
| |
| if (theLHSLength != 0 || theRHSLength != 0) |
| { |
| Type theLHSChar = Type(0); |
| Type theRHSChar = Type(0); |
| |
| SizeType i = 0; |
| |
| for(; i < theLHSLength && i < theRHSLength; i++) |
| { |
| theLHSChar = theLHS[i]; |
| theRHSChar = theRHS[i]; |
| |
| if (theLHSChar != theRHSChar) |
| { |
| break; |
| } |
| } |
| |
| if (i == theLHSLength) |
| { |
| // We reached the end of theLHS... |
| if (i != theRHSLength) |
| { |
| // but not the end of theRHS. |
| theResult = -1; |
| } |
| } |
| else if (i == theRHSLength) |
| { |
| // We reached the end of theRHS string... |
| if (i != theLHSLength) |
| { |
| // but not the end of theLHS string. |
| theResult = 1; |
| } |
| } |
| else |
| { |
| // We didn't reach the end of _either_ string, so |
| // return the difference between the two characters |
| // that caused the problem. |
| theResult = theLHSChar - theRHSChar; |
| } |
| } |
| |
| return theResult; |
| } |
| |
| |
| |
| int |
| XalanDOMString::compare(const XalanDOMChar* theString) const |
| { |
| invariants(); |
| |
| return doCompare(c_str(), length(), theString, length(theString)); |
| } |
| |
| |
| |
| int |
| XalanDOMString::compare( |
| size_type thePosition1, |
| size_type theCount1, |
| const XalanDOMChar* theString, |
| size_type theCount2) const |
| { |
| invariants(); |
| |
| return doCompare(c_str() + thePosition1, theCount1, theString, theCount2); |
| } |
| |
| |
| |
| XalanDOMString::CharVectorType |
| XalanDOMString::transcode() const |
| { |
| invariants(); |
| |
| CharVectorType theResult; |
| |
| if (TranscodeToLocalCodePage(c_str(), length(), theResult, true) == false) |
| { |
| throw TranscodingError(); |
| } |
| |
| return theResult; |
| } |
| |
| |
| |
| static inline XalanDOMString::size_type |
| length(const XalanDOMChar* theString) |
| { |
| assert(theString != 0); |
| |
| const XalanDOMChar* theStringPointer = theString; |
| |
| while(*theStringPointer != 0) |
| { |
| theStringPointer++; |
| } |
| |
| return XalanDOMString::size_type(theStringPointer - theString); |
| } |
| |
| |
| |
| bool |
| XalanDOMString::equals( |
| const XalanDOMChar* theLHS, |
| size_type theLHSLength, |
| const XalanDOMChar* theRHS, |
| size_type theRHSLength) |
| { |
| if (theLHSLength != theRHSLength) |
| { |
| return false; |
| } |
| else if (theLHSLength == 0) |
| { |
| return true; |
| } |
| else |
| { |
| const XalanDOMChar* const theEnd = theLHS + theLHSLength; |
| |
| while(*theLHS == *theRHS) |
| { |
| ++theLHS; |
| |
| if (theLHS == theEnd) |
| { |
| return true; |
| } |
| else |
| { |
| ++theRHS; |
| } |
| } |
| |
| return false; |
| } |
| } |
| |
| |
| |
| bool |
| XalanDOMString::equals( |
| const XalanDOMString& theLHS, |
| const XalanDOMString& theRHS) |
| { |
| const XalanDOMString::size_type theLHSLength = theLHS.size(); |
| const XalanDOMString::size_type theRHSLength = theRHS.size(); |
| |
| if (theLHSLength != theRHSLength) |
| { |
| return false; |
| } |
| else |
| { |
| return equals(theLHS.c_str(), theLHSLength, theRHS.c_str(), theRHSLength); |
| } |
| } |
| |
| |
| |
| XalanDOMString::size_type |
| XalanDOMString::length(const XalanDOMChar* theString) |
| { |
| return ::length(theString); |
| } |
| |
| |
| |
| XalanDOMString::size_type |
| XalanDOMString::length(const char* theString) |
| { |
| assert(theString != 0); |
| |
| #if defined(XALAN_STRICT_ANSI_HEADERS) |
| assert(std::strlen(theString) < size_type(npos)); |
| |
| return size_type(std::strlen(theString)); |
| #else |
| assert(strlen(theString) < size_type(npos)); |
| |
| return size_type(strlen(theString)); |
| #endif |
| |
| } |
| |
| |
| |
| #if defined(XALAN_USE_XERCES_LOCAL_CODEPAGE_TRANSCODERS) |
| |
| |
| |
| #include <util/XMLString.hpp> |
| |
| |
| |
| template <class SourceType, class TargetType> |
| bool |
| doXercesTranscode( |
| const SourceType* theSourceString, |
| XalanDOMString::size_type theSourceStringLength, |
| bool theSourceStringIsNullTerminated, |
| #if defined(XALAN_NO_NAMESPACES) |
| vector<TargetType>& theTargetVector, |
| #else |
| std::vector<TargetType>& theTargetVector, |
| #endif |
| bool terminate) |
| { |
| const SourceType* theRealSourceString = theSourceString; |
| |
| XalanDOMString::size_type theRealSourceStringLength = theSourceStringLength; |
| |
| XalanArrayAutoPtr<SourceType> theGuard; |
| |
| if (theSourceStringIsNullTerminated == true) |
| { |
| theRealSourceStringLength = XalanDOMString::length(theSourceString); |
| } |
| else |
| { |
| theGuard.reset(new SourceType[theRealSourceStringLength + 1]); |
| assert(theGuard.get() != 0); |
| |
| for (XalanDOMString::size_type index = 0; index < theRealSourceStringLength; ++index) |
| { |
| theGuard[index] = theSourceString[index]; |
| } |
| |
| theGuard[theRealSourceStringLength] = SourceType(0); |
| |
| theRealSourceString = theGuard.get(); |
| } |
| |
| // Initially, let's guess the the transcoded string will be of the same |
| // length as the UTF-16 string. |
| theTargetVector.resize(theRealSourceStringLength + 1, TargetType(0)); |
| |
| assert(theRealSourceString != 0); |
| |
| unsigned int theAttempts = 0; |
| bool fSuccess = false; |
| |
| do |
| { |
| // $$$ ToDo: We should use the Xerces transcoder interface |
| // instead of XMLString::transcode(), so we can better control |
| // error handling and failures due to inadequate space. |
| fSuccess = XMLString::transcode( |
| theRealSourceString, |
| &*theTargetVector.begin(), |
| theTargetVector.size() - 1); |
| |
| if (fSuccess == false) |
| { |
| if (theAttempts > 2) |
| { |
| break; |
| } |
| else |
| { |
| ++theAttempts; |
| |
| theTargetVector.resize(theTargetVector.size() + 10, TargetType(0)); |
| } |
| } |
| } while (fSuccess == false); |
| |
| if (fSuccess == false) |
| { |
| theTargetVector.clear(); |
| } |
| else if (terminate == false) |
| { |
| while(theTargetVector.back() == TargetType(0)) |
| { |
| theTargetVector.pop_back(); |
| } |
| } |
| |
| return fSuccess; |
| } |
| |
| #endif |
| |
| |
| |
| static bool |
| doTranscodeToLocalCodePage( |
| const XalanDOMChar* theSourceString, |
| XalanDOMString::size_type theSourceStringLength, |
| bool theSourceStringIsNullTerminated, |
| CharVectorType& theTargetVector, |
| bool terminate) |
| { |
| #if defined(XALAN_STRICT_ANSI_HEADERS) |
| using std::wcstombs; |
| #endif |
| |
| // Short circuit if it's a null pointer, or of length 0. |
| if (!theSourceString || (!theSourceString[0])) |
| { |
| if (terminate == true) |
| { |
| theTargetVector.resize(1); |
| |
| theTargetVector.back() = '\0'; |
| } |
| else |
| { |
| theTargetVector.clear(); |
| } |
| |
| return true; |
| } |
| #if defined(XALAN_USE_XERCES_LOCAL_CODEPAGE_TRANSCODERS) |
| else |
| { |
| return doXercesTranscode( |
| theSourceString, |
| theSourceStringLength, |
| theSourceStringIsNullTerminated, |
| theTargetVector, |
| terminate); |
| } |
| #else |
| const wchar_t* theTempSource = 0; |
| |
| // If our char sizes are not the same, or the input string is not null-terminated, |
| // we have to use a temporary buffer. |
| XalanArrayAutoPtr<wchar_t> theTempSourceJanitor; |
| |
| #if !defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH) |
| // This is a short-cut for when the theSourceString is mull-terminated _and_ |
| // XalanDOMChar and wchar_t are the same thing. |
| if (theSourceStringIsNullTerminated == true) |
| { |
| theTempSource = theSourceString; |
| } |
| else |
| #endif |
| { |
| if (theSourceStringIsNullTerminated == true) |
| { |
| theSourceStringLength = length(theSourceString); |
| } |
| |
| theTempSourceJanitor.reset(new wchar_t[theSourceStringLength + 1]); |
| |
| for (size_t index = 0; index < theSourceStringLength; ++index) |
| { |
| theTempSourceJanitor[index] = wchar_t(theSourceString[index]); |
| } |
| |
| theTempSourceJanitor[theSourceStringLength] = 0; |
| |
| theTempSource = theTempSourceJanitor.get(); |
| } |
| |
| // See how many chars we need to transcode. |
| const size_t targetLen = wcstombs(0, theTempSource, 0); |
| |
| if (targetLen == size_t(-1)) |
| { |
| return false; |
| } |
| else |
| { |
| // Resize, adding one byte if terminating... |
| theTargetVector.resize(terminate == true ? targetLen + 1 : targetLen); |
| |
| // And transcode our temp source buffer to the local buffer. Terminate |
| // |
| if (wcstombs(&theTargetVector[0], theTempSource, targetLen) == size_t(-1)) |
| { |
| theTargetVector.clear(); |
| |
| return false; |
| } |
| else |
| { |
| if (terminate == true) |
| { |
| theTargetVector.back() = '\0'; |
| } |
| |
| return true; |
| } |
| } |
| #endif |
| } |
| |
| |
| |
| XALAN_DOM_EXPORT_FUNCTION(bool) |
| TranscodeToLocalCodePage( |
| const XalanDOMChar* theSourceString, |
| XalanDOMString::size_type theSourceStringLength, |
| CharVectorType& theTargetVector, |
| bool terminate) |
| { |
| return doTranscodeToLocalCodePage(theSourceString, theSourceStringLength, false, theTargetVector, terminate); |
| } |
| |
| |
| |
| XALAN_DOM_EXPORT_FUNCTION(bool) |
| TranscodeToLocalCodePage( |
| const XalanDOMChar* theSourceString, |
| CharVectorType& theTargetVector, |
| bool terminate) |
| { |
| return doTranscodeToLocalCodePage(theSourceString, 0, true, theTargetVector, terminate); |
| } |
| |
| |
| |
| static bool |
| doTranscodeFromLocalCodePage( |
| const char* theSourceString, |
| XalanDOMString::size_type theSourceStringLength, |
| bool theSourceStringIsNullTerminated, |
| XalanDOMCharVectorType& theTargetVector, |
| bool terminate) |
| { |
| #if defined(XALAN_STRICT_ANSI_HEADERS) |
| using std::mbstowcs; |
| #endif |
| |
| typedef XalanDOMString::size_type size_type; |
| |
| // Short circuit if it's a null pointer, or of length 0. |
| if (!theSourceString || (!theSourceString[0])) |
| { |
| if (terminate == true) |
| { |
| theTargetVector.resize(1); |
| |
| theTargetVector.back() = '\0'; |
| } |
| else |
| { |
| theTargetVector.clear(); |
| } |
| |
| return true; |
| } |
| #if defined(XALAN_USE_XERCES_LOCAL_CODEPAGE_TRANSCODERS) |
| else |
| { |
| return doXercesTranscode( |
| theSourceString, |
| theSourceStringLength, |
| theSourceStringIsNullTerminated, |
| theTargetVector, |
| terminate); |
| } |
| #else |
| XalanArrayAutoPtr<char> tempString; |
| |
| if (theSourceStringIsNullTerminated == true) |
| { |
| theSourceStringLength = XalanDOMString::length(theSourceString); |
| } |
| else |
| { |
| tempString.reset(new char[theSourceStringLength + 1]); |
| |
| #if defined(XALAN_STRICT_ANSI_HEADERS) |
| std::strncpy(tempString.get(), theSourceString, theSourceStringLength); |
| #else |
| strncpy(tempString.get(), theSourceString, theSourceStringLength); |
| #endif |
| |
| tempString[theSourceStringLength] = '\0'; |
| |
| theSourceString = tempString.get(); |
| } |
| |
| // See how many chars we need to transcode. |
| const size_t theTargetLength = |
| mbstowcs(0, theSourceString, size_t(theSourceStringLength)); |
| |
| if (theTargetLength == size_t(-1)) |
| { |
| return false; |
| } |
| else |
| { |
| #if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH) |
| typedef XalanDOMString::WideCharVectorType WideCharVectorType; |
| |
| WideCharVectorType theTempResult; |
| |
| theTempResult.resize(terminate == true ? theTargetLength + 1 : theTargetLength); |
| |
| wchar_t* const theTargetPointer = &theTempResult[0]; |
| #else |
| theTargetVector.resize(terminate == true ? theTargetLength + 1 : theTargetLength); |
| |
| wchar_t* const theTargetPointer = &theTargetVector[0]; |
| #endif |
| |
| if (mbstowcs(theTargetPointer, theSourceString, size_t(theSourceStringLength)) == size_t(-1)) |
| { |
| theTargetVector.clear(); |
| |
| return false; |
| } |
| else |
| { |
| #if defined(XALAN_XALANDOMCHAR_USHORT_MISMATCH) |
| const WideCharVectorType::size_type theTempSize = theTempResult.size(); |
| |
| theTargetVector.reserve(theTempSize); |
| |
| for(WideCharVectorType::size_type i = 0; i < theTempSize; ++i) |
| { |
| theTargetVector.push_back(theTempResult[i]); |
| } |
| #endif |
| |
| if (terminate == true) |
| { |
| theTargetVector.back() = '\0'; |
| } |
| |
| return true; |
| } |
| } |
| #endif |
| } |
| |
| |
| |
| XALAN_DOM_EXPORT_FUNCTION(bool) |
| TranscodeFromLocalCodePage( |
| const char* theSourceString, |
| XalanDOMString::size_type theSourceStringLength, |
| XalanDOMCharVectorType& theTargetVector, |
| bool terminate) |
| { |
| return doTranscodeFromLocalCodePage(theSourceString, theSourceStringLength, false, theTargetVector, terminate); |
| } |
| |
| |
| |
| XALAN_DOM_EXPORT_FUNCTION(bool) |
| TranscodeFromLocalCodePage( |
| const char* theSourceString, |
| XalanDOMCharVectorType& theTargetVector, |
| bool terminate) |
| { |
| return doTranscodeFromLocalCodePage(theSourceString, 0, true, theTargetVector, terminate); |
| } |