Newer
Older
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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/PlatformUtils.hpp>
#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
#if !defined(U16_NEXT_UNSAFE) && defined(UTF16_NEXT_CHAR_UNSAFE)
#define U16_NEXT_UNSAFE UTF16_NEXT_CHAR_UNSAFE
#endif
#if !defined(U16_APPEND_UNSAFE) && defined(UTF16_APPEND_CHAR_UNSAFE)
#define U16_APPEND_UNSAFE UTF16_APPEND_CHAR_UNSAFE
#endif
#if !defined(U_IS_BMP) && defined(UTF16_CHAR_LENGTH)
#define U_IS_BMP(c) (UTF16_CHAR_LENGTH(c)==1)
#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.
//
static UChar* convertToUChar( const XMLCh* const toConvert
, const XMLSize_t srcLen = 0
Khaled Noaman
committed
, MemoryManager* const manager = 0)
const XMLSize_t actualLen = srcLen
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];
XMLCh* outPtr = retBuf;
const UChar* srcPtr = toConvert;
while (*srcPtr)
*outPtr++ = XMLCh(*srcPtr++);
*outPtr = 0;
return retBuf;
}
// ---------------------------------------------------------------------------
// ICUTransService: Constructors and Destructor
// ---------------------------------------------------------------------------
ICUTransService::ICUTransService()
{
#if (U_ICU_VERSION_MAJOR_NUM > 2 || (U_ICU_VERSION_MAJOR_NUM == 2 && U_ICU_VERSION_MINOR_NUM >= 6))
UErrorCode errorCode=U_ZERO_ERROR;
u_init(&errorCode);
if(U_FAILURE(errorCode)) {
XMLPlatformUtils::panic(PanicHandler::Panic_NoTransService);
}
#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 lazily allocated data
u_cleanup();
#endif
}
// ---------------------------------------------------------------------------
// ICUTransService: The virtual transcoding service API
// ---------------------------------------------------------------------------
int ICUTransService::compareIString(const XMLCh* const comp1
, const XMLCh* const comp2)
{
Loading
Loading full blame...