mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-21 04:29:31 +00:00
ICU-4163 ucol_cloneBinary & ucol_openBinary APIs
X-SVN-Rev: 16637
This commit is contained in:
parent
5a5375439d
commit
6f97dd1568
5 changed files with 226 additions and 10 deletions
|
@ -576,6 +576,8 @@ typedef enum UErrorCode {
|
|||
U_ENUM_OUT_OF_SYNC_ERROR = 25, /**< UEnumeration out of sync with underlying collection */
|
||||
U_INVARIANT_CONVERSION_ERROR = 26, /**< Unable to convert a UChar* string to char* with the invariant converter. */
|
||||
U_INVALID_STATE_ERROR = 27, /**< Requested operation can not be completed with ICU in its current state */
|
||||
U_COLLATOR_VERSION_MISMATCH = 28, /**< Collator version is not compatible with the base version */
|
||||
U_USELESS_COLLATOR_ERROR = 29, /**< Collator is options only and no base is specified */
|
||||
|
||||
U_STANDARD_ERROR_LIMIT, /**< This must always be the last value to indicate the limit for standard errors */
|
||||
/*
|
||||
|
|
|
@ -98,7 +98,9 @@ _uErrorName[U_STANDARD_ERROR_LIMIT]={
|
|||
"U_TOO_MANY_ALIASES_ERROR",
|
||||
"U_ENUM_OUT_OF_SYNC_ERROR",
|
||||
"U_INVARIANT_CONVERSION_ERROR",
|
||||
"U_INVALID_STATE_ERROR"
|
||||
"U_INVALID_STATE_ERROR",
|
||||
"U_COLLATOR_VERSION_MISMATCH",
|
||||
"U_USELESS_COLLATOR_ERROR"
|
||||
};
|
||||
static const char * const
|
||||
_uFmtErrorName[U_FMT_PARSE_ERROR_LIMIT - U_FMT_PARSE_ERROR_START] = {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2004, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
|
@ -491,6 +491,7 @@ clean:
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
ucol_setReqValidLocales(UCollator *coll, char *requestedLocaleToAdopt, char *validLocaleToAdopt)
|
||||
{
|
||||
|
@ -1730,7 +1731,7 @@ inline uint32_t ucol_IGetNextCE(const UCollator *coll, collIterate *collationSou
|
|||
if(order > UCOL_NOT_FOUND) { /* if a CE is special */
|
||||
order = ucol_prv_getSpecialCE(coll, ch, order, collationSource, status); /* and try to get the special CE */
|
||||
}
|
||||
if(order == UCOL_NOT_FOUND) { /* We couldn't find a good CE in the tailoring */
|
||||
if(order == UCOL_NOT_FOUND && coll->UCA) { /* We couldn't find a good CE in the tailoring */
|
||||
/* if we got here, the codepoint MUST be over 0xFF - so we look directly in the trie */
|
||||
order = UTRIE_GET32_FROM_LEAD(coll->UCA->mapping, ch);
|
||||
|
||||
|
@ -2140,10 +2141,12 @@ inline uint32_t ucol_IGetPrevCE(const UCollator *coll, collIterate *data,
|
|||
}
|
||||
else {
|
||||
/*result = ucmpe32_get(UCA->mapping, ch);*/
|
||||
if(coll->UCA) {
|
||||
result = UTRIE_GET32_FROM_LEAD(coll->UCA->mapping, ch);
|
||||
}
|
||||
}
|
||||
|
||||
if (result > UCOL_NOT_FOUND) {
|
||||
if (result > UCOL_NOT_FOUND && coll->UCA) {
|
||||
result = ucol_prv_getSpecialPrevCE(coll->UCA, ch, result, data, status);
|
||||
}
|
||||
}
|
||||
|
@ -6999,7 +7002,7 @@ ucol_setUpLatinOne(UCollator *coll, UErrorCode *status) {
|
|||
CE = coll->latinOneMapping[ch];
|
||||
} else {
|
||||
CE = UTRIE_GET32_FROM_LEAD(coll->mapping, ch);
|
||||
if(CE == UCOL_NOT_FOUND) {
|
||||
if(CE == UCOL_NOT_FOUND && coll->UCA) {
|
||||
CE = UTRIE_GET32_FROM_LEAD(coll->UCA->mapping, ch);
|
||||
}
|
||||
}
|
||||
|
@ -7634,7 +7637,11 @@ ucol_getVersion(const UCollator* coll,
|
|||
versionInfo[0] = (uint8_t)(cmbVersion>>8);
|
||||
versionInfo[1] = (uint8_t)cmbVersion;
|
||||
versionInfo[2] = coll->image->version[1];
|
||||
versionInfo[3] = coll->UCA->image->UCAVersion[0];
|
||||
if(coll->UCA) {
|
||||
versionInfo[3] = coll->UCA->image->UCAVersion[0];
|
||||
} else {
|
||||
versionInfo[3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -7648,7 +7655,7 @@ ucol_isTailored(const UCollator *coll, const UChar u, UErrorCode *status) {
|
|||
return FALSE;
|
||||
} else if(u < 0x100) { /* latin-1 */
|
||||
CE = coll->latinOneMapping[u];
|
||||
if(CE == coll->UCA->latinOneMapping[u]) {
|
||||
if(coll->UCA && CE == coll->UCA->latinOneMapping[u]) {
|
||||
return FALSE;
|
||||
}
|
||||
} else { /* regular */
|
||||
|
@ -9116,7 +9123,7 @@ ucol_getTailoredSet(const UCollator *coll, UErrorCode *status)
|
|||
if(status == NULL || U_FAILURE(*status)) {
|
||||
return NULL;
|
||||
}
|
||||
if(coll == NULL) {
|
||||
if(coll == NULL || coll->UCA == NULL) {
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
UParseError parseError;
|
||||
|
@ -9268,10 +9275,173 @@ returnResult:
|
|||
|
||||
U_CAPI void U_EXPORT2
|
||||
ucol_getUCAVersion(const UCollator* coll, UVersionInfo info) {
|
||||
if(coll) {
|
||||
if(coll && coll->UCA) {
|
||||
uprv_memcpy(info, coll->UCA->image->UCAVersion, sizeof(UVersionInfo));
|
||||
}
|
||||
}
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
ucol_cloneBinary(const UCollator *coll,
|
||||
uint8_t *buffer, int32_t capacity,
|
||||
UErrorCode *status)
|
||||
{
|
||||
int32_t length = 0;
|
||||
if(U_FAILURE(*status)) {
|
||||
return NULL;
|
||||
}
|
||||
if(coll->hasRealData == TRUE) {
|
||||
length = coll->image->size;
|
||||
if(length <= capacity) {
|
||||
uprv_memcpy(buffer, coll->image, length);
|
||||
}
|
||||
} else {
|
||||
length = (int32_t)(paddedsize(sizeof(UCATableHeader))+paddedsize(sizeof(UColOptionSet)));
|
||||
if(length <= capacity) {
|
||||
/* build the UCATableHeader with minimal entries */
|
||||
/* do not copy the header from the UCA file because its values are wrong! */
|
||||
/* uprv_memcpy(result, UCA->image, sizeof(UCATableHeader)); */
|
||||
|
||||
/* reset everything */
|
||||
uprv_memset(buffer, 0, length);
|
||||
|
||||
/* set the tailoring-specific values */
|
||||
UCATableHeader *myData = (UCATableHeader *)buffer;
|
||||
myData->size = length;
|
||||
|
||||
/* offset for the options, the only part of the data that is present after the header */
|
||||
myData->options = sizeof(UCATableHeader);
|
||||
|
||||
/* need to always set the expansion value for an upper bound of the options */
|
||||
myData->expansion = myData->options + sizeof(UColOptionSet);
|
||||
|
||||
myData->magic = UCOL_HEADER_MAGIC;
|
||||
myData->isBigEndian = U_IS_BIG_ENDIAN;
|
||||
myData->charSetFamily = U_CHARSET_FAMILY;
|
||||
|
||||
/* copy UCA's version; genrb will override all but the builder version with tailoring data */
|
||||
uprv_memcpy(myData->version, coll->image->version, sizeof(UVersionInfo));
|
||||
|
||||
uprv_memcpy(myData->UCAVersion, coll->image->UCAVersion, sizeof(UVersionInfo));
|
||||
uprv_memcpy(myData->UCDVersion, coll->image->UCDVersion, sizeof(UVersionInfo));
|
||||
uprv_memcpy(myData->formatVersion, coll->image->formatVersion, sizeof(UVersionInfo));
|
||||
myData->jamoSpecial = coll->image->jamoSpecial;
|
||||
|
||||
/* copy the collator options */
|
||||
uprv_memcpy(buffer+paddedsize(sizeof(UCATableHeader)), coll->options, sizeof(UColOptionSet));
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
U_CAPI UCollator* U_EXPORT2
|
||||
ucol_openBinary(const uint8_t *bin, int32_t length,
|
||||
const UCollator *base,
|
||||
UErrorCode *status)
|
||||
{
|
||||
UCollator *result = NULL;
|
||||
if(U_FAILURE(*status)){
|
||||
return NULL;
|
||||
}
|
||||
if(base == NULL) {
|
||||
// we don't support null base yet
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
UCATableHeader *colData = (UCATableHeader *)bin;
|
||||
// do we want version check here? We're trying to figure out whether collators are compatible
|
||||
if(uprv_memcmp(colData->UCAVersion, base->image->UCAVersion, sizeof(UVersionInfo)) != 0 ||
|
||||
uprv_memcmp(colData->UCDVersion, base->image->UCDVersion, sizeof(UVersionInfo)) != 0 ||
|
||||
colData->version[0] != UCOL_BUILDER_VERSION) {
|
||||
*status = U_COLLATOR_VERSION_MISMATCH;
|
||||
return NULL;
|
||||
} else {
|
||||
if((uint32_t)length > (paddedsize(sizeof(UCATableHeader)) + paddedsize(sizeof(UColOptionSet)))) {
|
||||
result = ucol_initCollator((const UCATableHeader *)bin, result, base, status);
|
||||
if(U_FAILURE(*status)){
|
||||
return NULL;
|
||||
}
|
||||
result->hasRealData = TRUE;
|
||||
} else {
|
||||
if(base) {
|
||||
result = ucol_initCollator(base->image, result, base, status);
|
||||
ucol_setOptionsFromHeader(result, (UColOptionSet *)(bin+((const UCATableHeader *)bin)->options), status);
|
||||
if(U_FAILURE(*status)){
|
||||
return NULL;
|
||||
}
|
||||
result->hasRealData = FALSE;
|
||||
} else {
|
||||
*status = U_USELESS_COLLATOR_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
result->freeImageOnClose = FALSE;
|
||||
}
|
||||
result->validLocale = NULL;
|
||||
result->requestedLocale = NULL;
|
||||
result->rules = NULL;
|
||||
result->rulesLength = 0;
|
||||
result->freeRulesOnClose = FALSE;
|
||||
result->rb = NULL;
|
||||
result->elements = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
U_CAPI UCollator* U_EXPORT2
|
||||
ucol_openFromImage( const uint8_t *image,
|
||||
UCollator *coll,
|
||||
UErrorCode *status)
|
||||
{
|
||||
return NULL;
|
||||
#if 0
|
||||
if(status == NULL || U_FAILURE(*status)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(image == NULL) {
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ucol_initUCA(status);
|
||||
|
||||
if(U_FAILURE(*status)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t len = ((UCATableHeader *)image)->size;
|
||||
UCATableHeader *table = (UCATableHeader *) uprv_malloc(len);
|
||||
/* test for NULL */
|
||||
if (table == NULL) {
|
||||
*status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
uprv_memcpy(table, image, len);
|
||||
|
||||
UCollator *result = ucol_initCollator(table,0,status);
|
||||
|
||||
if (result != NULL) {
|
||||
result->freeImageOnClose = TRUE;
|
||||
result->rules = NULL;
|
||||
result->rulesLength = 0;
|
||||
result->freeRulesOnClose = FALSE;
|
||||
result->rb = NULL;
|
||||
result->elements = NULL;
|
||||
result->validLocale = NULL;
|
||||
result->requestedLocale = NULL;
|
||||
if(U_SUCCESS(*status)) {
|
||||
result->dataInfo.dataVersion[0] = UCOL_BUILDER_VERSION;
|
||||
result->hasRealData = len > paddedsize(sizeof(UCATableHeader)) + paddedsize(sizeof(UColOptionSet));
|
||||
} else {
|
||||
ucol_close(result);
|
||||
result = NULL;
|
||||
}
|
||||
} else {
|
||||
uprv_free(table);
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_COLLATION */
|
||||
|
||||
|
|
|
@ -1138,6 +1138,45 @@ ucol_getUnsafeSet( const UCollator *coll,
|
|||
USet *unsafe,
|
||||
UErrorCode *status);
|
||||
|
||||
/** Creates a binary image of a collator. This binary image can be stored and
|
||||
* later used to instantiate a collator using ucol_openBinary.
|
||||
* This API supports preflighting.
|
||||
* @param coll Collator
|
||||
* @param buffer a fill-in buffer to receive the binary image
|
||||
* @param capacity capacity of the destination buffer
|
||||
* @param status for catching errors
|
||||
* @return size of the image
|
||||
* @see ucol_openBinary
|
||||
* @draft ICU 3.2
|
||||
*/
|
||||
U_DRAFT int32_t U_EXPORT2
|
||||
ucol_cloneBinary(const UCollator *coll,
|
||||
uint8_t *buffer, int32_t capacity,
|
||||
UErrorCode *status);
|
||||
|
||||
/** Opens a collator from a collator binary image created using
|
||||
* ucol_cloneBinary. Binary image used in instantiation of the
|
||||
* collator remains owned by the user and should stay around for
|
||||
* the lifetime of the collator. The API also takes a base collator
|
||||
* which usualy should be UCA.
|
||||
* @param bin binary image owned by the user and required through the
|
||||
* lifetime of the collator
|
||||
* @param length size of the image. If negative, the API will try to
|
||||
* figure out the length of the image
|
||||
* @param base fallback collator, usually UCA. Base is required to be
|
||||
* present through the lifetime of the collator. Currently
|
||||
* it cannot be NULL.
|
||||
* @param status for catching errors
|
||||
* @return newly created collator
|
||||
* @see ucol_cloneBinary
|
||||
* @draft ICU 3.2
|
||||
*/
|
||||
U_DRAFT UCollator* U_EXPORT2
|
||||
ucol_openBinary(const uint8_t *bin, int32_t length,
|
||||
const UCollator *base,
|
||||
UErrorCode *status);
|
||||
|
||||
|
||||
#endif /* #if !UCONFIG_NO_COLLATION */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -691,7 +691,10 @@ addCollation(struct SResource *result, uint32_t startline, UErrorCode *status)
|
|||
|
||||
if (U_SUCCESS(intStatus) && coll != NULL)
|
||||
{
|
||||
data = ucol_cloneRuleData(coll, &len, &intStatus);
|
||||
len = ucol_cloneBinary(coll, NULL, 0, &intStatus);
|
||||
data = (uint8_t *)uprv_malloc(len);
|
||||
len = ucol_cloneBinary(coll, data, len, &intStatus);
|
||||
//data = ucol_cloneRuleData(coll, &len, &intStatus);
|
||||
|
||||
/* tailoring rules version */
|
||||
/* This is wrong! */
|
||||
|
|
Loading…
Add table
Reference in a new issue