ICU-388 and jb 853: ucnv_safeClone - the guts of the implementation

X-SVN-Rev: 3657
This commit is contained in:
Jim Snyder Grant 2001-02-16 22:22:40 +00:00
parent 2a17db6667
commit 5479dd7c73
6 changed files with 207 additions and 8 deletions

View file

@ -135,6 +135,63 @@ UConverter* ucnv_openCCSID (int32_t codepage,
return createConverter (myName, err);
}
/* Creating a temporary stack-based object that can be used in one thread,
and created from a converter that is shared across threads.
*/
UConverter *ucnv_safeClone(const UConverter* cnv, void *stackBuffer, int32_t *pBufferSize, UErrorCode *status)
{
UConverter * localConverter;
int32_t bufferSizeNeeded;
if (status == NULL || U_FAILURE(*status)){
return 0;
}
if (!pBufferSize || !cnv){
*status = U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
if (cnv->sharedData->impl->safeClone != NULL) {
/* call the custom safeClone function for sizing */
bufferSizeNeeded = 0;
cnv->sharedData->impl->safeClone(cnv, stackBuffer, &bufferSizeNeeded, status);
}
else
{
bufferSizeNeeded = sizeof(UConverter);
}
if (*pBufferSize == 0){ /* 'preflighting' request - set needed size into *pBufferSize */
*pBufferSize = bufferSizeNeeded;
return 0;
}
if (*pBufferSize < bufferSizeNeeded || stackBuffer == NULL)
{
/* allocate one here...*/
localConverter = createConverter (ucnv_getName (cnv, status), status);
if (U_SUCCESS(*status))
{
*status = U_SAFECLONE_ALLOCATED_ERROR;
}
} else {
if (cnv->sharedData->impl->safeClone != NULL) {
/* call the custom safeClone function */
localConverter = cnv->sharedData->impl->safeClone(cnv, stackBuffer, pBufferSize, status);
}
else
{
localConverter = (UConverter *)stackBuffer;
memcpy(localConverter, cnv, sizeof(UConverter));
localConverter->isCopyLocal = TRUE;
}
}
return localConverter;
}
/*Decreases the reference counter in the shared immutable section of the object
*and frees the mutable part*/
@ -163,7 +220,7 @@ void ucnv_close (UConverter * converter)
};
UErrorCode errorCode;
if (converter == NULL)
if (converter == NULL || converter->isCopyLocal)
{
return;
}

View file

@ -313,6 +313,7 @@ static void _ISO2022Close(UConverter *converter);
static void _ISO2022Reset(UConverter *converter, UConverterResetChoice choice);
static const char* _ISO2022getName(const UConverter* cnv);
U_CFUNC void _ISO_2022_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorCode *err) ;
U_CFUNC UConverter * _ISO_2022_SafeClone(const UConverter *cnv, void *stackBuffer, int32_t *pBufferSize, UErrorCode *status);
/************ protos of functions for setting the initial state *********************/
static void setInitialStateToUnicodeJPCN(UConverter* converter,UConverterDataISO2022 *myConverterData);
static void setInitialStateFromUnicodeJPCN(UConverter* converter,UConverterDataISO2022 *myConverterData);
@ -337,7 +338,9 @@ static const UConverterImpl _ISO2022Impl={
T_UConverter_getNextUChar_ISO_2022,
NULL,
_ISO2022getName
_ISO2022getName,
_ISO_2022_WriteSub,
_ISO_2022_SafeClone
};
const UConverterStaticData _ISO2022StaticData={
@ -388,7 +391,8 @@ static const UConverterImpl _ISO2022JPImpl={
NULL,
_ISO2022getName,
_ISO_2022_WriteSub
_ISO_2022_WriteSub,
_ISO_2022_SafeClone
};
const UConverterStaticData _ISO2022JPStaticData={
sizeof(UConverterStaticData),
@ -436,7 +440,8 @@ static const UConverterImpl _ISO2022KRImpl={
NULL,
_ISO2022getName,
_ISO_2022_WriteSub
_ISO_2022_WriteSub,
_ISO_2022_SafeClone
};
const UConverterStaticData _ISO2022KRStaticData={
sizeof(UConverterStaticData),
@ -484,8 +489,8 @@ static const UConverterImpl _ISO2022CNImpl={
NULL,
_ISO2022getName,
_ISO_2022_WriteSub
_ISO_2022_WriteSub,
_ISO_2022_SafeClone
};
const UConverterStaticData _ISO2022CNStaticData={
sizeof(UConverterStaticData),
@ -3098,3 +3103,40 @@ _ISO_2022_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorC
buffer, (int32_t)(p - buffer),
offsetIndex, err);
}
/* structure for SafeClone calculations */
struct cloneStruct
{
UConverter cnv;
UConverterDataISO2022 mydata;
};
U_CFUNC UConverter *
_ISO_2022_SafeClone(
const UConverter *cnv,
void *stackBuffer,
int32_t *pBufferSize,
UErrorCode *status)
{
struct cloneStruct * localClone;
int32_t bufferSizeNeeded = sizeof(struct cloneStruct);
if (U_FAILURE(*status)){
return 0;
}
if (*pBufferSize == 0){ /* 'preflighting' request - set needed size into *pBufferSize */
*pBufferSize = bufferSizeNeeded;
return 0;
}
localClone = (struct cloneStruct *)stackBuffer;
memcpy(&localClone->cnv, cnv, sizeof(UConverter));
localClone->cnv.isCopyLocal = TRUE;
memcpy(&localClone->mydata, cnv->extraInfo, sizeof(UConverterDataISO2022));
localClone->cnv.extraInfo = &localClone->mydata;
return &localClone->cnv;
}

View file

@ -153,6 +153,7 @@ struct UConverter {
void *fromUContext;
void *toUContext;
UBool isCopyLocal; /* TRUE if created by safeClone with no allocation or ref count */
UConverterSharedData *sharedData; /* Pointer to the shared immutable part of the converter object */
/*

View file

@ -83,6 +83,16 @@ typedef const char * (*UConverterGetName) (const UConverter *cnv);
*/
typedef void (*UConverterWriteSub) (UConverterFromUnicodeArgs *pArgs, int32_t offsetIndex, UErrorCode *pErrorCode);
/**
* For converter-specific safeClone processing
* If this function is not set, then ucnv_safeClone assumes that the converter has no private data that changes
* after the converter is done opening.
*/
typedef UConverter * (*UConverterSafeClone) ( const UConverter *cnv,
void *stackBuffer,
int32_t *pBufferSize,
UErrorCode *status);
UBool CONVERSION_U_SUCCESS (UErrorCode err);
void flushInternalUnicodeBuffer (UConverter * _this,
@ -134,6 +144,7 @@ struct UConverterImpl {
UConverterGetStarters getStarters;
UConverterGetName getName;
UConverterWriteSub writeSub;
UConverterSafeClone safeClone;
};
extern const UConverterSharedData

View file

@ -56,6 +56,7 @@ static void _HZClose(UConverter *converter);
static void _HZReset(UConverter *converter, UConverterResetChoice choice);
U_CFUNC void _HZ_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorCode *err);
U_CFUNC UConverter * _HZ_SafeClone(const UConverter *cnv, void *stackBuffer, int32_t *pBufferSize, UErrorCode *status);
U_CFUNC void UConverter_toUnicode_HZ_OFFSETS_LOGIC (UConverterToUnicodeArgs *args,
UErrorCode *err);
@ -82,7 +83,8 @@ static UConverterImpl _HZImpl={
NULL,
NULL,
_HZ_WriteSub
_HZ_WriteSub,
_HZ_SafeClone
};
const UConverterStaticData _HZStaticData={
@ -643,3 +645,42 @@ _HZ_WriteSub(UConverterFromUnicodeArgs *args, int32_t offsetIndex, UErrorCode *e
buffer, (int32_t)(p - buffer),
offsetIndex, err);
}
/* structure for SafeClone calculations */
struct cloneStruct
{
UConverter cnv;
UConverterDataHZ mydata;
};
U_CFUNC UConverter *
_HZ_SafeClone(
const UConverter *cnv,
void *stackBuffer,
int32_t *pBufferSize,
UErrorCode *status)
{
struct cloneStruct * localClone;
int32_t bufferSizeNeeded = sizeof(struct cloneStruct);
if (U_FAILURE(*status)){
return 0;
}
if (*pBufferSize == 0){ /* 'preflighting' request - set needed size into *pBufferSize */
*pBufferSize = bufferSizeNeeded;
return 0;
}
localClone = (struct cloneStruct *)stackBuffer;
memcpy(&localClone->cnv, cnv, sizeof(UConverter));
localClone->cnv.isCopyLocal = TRUE;
memcpy(&localClone->mydata, cnv->extraInfo, sizeof(UConverterDataHZ));
localClone->cnv.extraInfo = &localClone->mydata;
return &localClone->cnv;
}

View file

@ -55,6 +55,12 @@ U_CFUNC void
_SCSUWriteSub(UConverterFromUnicodeArgs *pArgs,
int32_t offsetIndex,
UErrorCode *pErrorCode);
U_CFUNC UConverter *
_SCSUSafeClone(const UConverter *cnv,
void *stackBuffer,
int32_t *pBufferSize,
UErrorCode *status);
/* SCSU definitions --------------------------------------------------------- */
@ -1361,6 +1367,46 @@ _SCSUWriteSub(UConverterFromUnicodeArgs *pArgs,
}
}
/* structure for SafeClone calculations */
struct cloneStruct
{
UConverter cnv;
SCSUData mydata;
};
U_CFUNC UConverter *
_SCSUSafeClone(
const UConverter *cnv,
void *stackBuffer,
int32_t *pBufferSize,
UErrorCode *status)
{
struct cloneStruct * localClone;
int32_t bufferSizeNeeded = sizeof(struct cloneStruct);
if (U_FAILURE(*status)){
return 0;
}
if (*pBufferSize == 0){ /* 'preflighting' request - set needed size into *pBufferSize */
*pBufferSize = bufferSizeNeeded;
return 0;
}
localClone = (struct cloneStruct *)stackBuffer;
memcpy(&localClone->cnv, cnv, sizeof(UConverter));
localClone->cnv.isCopyLocal = TRUE;
memcpy(&localClone->mydata, cnv->extraInfo, sizeof(SCSUData));
localClone->cnv.extraInfo = &localClone->mydata;
return &localClone->cnv;
}
static const UConverterImpl _SCSUImpl={
UCNV_SCSU,
@ -1379,7 +1425,8 @@ static const UConverterImpl _SCSUImpl={
NULL,
_SCSUGetName,
_SCSUWriteSub
_SCSUWriteSub,
_SCSUSafeClone
};
static const UConverterStaticData _SCSUStaticData={