Newer
Older
* 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$
*/
// ---------------------------------------------------------------------------
// Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/TranscodingException.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>
#include "ICUTransService.hpp"
#include <string.h>
#include <unicode/uloc.h>
#include <unicode/ucnv.h>
#include <unicode/ucnv_err.h>
#include <unicode/ustring.h>
#include <unicode/udata.h>
#if (U_ICU_VERSION_MAJOR_NUM >= 2)
#include <unicode/uclean.h>
#endif
#if !defined(XML_OS390) && !defined(XML_AS400) && !defined(XML_HPUX) && !defined(XML_PTX)
// Forward reference the symbol which points to the ICU converter data.
#if (U_ICU_VERSION_MAJOR_NUM < 2)
extern "C" const uint8_t U_IMPORT icudata_dat[];
#endif
#endif
// ---------------------------------------------------------------------------
// Local, const data
// ---------------------------------------------------------------------------
static const XMLCh gMyServiceId[] =
{
chLatin_I, chLatin_C, chLatin_U, chNull
};
static const XMLCh gS390Id[] =
{
chLatin_S, chDigit_3, chDigit_9, chDigit_0, chNull
};
static const XMLCh gs390Id[] =
{
chLatin_s, chDigit_3, chDigit_9, chDigit_0, chNull
};
static const XMLCh gswaplfnlId[] =
{
chComma, chLatin_s, chLatin_w, chLatin_a, chLatin_p,
chLatin_l, chLatin_f, chLatin_n, chLatin_l, chNull
};
// ---------------------------------------------------------------------------
// Local functions
// ---------------------------------------------------------------------------
//
// When XMLCh and ICU's UChar are not the same size, we have to do a temp
// conversion of all strings. These local helper methods make that easier.
//
Khaled Noaman
committed
static UChar* convertToUChar( const XMLCh* const toConvert
, const unsigned int srcLen = 0
, MemoryManager* const manager = 0)
{
const unsigned int actualLen = srcLen
? srcLen : XMLString::stringLen(toConvert);
Khaled Noaman
committed
UChar* tmpBuf = (manager)
? (UChar*) manager->allocate((actualLen + 1) * sizeof(UChar))
: new UChar[actualLen + 1];
const XMLCh* srcPtr = toConvert;
UChar* outPtr = tmpBuf;
while (*srcPtr)
*outPtr++ = UChar(*srcPtr++);
*outPtr = 0;
return tmpBuf;
}
static XMLCh* convertToXMLCh( const UChar* const toConvert,
MemoryManager* const manager = 0)
XMLCh* retBuf = (manager)
? (XMLCh*) manager->allocate((srcLen+1) * sizeof(XMLCh))
: new XMLCh[srcLen + 1];
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
XMLCh* outPtr = retBuf;
const UChar* srcPtr = toConvert;
while (*srcPtr)
*outPtr++ = XMLCh(*srcPtr++);
*outPtr = 0;
return retBuf;
}
// ---------------------------------------------------------------------------
// ICUTransService: Constructors and Destructor
// ---------------------------------------------------------------------------
ICUTransService::ICUTransService()
{
#if !defined(XML_OS390) && !defined(XML_AS400) && !defined(XML_HPUX) && !defined(XML_PTX)
#if (U_ICU_VERSION_MAJOR_NUM < 2)
// Starting with ICU 2.0, ICU itself includes a static reference to the data
// entrypoint symbol.
//
// ICU 1.8 (and previous) did not include a static reference, but would
// dynamically load the data dll when it was first needed, however this dynamic
// loading proved unreliable in some of the odd environments that Xerces needed
// to run in. Hence, the static reference.
// Pass the location of the converter data to ICU. By doing so, we are
// forcing the load of ICU converter data DLL, after the Xerces-C DLL is
// loaded. This implies that Xerces-C, now has to explicitly link with the
// ICU converter dll. However, the advantage is that we no longer depend
// on the code which does demand dynamic loading of DLL's. The demand
// loading is highly system dependent and was a constant source of support
// calls.
UErrorCode uerr = U_ZERO_ERROR;
udata_setCommonData((void *) icudata_dat, &uerr);
#endif
#endif
}
ICUTransService::~ICUTransService()
{
/*
* commented out the following clean up code
* in case users use ICU outside of the parser
* if we clean up here, users' code may crash
*
#if (U_ICU_VERSION_MAJOR_NUM >= 2)
// release all lasily allocated data
u_cleanup();
#endif
}
// ---------------------------------------------------------------------------
// ICUTransService: The virtual transcoding service API
// ---------------------------------------------------------------------------
int ICUTransService::compareIString(const XMLCh* const comp1
, const XMLCh* const comp2)
{
const XMLCh* psz1 = comp1;
const XMLCh* psz2 = comp2;
unsigned int curCount = 0;
while (true)
{
//
// If an inequality, then return the difference. Note that the XMLCh
// might be bigger physically than UChar, but it won't hold anything
// larger than 0xFFFF, so our cast here will work for both possible
// sizes of XMLCh.
//
return int(*psz1) - int(*psz2);
// If either has ended, then they both ended, so equal
if (!*psz1 || !*psz2)
break;
// Move upwards for the next round
psz1++;
psz2++;
}
return 0;
}
int ICUTransService::compareNIString(const XMLCh* const comp1
, const XMLCh* const comp2
, const unsigned int maxChars)
{
Loading
Loading full blame...