mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-06 14:05:32 +00:00
ICU-4506 Break alias table dependency on the rest of conversion code
X-SVN-Rev: 17568
This commit is contained in:
parent
3f20ab8dba
commit
17fa571373
7 changed files with 281 additions and 312 deletions
|
@ -34,7 +34,6 @@
|
|||
#include "utracimp.h"
|
||||
#include "ustr_imp.h"
|
||||
#include "ucnv_imp.h"
|
||||
#include "ucnv_io.h"
|
||||
#include "ucnv_cnv.h"
|
||||
#include "ucnv_bld.h"
|
||||
|
||||
|
@ -56,17 +55,6 @@ static const UAmbiguousConverter ambiguousConverters[]={
|
|||
{ "ISO_2022,locale=ko,version=0", 0x20a9 }
|
||||
};
|
||||
|
||||
U_CAPI const char* U_EXPORT2
|
||||
ucnv_getDefaultName ()
|
||||
{
|
||||
return ucnv_io_getDefaultConverterName();
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
ucnv_setDefaultName (const char *converterName)
|
||||
{
|
||||
ucnv_io_setDefaultConverterName(converterName);
|
||||
}
|
||||
/*Calls through createConverter */
|
||||
U_CAPI UConverter* U_EXPORT2
|
||||
ucnv_open (const char *name,
|
||||
|
@ -107,6 +95,28 @@ ucnv_openU (const UChar * name,
|
|||
return ucnv_open(u_austrcpy(asciiName, name), err);
|
||||
}
|
||||
|
||||
/* Copy the string that is represented by the UConverterPlatform enum
|
||||
* @param platformString An output buffer
|
||||
* @param platform An enum representing a platform
|
||||
* @return the length of the copied string.
|
||||
*/
|
||||
static int32_t
|
||||
ucnv_copyPlatformString(char *platformString, UConverterPlatform pltfrm)
|
||||
{
|
||||
switch (pltfrm)
|
||||
{
|
||||
case UCNV_IBM:
|
||||
uprv_strcpy(platformString, "ibm-");
|
||||
return 4;
|
||||
case UCNV_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
|
||||
/* default to empty string */
|
||||
*platformString = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*Assumes a $platform-#codepage.$CONVERTER_FILE_EXTENSION scheme and calls
|
||||
*through createConverter*/
|
||||
U_CAPI UConverter* U_EXPORT2
|
||||
|
@ -350,47 +360,21 @@ ucnv_close (UConverter * converter)
|
|||
U_CAPI const char* U_EXPORT2
|
||||
ucnv_getAvailableName (int32_t n)
|
||||
{
|
||||
if (0 <= n && n <= 0xffff) {
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
const char *name = ucnv_io_getAvailableConverter((uint16_t)n, &err);
|
||||
if (U_SUCCESS(err)) {
|
||||
return name;
|
||||
if (0 <= n && n <= 0xffff) {
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
const char *name = ucnv_bld_getAvailableConverter((uint16_t)n, &err);
|
||||
if (U_SUCCESS(err)) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
ucnv_countAvailable ()
|
||||
{
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
return ucnv_io_countAvailableConverters(&err);
|
||||
}
|
||||
|
||||
U_CAPI uint16_t U_EXPORT2
|
||||
ucnv_countAliases(const char *alias, UErrorCode *pErrorCode)
|
||||
{
|
||||
return ucnv_io_countAliases(alias, pErrorCode);
|
||||
}
|
||||
|
||||
|
||||
U_CAPI const char* U_EXPORT2
|
||||
ucnv_getAlias(const char *alias, uint16_t n, UErrorCode *pErrorCode)
|
||||
{
|
||||
return ucnv_io_getAlias(alias, n, pErrorCode);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
ucnv_getAliases(const char *alias, const char **aliases, UErrorCode *pErrorCode)
|
||||
{
|
||||
ucnv_io_getAliases(alias, 0, aliases, pErrorCode);
|
||||
}
|
||||
|
||||
U_CAPI uint16_t U_EXPORT2
|
||||
ucnv_countStandards(void)
|
||||
{
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
return ucnv_io_countStandards(&err);
|
||||
return ucnv_bld_countAvailableConverters(&err);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
********************************************************************
|
||||
* COPYRIGHT:
|
||||
* Copyright (c) 1996-2004, International Business Machines Corporation and
|
||||
* Copyright (c) 1996-2005, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
********************************************************************
|
||||
*
|
||||
|
@ -23,6 +23,7 @@
|
|||
|
||||
#if !UCONFIG_NO_CONVERSION
|
||||
|
||||
#include "unicode/putil.h"
|
||||
#include "unicode/udata.h"
|
||||
#include "unicode/ucnv.h"
|
||||
#include "unicode/uloc.h"
|
||||
|
@ -154,6 +155,12 @@ static UMTX cnvCacheMutex = NULL; /* Mutex for synchronizing cnv cache a
|
|||
/* Note: the global mutex is used for */
|
||||
/* reference count updates. */
|
||||
|
||||
static const char **gAvailableConverters = NULL;
|
||||
static uint16_t gAvailableConverterCount = 0;
|
||||
|
||||
static char gDefaultConverterNameBuffer[UCNV_MAX_CONVERTER_NAME_LENGTH + 1]; /* +1 for NULL */
|
||||
static const char *gDefaultConverterName = NULL;
|
||||
|
||||
|
||||
static const char DATA_TYPE[] = "cnv";
|
||||
|
||||
|
@ -170,6 +177,12 @@ static UBool U_CALLCONV ucnv_cleanup(void) {
|
|||
}
|
||||
}
|
||||
|
||||
/* Called from ucnv_flushCache because it allocates the hashtable */
|
||||
/*ucnv_flushAvailableConverterCache();*/
|
||||
|
||||
gDefaultConverterName = NULL;
|
||||
gDefaultConverterNameBuffer[0] = 0;
|
||||
|
||||
umtx_destroy(&cnvCacheMutex); /* Don't worry about destroying the mutex even */
|
||||
/* if the hash table still exists. The mutex */
|
||||
/* will lazily re-init itself if needed. */
|
||||
|
@ -307,23 +320,6 @@ static UConverterSharedData *createConverterFromFile(UConverterLoadArgs *pArgs,
|
|||
return sharedData;
|
||||
}
|
||||
|
||||
int32_t
|
||||
ucnv_copyPlatformString(char *platformString, UConverterPlatform pltfrm)
|
||||
{
|
||||
switch (pltfrm)
|
||||
{
|
||||
case UCNV_IBM:
|
||||
uprv_strcpy(platformString, "ibm-");
|
||||
return 4;
|
||||
case UCNV_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
|
||||
/* default to empty string */
|
||||
*platformString = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*returns a converter type from a string
|
||||
*/
|
||||
static const UConverterSharedData *
|
||||
|
@ -379,7 +375,7 @@ ucnv_shareConverterData(UConverterSharedData * data)
|
|||
if (SHARED_DATA_HASHTABLE == NULL)
|
||||
{
|
||||
SHARED_DATA_HASHTABLE = uhash_openSize(uhash_hashChars, uhash_compareChars,
|
||||
ucnv_io_countAvailableAliases(&err),
|
||||
ucnv_io_countTotalAliases(&err),
|
||||
&err);
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
|
||||
|
||||
|
@ -676,7 +672,7 @@ ucnv_loadSharedData(const char *converterName, UConverterLookupData *lookup, UEr
|
|||
|
||||
/* In case "name" is NULL we want to open the default converter. */
|
||||
if (converterName == NULL) {
|
||||
lookup->realName = ucnv_io_getDefaultConverterName();
|
||||
lookup->realName = ucnv_getDefaultName();
|
||||
if (lookup->realName == NULL) {
|
||||
*err = U_MISSING_RESOURCE_ERROR;
|
||||
return NULL;
|
||||
|
@ -905,6 +901,17 @@ ucnv_createConverterFromSharedData(UConverter *myUConverter,
|
|||
return myUConverter;
|
||||
}
|
||||
|
||||
static void
|
||||
ucnv_flushAvailableConverterCache() {
|
||||
if (gAvailableConverters) {
|
||||
umtx_lock(&cnvCacheMutex);
|
||||
gAvailableConverterCount = 0;
|
||||
uprv_free((char **)gAvailableConverters);
|
||||
gAvailableConverters = NULL;
|
||||
umtx_unlock(&cnvCacheMutex);
|
||||
}
|
||||
}
|
||||
|
||||
/*Frees all shared immutable objects that aren't referred to (reference count = 0)
|
||||
*/
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
|
@ -974,12 +981,178 @@ ucnv_flushCache ()
|
|||
|
||||
UTRACE_DATA1(UTRACE_INFO, "ucnv_flushCache() exits with %d converters remaining", remaining);
|
||||
|
||||
ucnv_io_flushAvailableConverterCache();
|
||||
ucnv_flushAvailableConverterCache();
|
||||
|
||||
UTRACE_EXIT_VALUE(tableDeletedNum);
|
||||
return tableDeletedNum;
|
||||
}
|
||||
|
||||
/* available converters list --------------------------------------------------- */
|
||||
|
||||
static UBool haveAvailableConverterList(UErrorCode *pErrorCode) {
|
||||
int needInit;
|
||||
UMTX_CHECK(&cnvCacheMutex, (gAvailableConverters == NULL), needInit);
|
||||
if (needInit) {
|
||||
UConverter tempConverter;
|
||||
UEnumeration *allConvEnum = NULL;
|
||||
uint16_t idx;
|
||||
uint16_t localConverterCount;
|
||||
uint16_t allConverterCount;
|
||||
UErrorCode localStatus;
|
||||
const char *converterName;
|
||||
const char **localConverterList;
|
||||
|
||||
allConvEnum = ucnv_openAllNames(pErrorCode);
|
||||
allConverterCount = uenum_count(allConvEnum, pErrorCode);
|
||||
if (U_FAILURE(*pErrorCode)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* We can't have more than "*converterTable" converters to open */
|
||||
localConverterList = (const char **) uprv_malloc(allConverterCount * sizeof(char*));
|
||||
if (!localConverterList) {
|
||||
*pErrorCode = U_MEMORY_ALLOCATION_ERROR;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
localConverterCount = 0;
|
||||
|
||||
for (idx = 0; idx < allConverterCount; idx++) {
|
||||
localStatus = U_ZERO_ERROR;
|
||||
converterName = uenum_next(allConvEnum, NULL, &localStatus);
|
||||
ucnv_close(ucnv_createConverter(&tempConverter, converterName, &localStatus));
|
||||
if (U_SUCCESS(localStatus)) {
|
||||
localConverterList[localConverterCount++] = converterName;
|
||||
}
|
||||
}
|
||||
uenum_close(allConvEnum);
|
||||
|
||||
umtx_lock(&cnvCacheMutex);
|
||||
if (gAvailableConverters == NULL) {
|
||||
gAvailableConverters = localConverterList;
|
||||
gAvailableConverterCount = localConverterCount;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
|
||||
}
|
||||
else {
|
||||
uprv_free((char **)localConverterList);
|
||||
}
|
||||
umtx_unlock(&cnvCacheMutex);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
U_CFUNC uint16_t
|
||||
ucnv_bld_countAvailableConverters(UErrorCode *pErrorCode) {
|
||||
if (haveAvailableConverterList(pErrorCode)) {
|
||||
return gAvailableConverterCount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_CFUNC const char *
|
||||
ucnv_bld_getAvailableConverter(uint16_t n, UErrorCode *pErrorCode) {
|
||||
if (haveAvailableConverterList(pErrorCode)) {
|
||||
if (n < gAvailableConverterCount) {
|
||||
return gAvailableConverters[n];
|
||||
}
|
||||
*pErrorCode = U_INDEX_OUTOFBOUNDS_ERROR;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* default converter name --------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* In order to be really thread-safe, the get function would have to take
|
||||
* a buffer parameter and copy the current string inside a mutex block.
|
||||
* This implementation only tries to be really thread-safe while
|
||||
* setting the name.
|
||||
* It assumes that setting a pointer is atomic.
|
||||
*/
|
||||
|
||||
U_CAPI const char* U_EXPORT2
|
||||
ucnv_getDefaultName() {
|
||||
/* local variable to be thread-safe */
|
||||
const char *name;
|
||||
|
||||
UMTX_CHECK(&cnvCacheMutex, gDefaultConverterName, name);
|
||||
if(name==NULL) {
|
||||
UErrorCode errorCode = U_ZERO_ERROR;
|
||||
UConverter *cnv = NULL;
|
||||
int32_t length = 0;
|
||||
|
||||
name = uprv_getDefaultCodepage();
|
||||
|
||||
/* if the name is there, test it out and get the canonical name with options */
|
||||
if(name != NULL) {
|
||||
cnv = ucnv_open(name, &errorCode);
|
||||
if(U_SUCCESS(errorCode) && cnv != NULL) {
|
||||
name = ucnv_getName(cnv, &errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
if(name == NULL || name[0] == 0
|
||||
|| U_FAILURE(errorCode) || cnv == NULL
|
||||
|| length>=sizeof(gDefaultConverterNameBuffer))
|
||||
{
|
||||
/* Panic time, let's use a fallback. */
|
||||
#if (U_CHARSET_FAMILY == U_ASCII_FAMILY)
|
||||
name = "US-ASCII";
|
||||
/* there is no 'algorithmic' converter for EBCDIC */
|
||||
#elif defined(OS390)
|
||||
name = "ibm-1047_P100-1995" UCNV_SWAP_LFNL_OPTION_STRING;
|
||||
#else
|
||||
name = "ibm-37_P100-1995";
|
||||
#endif
|
||||
}
|
||||
|
||||
length=(int32_t)(uprv_strlen(name));
|
||||
|
||||
/* Copy the name before we close the converter. */
|
||||
umtx_lock(&cnvCacheMutex);
|
||||
uprv_memcpy(gDefaultConverterNameBuffer, name, length);
|
||||
gDefaultConverterNameBuffer[length]=0;
|
||||
gDefaultConverterName = gDefaultConverterNameBuffer;
|
||||
name = gDefaultConverterName;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
|
||||
umtx_unlock(&cnvCacheMutex);
|
||||
|
||||
/* The close may make the current name go away. */
|
||||
ucnv_close(cnv);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
ucnv_setDefaultName(const char *converterName) {
|
||||
if(converterName==NULL) {
|
||||
/* reset to the default codepage */
|
||||
umtx_lock(&cnvCacheMutex);
|
||||
gDefaultConverterName=NULL;
|
||||
umtx_unlock(&cnvCacheMutex);
|
||||
} else {
|
||||
UErrorCode errorCode=U_ZERO_ERROR;
|
||||
const char *name=ucnv_io_getConverterName(converterName, &errorCode);
|
||||
|
||||
umtx_lock(&cnvCacheMutex);
|
||||
|
||||
if(U_SUCCESS(errorCode) && name!=NULL) {
|
||||
gDefaultConverterName=name;
|
||||
} else {
|
||||
/* do not set the name if the alias lookup failed and it is too long */
|
||||
int32_t length=(int32_t)(uprv_strlen(converterName));
|
||||
if(length<sizeof(gDefaultConverterNameBuffer)) {
|
||||
/* it was not found as an alias, so copy it - accept an empty name */
|
||||
uprv_memcpy(gDefaultConverterNameBuffer, converterName, length);
|
||||
gDefaultConverterNameBuffer[length]=0;
|
||||
gDefaultConverterName=gDefaultConverterNameBuffer;
|
||||
}
|
||||
}
|
||||
umtx_unlock(&cnvCacheMutex);
|
||||
}
|
||||
}
|
||||
|
||||
/* data swapping ------------------------------------------------------------ */
|
||||
|
||||
/* most of this might belong more properly into ucnvmbcs.c, but that is so large */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1999-2004, International Business Machines
|
||||
* Copyright (C) 1999-2005, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*
|
||||
|
@ -221,6 +221,26 @@ U_CDECL_END /* end of UConverter */
|
|||
|
||||
#define CONVERTER_FILE_EXTENSION ".cnv"
|
||||
|
||||
|
||||
/**
|
||||
* Return the number of all converter names.
|
||||
* @param pErrorCode The error code
|
||||
* @return the number of all converter names
|
||||
*/
|
||||
U_CFUNC uint16_t
|
||||
ucnv_bld_countAvailableConverters(UErrorCode *pErrorCode);
|
||||
|
||||
/**
|
||||
* Return the (n)th converter name in mixed case, or NULL
|
||||
* if there is none (typically, if the data cannot be loaded).
|
||||
* 0<=index<ucnv_io_countAvailableConverters().
|
||||
* @param n The number specifies which converter name to get
|
||||
* @param pErrorCode The error code
|
||||
* @return the (n)th converter name in mixed case, or NULL if there is none.
|
||||
*/
|
||||
U_CFUNC const char *
|
||||
ucnv_bld_getAvailableConverter(uint16_t n, UErrorCode *pErrorCode);
|
||||
|
||||
/**
|
||||
* Load a non-algorithmic converter.
|
||||
* If pkg==NULL, then this function must be called inside umtx_lock(&cnvCacheMutex).
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1999-2004, International Business Machines
|
||||
* Copyright (C) 1999-2005, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*
|
||||
|
@ -87,13 +87,6 @@ ucnv_unloadSharedDataIfReady(UConverterSharedData *sharedData);
|
|||
void
|
||||
ucnv_incrementRefCount(UConverterSharedData *sharedData);
|
||||
|
||||
/* Copy the string that is represented by the UConverterPlatform enum
|
||||
* @param platformString An output buffer
|
||||
* @param platform An enum representing a platform
|
||||
* @return the length of the copied string.
|
||||
*/
|
||||
int32_t ucnv_copyPlatformString(char *platformString, UConverterPlatform platform);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _UCNV_IMP */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2004, International Business Machines
|
||||
* Copyright (C) 1999-2005, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -31,8 +31,7 @@
|
|||
|
||||
#if !UCONFIG_NO_CONVERSION
|
||||
|
||||
#include "unicode/putil.h"
|
||||
#include "unicode/ucnv.h" /* This file implements ucnv_xXXX() APIs */
|
||||
#include "unicode/ucnv.h"
|
||||
#include "unicode/udata.h"
|
||||
|
||||
#include "umutex.h"
|
||||
|
@ -196,12 +195,6 @@ static uint32_t gTaggedAliasArraySize;
|
|||
static uint32_t gTaggedAliasListsSize;
|
||||
static uint32_t gStringTableSize;
|
||||
|
||||
static const char **gAvailableConverters = NULL;
|
||||
static uint16_t gAvailableConverterCount = 0;
|
||||
|
||||
static char gDefaultConverterNameBuffer[UCNV_MAX_CONVERTER_NAME_LENGTH + 1]; /* +1 for NULL */
|
||||
static const char *gDefaultConverterName = NULL;
|
||||
|
||||
#define GET_STRING(idx) (const char *)(gStringTable + (idx))
|
||||
|
||||
static UBool U_CALLCONV
|
||||
|
@ -226,8 +219,6 @@ static UBool U_CALLCONV ucnv_io_cleanup(void)
|
|||
gAliasData = NULL;
|
||||
}
|
||||
|
||||
ucnv_io_flushAvailableConverterCache();
|
||||
|
||||
gConverterListSize = 0;
|
||||
gTagListSize = 0;
|
||||
gAliasListSize = 0;
|
||||
|
@ -244,26 +235,21 @@ static UBool U_CALLCONV ucnv_io_cleanup(void)
|
|||
gTaggedAliasLists = NULL;
|
||||
gStringTable = NULL;
|
||||
|
||||
gDefaultConverterName = NULL;
|
||||
gDefaultConverterNameBuffer[0] = 0;
|
||||
|
||||
return TRUE; /* Everything was cleaned up */
|
||||
}
|
||||
|
||||
static UBool
|
||||
haveAliasData(UErrorCode *pErrorCode) {
|
||||
int haveData;
|
||||
int needInit;
|
||||
|
||||
if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
umtx_lock(NULL);
|
||||
haveData = (int)(gAliasData==NULL);
|
||||
umtx_unlock(NULL);
|
||||
UMTX_CHECK(NULL, (gAliasData==NULL), needInit);
|
||||
|
||||
/* load converter alias data from file if necessary */
|
||||
if (haveData) {
|
||||
if (needInit) {
|
||||
UDataMemory *data = NULL;
|
||||
const uint16_t *table = NULL;
|
||||
uint32_t tableStart;
|
||||
|
@ -830,6 +816,32 @@ ucnv_getStandardName(const char *alias, const char *standard, UErrorCode *pError
|
|||
return NULL;
|
||||
}
|
||||
|
||||
U_CAPI uint16_t U_EXPORT2
|
||||
ucnv_countAliases(const char *alias, UErrorCode *pErrorCode)
|
||||
{
|
||||
return ucnv_io_countAliases(alias, pErrorCode);
|
||||
}
|
||||
|
||||
|
||||
U_CAPI const char* U_EXPORT2
|
||||
ucnv_getAlias(const char *alias, uint16_t n, UErrorCode *pErrorCode)
|
||||
{
|
||||
return ucnv_io_getAlias(alias, n, pErrorCode);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
ucnv_getAliases(const char *alias, const char **aliases, UErrorCode *pErrorCode)
|
||||
{
|
||||
ucnv_io_getAliases(alias, 0, aliases, pErrorCode);
|
||||
}
|
||||
|
||||
U_CAPI uint16_t U_EXPORT2
|
||||
ucnv_countStandards(void)
|
||||
{
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
return ucnv_io_countStandards(&err);
|
||||
}
|
||||
|
||||
U_CAPI const char * U_EXPORT2
|
||||
ucnv_getCanonicalName(const char *alias, const char *standard, UErrorCode *pErrorCode) {
|
||||
if (haveAliasData(pErrorCode) && isAlias(alias, pErrorCode)) {
|
||||
|
@ -843,80 +855,6 @@ ucnv_getCanonicalName(const char *alias, const char *standard, UErrorCode *pErro
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ucnv_io_flushAvailableConverterCache() {
|
||||
if (gAvailableConverters) {
|
||||
umtx_lock(NULL);
|
||||
gAvailableConverterCount = 0;
|
||||
uprv_free((char **)gAvailableConverters);
|
||||
gAvailableConverters = NULL;
|
||||
umtx_unlock(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static UBool haveAvailableConverterList(UErrorCode *pErrorCode) {
|
||||
if (gAvailableConverters == NULL) {
|
||||
uint16_t idx;
|
||||
uint16_t localConverterCount;
|
||||
UErrorCode status;
|
||||
const char *converterName;
|
||||
const char **localConverterList;
|
||||
|
||||
if (!haveAliasData(pErrorCode)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* We can't have more than "*converterTable" converters to open */
|
||||
localConverterList = (const char **) uprv_malloc(gConverterListSize * sizeof(char*));
|
||||
if (!localConverterList) {
|
||||
*pErrorCode = U_MEMORY_ALLOCATION_ERROR;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
localConverterCount = 0;
|
||||
|
||||
for (idx = 0; idx < gConverterListSize; idx++) {
|
||||
status = U_ZERO_ERROR;
|
||||
converterName = GET_STRING(gConverterList[idx]);
|
||||
ucnv_close(ucnv_open(converterName, &status));
|
||||
if (U_SUCCESS(status)) {
|
||||
localConverterList[localConverterCount++] = converterName;
|
||||
}
|
||||
}
|
||||
|
||||
umtx_lock(NULL);
|
||||
if (gAvailableConverters == NULL) {
|
||||
gAvailableConverters = localConverterList;
|
||||
gAvailableConverterCount = localConverterCount;
|
||||
/* haveData should have already registered the cleanup function */
|
||||
}
|
||||
else {
|
||||
uprv_free((char **)localConverterList);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
U_CFUNC uint16_t
|
||||
ucnv_io_countAvailableConverters(UErrorCode *pErrorCode) {
|
||||
if (haveAvailableConverterList(pErrorCode)) {
|
||||
return gAvailableConverterCount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_CFUNC const char *
|
||||
ucnv_io_getAvailableConverter(uint16_t n, UErrorCode *pErrorCode) {
|
||||
if (haveAvailableConverterList(pErrorCode)) {
|
||||
if (n < gAvailableConverterCount) {
|
||||
return gAvailableConverters[n];
|
||||
}
|
||||
*pErrorCode = U_INDEX_OUTOFBOUNDS_ERROR;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int32_t U_CALLCONV
|
||||
ucnv_io_countAllConverters(UEnumeration *enumerator, UErrorCode *pErrorCode) {
|
||||
return gConverterListSize;
|
||||
|
@ -981,109 +919,13 @@ ucnv_openAllNames(UErrorCode *pErrorCode) {
|
|||
}
|
||||
|
||||
U_CFUNC uint16_t
|
||||
ucnv_io_countAvailableAliases(UErrorCode *pErrorCode) {
|
||||
ucnv_io_countTotalAliases(UErrorCode *pErrorCode) {
|
||||
if (haveAliasData(pErrorCode)) {
|
||||
return (uint16_t)gAliasListSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* default converter name --------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* In order to be really thread-safe, the get function would have to take
|
||||
* a buffer parameter and copy the current string inside a mutex block.
|
||||
* This implementation only tries to be really thread-safe while
|
||||
* setting the name.
|
||||
* It assumes that setting a pointer is atomic.
|
||||
*/
|
||||
|
||||
U_CFUNC const char *
|
||||
ucnv_io_getDefaultConverterName() {
|
||||
/* local variable to be thread-safe */
|
||||
const char *name;
|
||||
|
||||
umtx_lock(NULL);
|
||||
name=gDefaultConverterName;
|
||||
umtx_unlock(NULL);
|
||||
|
||||
if(name==NULL) {
|
||||
UErrorCode errorCode = U_ZERO_ERROR;
|
||||
UConverter *cnv = NULL;
|
||||
int32_t length = 0;
|
||||
|
||||
name = uprv_getDefaultCodepage();
|
||||
|
||||
/* if the name is there, test it out and get the canonical name with options */
|
||||
if(name != NULL) {
|
||||
cnv = ucnv_open(name, &errorCode);
|
||||
if(U_SUCCESS(errorCode) && cnv != NULL) {
|
||||
name = ucnv_getName(cnv, &errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
if(name == NULL || name[0] == 0
|
||||
|| U_FAILURE(errorCode) || cnv == NULL
|
||||
|| length>=sizeof(gDefaultConverterNameBuffer))
|
||||
{
|
||||
/* Panic time, let's use a fallback. */
|
||||
#if (U_CHARSET_FAMILY == U_ASCII_FAMILY)
|
||||
name = "US-ASCII";
|
||||
/* there is no 'algorithmic' converter for EBCDIC */
|
||||
#elif defined(OS390)
|
||||
name = "ibm-1047_P100-1995" UCNV_SWAP_LFNL_OPTION_STRING;
|
||||
#else
|
||||
name = "ibm-37_P100-1995";
|
||||
#endif
|
||||
}
|
||||
|
||||
length=(int32_t)(uprv_strlen(name));
|
||||
|
||||
/* Copy the name before we close the converter. */
|
||||
umtx_lock(NULL);
|
||||
uprv_memcpy(gDefaultConverterNameBuffer, name, length);
|
||||
gDefaultConverterNameBuffer[length]=0;
|
||||
gDefaultConverterName = gDefaultConverterNameBuffer;
|
||||
name = gDefaultConverterName;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCNV_IO, ucnv_io_cleanup);
|
||||
umtx_unlock(NULL);
|
||||
|
||||
/* The close may make the current name go away. */
|
||||
ucnv_close(cnv);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
U_CFUNC void
|
||||
ucnv_io_setDefaultConverterName(const char *converterName) {
|
||||
if(converterName==NULL) {
|
||||
/* reset to the default codepage */
|
||||
umtx_lock(NULL);
|
||||
gDefaultConverterName=NULL;
|
||||
umtx_unlock(NULL);
|
||||
} else {
|
||||
UErrorCode errorCode=U_ZERO_ERROR;
|
||||
const char *name=ucnv_io_getConverterName(converterName, &errorCode);
|
||||
|
||||
umtx_lock(NULL);
|
||||
|
||||
if(U_SUCCESS(errorCode) && name!=NULL) {
|
||||
gDefaultConverterName=name;
|
||||
} else {
|
||||
/* do not set the name if the alias lookup failed and it is too long */
|
||||
int32_t length=(int32_t)(uprv_strlen(converterName));
|
||||
if(length<sizeof(gDefaultConverterNameBuffer)) {
|
||||
/* it was not found as an alias, so copy it - accept an empty name */
|
||||
uprv_memcpy(gDefaultConverterNameBuffer, converterName, length);
|
||||
gDefaultConverterNameBuffer[length]=0;
|
||||
gDefaultConverterName=gDefaultConverterNameBuffer;
|
||||
}
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* alias table swapping ----------------------------------------------------- */
|
||||
|
||||
typedef char * U_CALLCONV StripForCompareFn(char *dst, const char *name);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1999-2004, International Business Machines
|
||||
* Copyright (C) 1999-2005, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*
|
||||
|
@ -103,55 +103,13 @@ ucnv_io_getAlias(const char *alias, uint16_t n, UErrorCode *pErrorCode);
|
|||
U_CFUNC uint16_t
|
||||
ucnv_io_countStandards(UErrorCode *pErrorCode);
|
||||
|
||||
/**
|
||||
* Return the number of all converter names.
|
||||
* @param pErrorCode The error code
|
||||
* @return the number of all converter names
|
||||
*/
|
||||
U_CFUNC uint16_t
|
||||
ucnv_io_countAvailableConverters(UErrorCode *pErrorCode);
|
||||
|
||||
/**
|
||||
* Return the (n)th converter name in mixed case, or NULL
|
||||
* if there is none (typically, if the data cannot be loaded).
|
||||
* 0<=index<ucnv_io_countAvailableConverters().
|
||||
* @param n The number specifies which converter name to get
|
||||
* @param pErrorCode The error code
|
||||
* @return the (n)th converter name in mixed case, or NULL if there is none.
|
||||
*/
|
||||
U_CFUNC const char *
|
||||
ucnv_io_getAvailableConverter(uint16_t n, UErrorCode *pErrorCode);
|
||||
|
||||
/**
|
||||
* Return the (n)th converter name in mixed case, or NULL
|
||||
* if there is none (typically, if the data cannot be loaded).
|
||||
* 0<=index<ucnv_io_countAvailableConverters().
|
||||
*/
|
||||
U_CFUNC void
|
||||
ucnv_io_flushAvailableConverterCache(void);
|
||||
|
||||
/**
|
||||
* Return the number of all aliases (and converter names).
|
||||
* @param pErrorCode The error code
|
||||
* @return the number of all aliases
|
||||
*/
|
||||
U_CFUNC uint16_t
|
||||
ucnv_io_countAvailableAliases(UErrorCode *pErrorCode);
|
||||
|
||||
/**
|
||||
* Get the name of the default converter.
|
||||
* This name is already resolved by <code>ucnv_io_getConverterName()</code>.
|
||||
* @return the name of the default converter
|
||||
*/
|
||||
U_CFUNC const char *
|
||||
ucnv_io_getDefaultConverterName(void);
|
||||
|
||||
/**
|
||||
* Set the name of the default converter.
|
||||
* @param name The name set to the default converter
|
||||
*/
|
||||
U_CFUNC void
|
||||
ucnv_io_setDefaultConverterName(const char *name);
|
||||
ucnv_io_countTotalAliases(UErrorCode *pErrorCode);
|
||||
|
||||
/**
|
||||
* Swap an ICU converter alias table. See ucnv_io.c.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
********************************************************************************
|
||||
*
|
||||
* Copyright (C) 1998-2004, International Business Machines
|
||||
* Copyright (C) 1998-2005, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
********************************************************************************
|
||||
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include "unicode/putil.h"
|
||||
#include "ucnv_io.h"
|
||||
#include "unicode/ucnv_err.h"
|
||||
#include "ucnv_bld.h"
|
||||
#include "ucnv_imp.h"
|
||||
|
|
Loading…
Add table
Reference in a new issue