ICU-266 c++-ify UConverter (UConverterImpl resembles a vtable)

X-SVN-Rev: 736
This commit is contained in:
Markus Scherer 2000-02-09 19:15:17 +00:00
parent f83bf17a46
commit 111462800f
8 changed files with 129 additions and 158 deletions

View file

@ -1048,17 +1048,15 @@ void ucnv_getStarters(const UConverter* converter,
bool_t starters[256],
UErrorCode* err)
{
if (U_FAILURE(*err)) return;
/*Fire off an error if converter is not UCNV_MBCS*/
if (converter->sharedData->conversionType != UCNV_MBCS)
{
*err = U_ILLEGAL_ARGUMENT_ERROR;
return;
if (err == NULL || U_FAILURE(*err)) {
return;
}
if(converter->sharedData->impl->getStarters != NULL) {
converter->sharedData->impl->getStarters(converter, starters, err);
} else {
*err = U_ILLEGAL_ARGUMENT_ERROR;
}
/*fill's in the starters boolean array*/
uprv_memcpy(starters, converter->sharedData->table->mbcs.starters, 256*sizeof(bool_t));
return;
}
int32_t ucnv_getAmbiguousCCSID(const UConverter *cnv)

View file

@ -137,7 +137,7 @@ _ISO2022Open(UConverter *cnv, const char *name, const char *locale, UErrorCode *
static void
_ISO2022Close(UConverter *converter) {
if (converter->mode == UCNV_SO) {
if (converter->extraInfo != NULL) {
ucnv_close (((UConverterDataISO2022 *) (converter->extraInfo))->currentConverter);
uprv_free (converter->extraInfo);
}
@ -668,7 +668,7 @@ UChar T_UConverter_getNextUChar_ISO_2022(UConverter* converter,
return 0xFFFD;
}
static UConverterImpl _ISO2022Impl={
static const UConverterImpl _ISO2022Impl={
UCNV_ISO_2022,
NULL,
@ -682,10 +682,12 @@ static UConverterImpl _ISO2022Impl={
T_UConverter_toUnicode_ISO_2022_OFFSETS_LOGIC,
T_UConverter_fromUnicode_ISO_2022,
T_UConverter_fromUnicode_ISO_2022_OFFSETS_LOGIC,
T_UConverter_getNextUChar_ISO_2022
T_UConverter_getNextUChar_ISO_2022,
NULL
};
extern UConverterSharedData _ISO2022Data={
extern const UConverterSharedData _ISO2022Data={
sizeof(UConverterSharedData), ~0,
NULL, NULL, &_ISO2022Impl, "ISO_2022",
2022, UCNV_IBM, UCNV_ISO_2022, 1, 4,
@ -1272,7 +1274,7 @@ UChar T_UConverter_getNextUChar_EBCDIC_STATEFUL(UConverter* converter,
}
}
static UConverterImpl _EBCDICStatefulImpl={
static const UConverterImpl _EBCDICStatefulImpl={
UCNV_EBCDIC_STATEFUL,
_DBCSLoad,
@ -1286,10 +1288,12 @@ static UConverterImpl _EBCDICStatefulImpl={
T_UConverter_toUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC,
T_UConverter_fromUnicode_EBCDIC_STATEFUL,
T_UConverter_fromUnicode_EBCDIC_STATEFUL_OFFSETS_LOGIC,
T_UConverter_getNextUChar_EBCDIC_STATEFUL
T_UConverter_getNextUChar_EBCDIC_STATEFUL,
NULL
};
extern UConverterSharedData _EBCDICStatefulData={
extern const UConverterSharedData _EBCDICStatefulData={
sizeof(UConverterSharedData), 1,
NULL, NULL, &_EBCDICStatefulImpl, "EBCDICStateful",
0, UCNV_IBM, UCNV_EBCDIC_STATEFUL, 1, 1,

View file

@ -60,17 +60,10 @@ static struct {
*goes to disk and opens it.
*allocates the memory and returns a new UConverter object
*/
static UConverter *createConverterFromFile (const char *converterName, UErrorCode * err);
static UConverterSharedData *createConverterFromFile (const char *converterName, UErrorCode * err);
static const UConverterSharedData *getAlgorithmicTypeFromName (const char *realName);
/*these functions initialize the lightweight mutable part of the
*object to correct values based on the sharedData defaults.
*/
static void initializeDataConverter (UConverter * myConverter);
static void initializeAlgorithmicConverter (UConverter * myConverter);
/**
*hash function for UConverterSharedData
*/
@ -109,22 +102,9 @@ UConverterSharedData_1_4;
*/
U_CAPI UConverterSharedData* U_EXPORT2 ucnv_data_unFlattenClone(UDataMemory *pData, UErrorCode *status);
/*initializes some global variables */
UHashtable *SHARED_DATA_HASHTABLE = NULL;
/*Returns uppercased string */
char *
strtoupper (char *name)
{
int32_t i = 0;
while (name[i] = uprv_toupper (name[i]))
i++;
return name;
}
static bool_t
isCnvAcceptable(void *context,
const char *type, const char *name,
@ -143,10 +123,10 @@ isCnvAcceptable(void *context,
#define DATA_TYPE "cnv"
UConverter* createConverterFromFile (const char *fileName, UErrorCode * err)
UConverterSharedData *createConverterFromFile (const char *fileName, UErrorCode * err)
{
UConverter *myConverter = NULL;
UDataMemory *data;
UConverterSharedData *sharedData;
if (err == NULL || U_FAILURE (*err)) {
return NULL;
@ -158,25 +138,14 @@ UConverter* createConverterFromFile (const char *fileName, UErrorCode * err)
return NULL;
}
myConverter = (UConverter *) uprv_malloc (sizeof (UConverter));
if (myConverter == NULL)
{
udata_close(data);
*err = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
myConverter->sharedData = ucnv_data_unFlattenClone(data, err);
sharedData = ucnv_data_unFlattenClone(data, err);
if(U_FAILURE(*err))
{
udata_close(data);
uprv_free (myConverter);
return NULL;
}
initializeDataConverter (myConverter);
return myConverter;
return sharedData;
}
void
@ -324,6 +293,7 @@ UConverter *
isDefaultConverter = FALSE;
}
/* resolve aliases */
if (*converterName == 0) {
/* Use the PlatformInvariant algorithmic converter. */
realName = "PlatformInvariant";
@ -342,122 +312,74 @@ UConverter *
}
}
/* get the shared data for an algorithmic converter, if it is one */
mySharedConverterData = (UConverterSharedData *)getAlgorithmicTypeFromName (realName);
if (mySharedConverterData == NULL)
{
/* it is a data-based converter, get its shared data */
mySharedConverterData = getSharedConverterData (realName);
if (mySharedConverterData == NULL)
{
/*Not cached, we need to stream it in from file */
myUConverter = createConverterFromFile (realName, err);
if (U_FAILURE (*err) || (myUConverter == NULL))
mySharedConverterData = createConverterFromFile (realName, err);
if (U_FAILURE (*err) || (mySharedConverterData == NULL))
{
return myUConverter;
return NULL;
}
else
{
/*shared it with other library clients */
shareConverterData (myUConverter->sharedData);
return myUConverter;
/* share it with other library clients */
shareConverterData (mySharedConverterData);
}
}
else
{
/*Is already cached, point to an existing one */
myUConverter = (UConverter *) uprv_malloc (sizeof (UConverter));
if (myUConverter == NULL)
{
*err = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
/* ### this is unsafe: the shared data could have been deleted since sharing or getting it - these operations should increase the counter! */
/*update the reference counter: one more client */
/* update the reference counter: one more client */
umtx_lock (NULL);
mySharedConverterData->referenceCounter++;
umtx_unlock (NULL);
myUConverter->sharedData = mySharedConverterData;
initializeDataConverter (myUConverter);
return myUConverter;
}
}
else
/* allocate the converter */
myUConverter = (UConverter *) uprv_malloc (sizeof (UConverter));
if (myUConverter == NULL)
{
myUConverter = (UConverter *) uprv_malloc (sizeof (UConverter));
if (myUConverter == NULL)
{
*err = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
/*initializes the converter */
uprv_memset(myUConverter, 0, sizeof(UConverter));
myUConverter->sharedData = mySharedConverterData;
initializeAlgorithmicConverter (myUConverter);
return myUConverter;
if (mySharedConverterData->referenceCounter != ~0) {
umtx_lock (NULL);
--mySharedConverterData->referenceCounter;
umtx_unlock (NULL);
}
*err = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
return NULL;
}
/*Initializes the mutable lightweight portion of the object
*By copying data from UConverter->sharedData->defaultConverter
*/
void initializeDataConverter (UConverter * myUConverter)
{
/* initialize the converter */
uprv_memset(myUConverter, 0, sizeof(UConverter));
myUConverter->sharedData = mySharedConverterData;
myUConverter->mode = UCNV_SI;
myUConverter->UCharErrorBufferLength = 0;
myUConverter->charErrorBufferLength = 0;
myUConverter->subCharLen = myUConverter->sharedData->defaultConverterValues.subCharLen;
uprv_memcpy (myUConverter->subChar,
myUConverter->sharedData->defaultConverterValues.subChar,
myUConverter->subCharLen);
myUConverter->toUnicodeStatus = 0x00;
myUConverter->fromUnicodeStatus = 0x00;
myUConverter->sharedData->defaultConverterValues.toUnicodeStatus = 0x00;
myUConverter->fromCharErrorBehaviour = (UConverterToUCallback) UCNV_TO_U_CALLBACK_SUBSTITUTE;
myUConverter->fromUCharErrorBehaviour = (UConverterFromUCallback) UCNV_FROM_U_CALLBACK_SUBSTITUTE;
myUConverter->extraInfo = NULL;
myUConverter->toUnicodeStatus = myUConverter->sharedData->defaultConverterValues.toUnicodeStatus;
myUConverter->subCharLen = myUConverter->sharedData->defaultConverterValues.subCharLen;
uprv_memcpy (myUConverter->subChar, myUConverter->sharedData->defaultConverterValues.subChar, myUConverter->subCharLen);
return;
}
/* This function initializes algorithmic converters
* based on their type
*/
void
initializeAlgorithmicConverter (UConverter * myConverter)
{
myConverter->mode = UCNV_SI;
myConverter->fromCharErrorBehaviour = (UConverterToUCallback) UCNV_TO_U_CALLBACK_SUBSTITUTE;
myConverter->fromUCharErrorBehaviour = (UConverterFromUCallback) UCNV_FROM_U_CALLBACK_SUBSTITUTE;
myConverter->charErrorBufferLength = 0;
myConverter->UCharErrorBufferLength = 0;
myConverter->extraInfo = NULL;
myConverter->fromUnicodeStatus = 0;
myConverter->toUnicodeStatus = myConverter->sharedData->defaultConverterValues.toUnicodeStatus;
myConverter->subCharLen = myConverter->sharedData->defaultConverterValues.subCharLen;
uprv_memcpy (myConverter->subChar, myConverter->sharedData->defaultConverterValues.subChar, UCNV_MAX_SUBCHAR_LEN);
if(myConverter->sharedData->impl->open != NULL) {
UErrorCode errorCode = U_ZERO_ERROR;
/* ### pass in real parameters, and use the error code */
myConverter->sharedData->impl->open(myConverter, NULL, NULL, &errorCode);
if(myUConverter != NULL && myUConverter->sharedData->impl->open != NULL) {
myUConverter->sharedData->impl->open(myUConverter, realName, NULL, err);
if(U_FAILURE(*err)) {
ucnv_close(myUConverter);
return NULL;
}
}
return myUConverter;
}
UConverterSharedData* ucnv_data_unFlattenClone(UDataMemory *pData, UErrorCode *status)
{
const uint8_t *raw = (const uint8_t *)udata_getMemory(pData);
/* version 1.0 of .cnv files directly contains a UConverterSharedData_1_4 structure */
const UConverterSharedData_1_4 *source = (const UConverterSharedData_1_4 *) raw;
UConverterSharedData *data;
UConverterType type = source->conversionType;
@ -497,7 +419,12 @@ UConverterSharedData* ucnv_data_unFlattenClone(UDataMemory *pData, UErrorCode *s
data->platform = source->platform;
data->minBytesPerChar = source->minBytesPerChar;
data->maxBytesPerChar = source->maxBytesPerChar;
uprv_memcpy(&data->defaultConverterValues, &source->defaultConverterValues, sizeof(data->defaultConverterValues));
/* version 1.0 of .cnv files does not store valid toUnicodeStatus - do not copy the whole defaultConverterValues */
data->defaultConverterValues.subCharLen = source->defaultConverterValues.subCharLen;
uprv_memcpy(&data->defaultConverterValues.subChar,
&source->defaultConverterValues.subChar,
data->defaultConverterValues.subCharLen);
if(data->impl->load != NULL) {
data->impl->load(data, raw + source->structSize, status);

View file

@ -136,6 +136,10 @@ typedef UChar (*T_GetNextUCharFunction) (UConverter *,
const char *,
UErrorCode *);
typedef void (*UConverterGetStarters)(const UConverter* converter,
bool_t starters[256],
UErrorCode *pErrorCode);
bool_t CONVERSION_U_SUCCESS (UErrorCode err);
void flushInternalUnicodeBuffer (UConverter * _this,
@ -152,6 +156,22 @@ void flushInternalCharBuffer (UConverter * _this,
int32_t** offsets,
UErrorCode * err);
/**
* UConverterImpl contains all the data and functions for a converter type.
* Its function pointers work much like a C++ vtable.
* Many converter types need to define only a subset of the functions;
* when a function pointer is NULL, then a default action will be performed.
*
* Every converter type must implement toUnicode, fromUnicode, and getNextUChar,
* otherwise the converter may crash.
* Every converter type that has variable-length codepage sequences should
* also implement toUnicodeWithOffsets and fromUnicodeWithOffsets for
* correct offset handling.
* All other functions may or may not be implemented - it depends only on
* whether the converter type needs them.
*
* When open() fails, then close() will be called, if present.
*/
struct UConverterImpl {
UConverterType type;
@ -167,9 +187,11 @@ struct UConverterImpl {
T_FromUnicodeFunction fromUnicode;
T_FromUnicodeFunction fromUnicodeWithOffsets;
T_GetNextUCharFunction getNextUChar;
UConverterGetStarters getStarters;
};
extern UConverterSharedData
extern const UConverterSharedData
_SBCSData, _DBCSData, _MBCSData, _Latin1Data,
_UTF8Data, _UTF16BEData, _UTF16LEData, _EBCDICStatefulData,
_ISO2022Data;

View file

@ -693,7 +693,7 @@ UChar T_UConverter_getNextUChar_UTF8(UConverter* converter,
}
}
static UConverterImpl _UTF8Impl={
static const UConverterImpl _UTF8Impl={
UCNV_UTF8,
NULL,
@ -707,10 +707,12 @@ static UConverterImpl _UTF8Impl={
T_UConverter_toUnicode_UTF8_OFFSETS_LOGIC,
T_UConverter_fromUnicode_UTF8,
T_UConverter_fromUnicode_UTF8_OFFSETS_LOGIC,
T_UConverter_getNextUChar_UTF8
T_UConverter_getNextUChar_UTF8,
NULL
};
extern UConverterSharedData _UTF8Data={
extern const UConverterSharedData _UTF8Data={
sizeof(UConverterSharedData), ~0,
NULL, NULL, &_UTF8Impl, "UTF8",
1208, UCNV_IBM, UCNV_UTF8, 1, 4,
@ -865,7 +867,7 @@ UChar T_UConverter_getNextUChar_UTF16_BE(UConverter* converter,
return myUChar;
}
static UConverterImpl _UTF16BEImpl={
static const UConverterImpl _UTF16BEImpl={
UCNV_UTF16_BigEndian,
NULL,
@ -879,10 +881,12 @@ static UConverterImpl _UTF16BEImpl={
NULL,
T_UConverter_fromUnicode_UTF16_BE,
NULL,
T_UConverter_getNextUChar_UTF16_BE
T_UConverter_getNextUChar_UTF16_BE,
NULL
};
extern UConverterSharedData _UTF16BEData={
extern const UConverterSharedData _UTF16BEData={
sizeof(UConverterSharedData), ~0,
NULL, NULL, &_UTF16BEImpl, "UTF16_BigEndian",
1200, UCNV_IBM, UCNV_UTF16_BigEndian, 2, 2,
@ -1041,7 +1045,7 @@ UChar T_UConverter_getNextUChar_UTF16_LE(UConverter* converter,
return myUChar;
}
static UConverterImpl _UTF16LEImpl={
static const UConverterImpl _UTF16LEImpl={
UCNV_UTF16_LittleEndian,
NULL,
@ -1055,10 +1059,12 @@ static UConverterImpl _UTF16LEImpl={
NULL,
T_UConverter_fromUnicode_UTF16_LE,
NULL,
T_UConverter_getNextUChar_UTF16_LE
T_UConverter_getNextUChar_UTF16_LE,
NULL
};
extern UConverterSharedData _UTF16LEData={
extern const UConverterSharedData _UTF16LEData={
sizeof(UConverterSharedData), ~0,
NULL, NULL, &_UTF16LEImpl, "UTF16_LittleEndian",
1200, UCNV_IBM, UCNV_UTF16_LittleEndian, 2, 2,

View file

@ -141,7 +141,7 @@ UChar T_UConverter_getNextUChar_LATIN_1(UConverter* converter,
return (UChar)*((*source)++);
}
static UConverterImpl _Latin1Impl={
static const UConverterImpl _Latin1Impl={
UCNV_LATIN_1,
NULL,
@ -155,10 +155,12 @@ static UConverterImpl _Latin1Impl={
NULL,
T_UConverter_fromUnicode_LATIN_1,
NULL,
T_UConverter_getNextUChar_LATIN_1
T_UConverter_getNextUChar_LATIN_1,
NULL
};
extern UConverterSharedData _Latin1Data={
extern const UConverterSharedData _Latin1Data={
sizeof(UConverterSharedData), ~0,
NULL, NULL, &_Latin1Impl, "LATIN_1",
819, UCNV_IBM, UCNV_LATIN_1, 1, 1,

View file

@ -556,7 +556,13 @@ UChar T_UConverter_getNextUChar_MBCS(UConverter* converter,
}
}
static UConverterImpl _MBCSImpl={
void
_MBCSGetStarters(const UConverter* converter, bool_t starters[256], UErrorCode *pErrorCode) {
/* fills in the starters boolean array */
uprv_memcpy(starters, converter->sharedData->table->mbcs.starters, 256*sizeof(bool_t));
}
static const UConverterImpl _MBCSImpl={
UCNV_MBCS,
_MBCSLoad,
@ -570,10 +576,12 @@ static UConverterImpl _MBCSImpl={
T_UConverter_toUnicode_MBCS_OFFSETS_LOGIC,
T_UConverter_fromUnicode_MBCS,
T_UConverter_fromUnicode_MBCS_OFFSETS_LOGIC,
T_UConverter_getNextUChar_MBCS
T_UConverter_getNextUChar_MBCS,
_MBCSGetStarters
};
extern UConverterSharedData _MBCSData={
extern const UConverterSharedData _MBCSData={
sizeof(UConverterSharedData), 1,
NULL, NULL, &_MBCSImpl, "MBCS",
0, UCNV_IBM, UCNV_MBCS, 1, 1,

View file

@ -222,7 +222,7 @@ UChar T_UConverter_getNextUChar_SBCS(UConverter* converter,
}
}
static UConverterImpl _SBCSImpl={
static const UConverterImpl _SBCSImpl={
UCNV_SBCS,
_SBCSLoad,
@ -236,10 +236,12 @@ static UConverterImpl _SBCSImpl={
NULL,
T_UConverter_fromUnicode_SBCS,
NULL,
T_UConverter_getNextUChar_SBCS
T_UConverter_getNextUChar_SBCS,
NULL
};
extern UConverterSharedData _SBCSData={
extern const UConverterSharedData _SBCSData={
sizeof(UConverterSharedData), 1,
NULL, NULL, &_SBCSImpl, "SBCS",
0, UCNV_IBM, UCNV_SBCS, 1, 1,
@ -506,7 +508,7 @@ UChar T_UConverter_getNextUChar_DBCS(UConverter* converter,
}
}
static UConverterImpl _DBCSImpl={
static const UConverterImpl _DBCSImpl={
UCNV_DBCS,
_DBCSLoad,
@ -520,10 +522,12 @@ static UConverterImpl _DBCSImpl={
NULL,
T_UConverter_fromUnicode_DBCS,
NULL,
T_UConverter_getNextUChar_DBCS
T_UConverter_getNextUChar_DBCS,
NULL
};
extern UConverterSharedData _DBCSData={
extern const UConverterSharedData _DBCSData={
sizeof(UConverterSharedData), 1,
NULL, NULL, &_DBCSImpl, "DBCS",
0, UCNV_IBM, UCNV_DBCS, 2, 2,