diff options
Diffstat (limited to 'Build/source/libs/icu/icu-xetex/common/propname.cpp')
-rw-r--r-- | Build/source/libs/icu/icu-xetex/common/propname.cpp | 758 |
1 files changed, 758 insertions, 0 deletions
diff --git a/Build/source/libs/icu/icu-xetex/common/propname.cpp b/Build/source/libs/icu/icu-xetex/common/propname.cpp new file mode 100644 index 00000000000..55e354044f3 --- /dev/null +++ b/Build/source/libs/icu/icu-xetex/common/propname.cpp @@ -0,0 +1,758 @@ +/* +********************************************************************** +* Copyright (c) 2002-2006, International Business Machines +* Corporation and others. All Rights Reserved. +********************************************************************** +* Author: Alan Liu +* Created: October 30 2002 +* Since: ICU 2.4 +********************************************************************** +*/ +#include "propname.h" +#include "unicode/uchar.h" +#include "unicode/udata.h" +#include "umutex.h" +#include "cmemory.h" +#include "cstring.h" +#include "ucln_cmn.h" +#include "uarrsort.h" + +U_CDECL_BEGIN + +/** + * Get the next non-ignorable ASCII character from a property name + * and lowercases it. + * @return ((advance count for the name)<<8)|character + */ +static inline int32_t +getASCIIPropertyNameChar(const char *name) { + int32_t i; + char c; + + /* Ignore delimiters '-', '_', and ASCII White_Space */ + for(i=0; + (c=name[i++])==0x2d || c==0x5f || + c==0x20 || (0x09<=c && c<=0x0d); + ) {} + + if(c!=0) { + return (i<<8)|(uint8_t)uprv_asciitolower((char)c); + } else { + return i<<8; + } +} + +/** + * Get the next non-ignorable EBCDIC character from a property name + * and lowercases it. + * @return ((advance count for the name)<<8)|character + */ +static inline int32_t +getEBCDICPropertyNameChar(const char *name) { + int32_t i; + char c; + + /* Ignore delimiters '-', '_', and EBCDIC White_Space */ + for(i=0; + (c=name[i++])==0x60 || c==0x6d || + c==0x40 || c==0x05 || c==0x15 || c==0x25 || c==0x0b || c==0x0c || c==0x0d; + ) {} + + if(c!=0) { + return (i<<8)|(uint8_t)uprv_ebcdictolower((char)c); + } else { + return i<<8; + } +} + +/** + * Unicode property names and property value names are compared "loosely". + * + * UCD.html 4.0.1 says: + * For all property names, property value names, and for property values for + * Enumerated, Binary, or Catalog properties, use the following + * loose matching rule: + * + * LM3. Ignore case, whitespace, underscore ('_'), and hyphens. + * + * This function does just that, for (char *) name strings. + * It is almost identical to ucnv_compareNames() but also ignores + * C0 White_Space characters (U+0009..U+000d, and U+0085 on EBCDIC). + * + * @internal + */ + +U_CAPI int32_t U_EXPORT2 +uprv_compareASCIIPropertyNames(const char *name1, const char *name2) { + int32_t rc, r1, r2; + + for(;;) { + r1=getASCIIPropertyNameChar(name1); + r2=getASCIIPropertyNameChar(name2); + + /* If we reach the ends of both strings then they match */ + if(((r1|r2)&0xff)==0) { + return 0; + } + + /* Compare the lowercased characters */ + if(r1!=r2) { + rc=(r1&0xff)-(r2&0xff); + if(rc!=0) { + return rc; + } + } + + name1+=r1>>8; + name2+=r2>>8; + } +} + +U_CAPI int32_t U_EXPORT2 +uprv_compareEBCDICPropertyNames(const char *name1, const char *name2) { + int32_t rc, r1, r2; + + for(;;) { + r1=getEBCDICPropertyNameChar(name1); + r2=getEBCDICPropertyNameChar(name2); + + /* If we reach the ends of both strings then they match */ + if(((r1|r2)&0xff)==0) { + return 0; + } + + /* Compare the lowercased characters */ + if(r1!=r2) { + rc=(r1&0xff)-(r2&0xff); + if(rc!=0) { + return rc; + } + } + + name1+=r1>>8; + name2+=r2>>8; + } +} + +U_CDECL_END + +U_NAMESPACE_BEGIN + +//---------------------------------------------------------------------- +// PropertyAliases implementation + +const char* +PropertyAliases::chooseNameInGroup(Offset offset, + UPropertyNameChoice choice) const { + int32_t c = choice; + if (!offset || c < 0) { + return NULL; + } + const Offset* p = (const Offset*) getPointer(offset); + while (c-- > 0) { + if (*p++ < 0) return NULL; + } + Offset a = *p; + if (a < 0) a = -a; + return (const char*) getPointerNull(a); +} + +const ValueMap* +PropertyAliases::getValueMap(EnumValue prop) const { + NonContiguousEnumToOffset* e2o = (NonContiguousEnumToOffset*) getPointer(enumToValue_offset); + Offset a = e2o->getOffset(prop); + return (const ValueMap*) (a ? getPointerNull(a) : NULL); +} + +inline const char* +PropertyAliases::getPropertyName(EnumValue prop, + UPropertyNameChoice choice) const { + NonContiguousEnumToOffset* e2n = (NonContiguousEnumToOffset*) getPointer(enumToName_offset); + return chooseNameInGroup(e2n->getOffset(prop), choice); +} + +inline EnumValue +PropertyAliases::getPropertyEnum(const char* alias) const { + NameToEnum* n2e = (NameToEnum*) getPointer(nameToEnum_offset); + return n2e->getEnum(alias, *this); +} + +inline const char* +PropertyAliases::getPropertyValueName(EnumValue prop, + EnumValue value, + UPropertyNameChoice choice) const { + const ValueMap* vm = getValueMap(prop); + if (!vm) return NULL; + Offset a; + if (vm->enumToName_offset) { + a = ((EnumToOffset*) getPointer(vm->enumToName_offset))-> + getOffset(value); + } else { + a = ((NonContiguousEnumToOffset*) getPointer(vm->ncEnumToName_offset))-> + getOffset(value); + } + return chooseNameInGroup(a, choice); +} + +inline EnumValue +PropertyAliases::getPropertyValueEnum(EnumValue prop, + const char* alias) const { + const ValueMap* vm = getValueMap(prop); + if (!vm) return UCHAR_INVALID_CODE; + NameToEnum* n2e = (NameToEnum*) getPointer(vm->nameToEnum_offset); + return n2e->getEnum(alias, *this); +} + +U_NAMESPACE_END +U_NAMESPACE_USE + +//---------------------------------------------------------------------- +// UDataMemory structures + +static const PropertyAliases* PNAME = NULL; +static UDataMemory* UDATA = NULL; + +//---------------------------------------------------------------------- +// UDataMemory loading/unloading + +/** + * udata callback to verify the zone data. + */ +U_CDECL_BEGIN +static UBool U_CALLCONV +isPNameAcceptable(void* /*context*/, + const char* /*type*/, const char* /*name*/, + const UDataInfo* info) { + return + info->size >= sizeof(UDataInfo) && + info->isBigEndian == U_IS_BIG_ENDIAN && + info->charsetFamily == U_CHARSET_FAMILY && + info->dataFormat[0] == PNAME_SIG_0 && + info->dataFormat[1] == PNAME_SIG_1 && + info->dataFormat[2] == PNAME_SIG_2 && + info->dataFormat[3] == PNAME_SIG_3 && + info->formatVersion[0] == PNAME_FORMAT_VERSION; +} + +static UBool U_CALLCONV pname_cleanup(void) { + if (UDATA) { + udata_close(UDATA); + UDATA = NULL; + } + PNAME = NULL; + return TRUE; +} +U_CDECL_END + +/** + * Load the property names data. Caller should check that data is + * not loaded BEFORE calling this function. Returns TRUE if the load + * succeeds. + */ +static UBool _load() { + UErrorCode ec = U_ZERO_ERROR; + UDataMemory* data = + udata_openChoice(0, PNAME_DATA_TYPE, PNAME_DATA_NAME, + isPNameAcceptable, 0, &ec); + if (U_SUCCESS(ec)) { + umtx_lock(NULL); + if (UDATA == NULL) { + UDATA = data; + PNAME = (const PropertyAliases*) udata_getMemory(UDATA); + ucln_common_registerCleanup(UCLN_COMMON_PNAME, pname_cleanup); + data = NULL; + } + umtx_unlock(NULL); + } + if (data) { + udata_close(data); + } + return PNAME!=NULL; +} + +/** + * Inline function that expands to code that does a lazy load of the + * property names data. If the data is already loaded, avoids an + * unnecessary function call. If the data is not loaded, call _load() + * to load it, and return TRUE if the load succeeds. + */ +static inline UBool load() { + UBool f; + UMTX_CHECK(NULL, (PNAME!=NULL), f); + return f || _load(); +} + +//---------------------------------------------------------------------- +// Public API implementation + +// The C API is just a thin wrapper. Each function obtains a pointer +// to the singleton PropertyAliases, and calls the appropriate method +// on it. If it cannot obtain a pointer, because valid data is not +// available, then it returns NULL or UCHAR_INVALID_CODE. + +U_CAPI const char* U_EXPORT2 +u_getPropertyName(UProperty property, + UPropertyNameChoice nameChoice) { + return load() ? PNAME->getPropertyName(property, nameChoice) + : NULL; +} + +U_CAPI UProperty U_EXPORT2 +u_getPropertyEnum(const char* alias) { + UProperty p = load() ? (UProperty) PNAME->getPropertyEnum(alias) + : UCHAR_INVALID_CODE; + return p; +} + +U_CAPI const char* U_EXPORT2 +u_getPropertyValueName(UProperty property, + int32_t value, + UPropertyNameChoice nameChoice) { + return load() ? PNAME->getPropertyValueName(property, value, nameChoice) + : NULL; +} + +U_CAPI int32_t U_EXPORT2 +u_getPropertyValueEnum(UProperty property, + const char* alias) { + return load() ? PNAME->getPropertyValueEnum(property, alias) + : (int32_t)UCHAR_INVALID_CODE; +} + +/* data swapping ------------------------------------------------------------ */ + +/* + * Sub-structure-swappers use the temp array (which is as large as the + * actual data) for intermediate storage, + * as well as to indicate if a particular structure has been swapped already. + * The temp array is initially reset to all 0. + * pos is the byte offset of the sub-structure in the inBytes/outBytes/temp arrays. + */ + +int32_t +EnumToOffset::swap(const UDataSwapper *ds, + const uint8_t *inBytes, int32_t length, uint8_t *outBytes, + uint8_t *temp, int32_t pos, + UErrorCode *pErrorCode) { + const EnumToOffset *inMap; + EnumToOffset *outMap, *tempMap; + int32_t size; + + tempMap=(EnumToOffset *)(temp+pos); + if(tempMap->enumStart!=0 || tempMap->enumLimit!=0) { + /* this map was swapped already */ + size=tempMap->getSize(); + return size; + } + + inMap=(const EnumToOffset *)(inBytes+pos); + outMap=(EnumToOffset *)(outBytes+pos); + + tempMap->enumStart=udata_readInt32(ds, inMap->enumStart); + tempMap->enumLimit=udata_readInt32(ds, inMap->enumLimit); + size=tempMap->getSize(); + + if(length>=0) { + if(length<(pos+size)) { + if(length<(int32_t)sizeof(PropertyAliases)) { + udata_printError(ds, "upname_swap(EnumToOffset): too few bytes (%d after header)\n" + " for pnames.icu EnumToOffset{%d..%d} at %d\n", + length, tempMap->enumStart, tempMap->enumLimit, pos); + *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; + return 0; + } + } + + /* swap enumStart and enumLimit */ + ds->swapArray32(ds, inMap, 2*sizeof(EnumValue), outMap, pErrorCode); + + /* swap _offsetArray[] */ + ds->swapArray16(ds, inMap->getOffsetArray(), (tempMap->enumLimit-tempMap->enumStart)*sizeof(Offset), + outMap->getOffsetArray(), pErrorCode); + } + + return size; +} + +int32_t +NonContiguousEnumToOffset::swap(const UDataSwapper *ds, + const uint8_t *inBytes, int32_t length, uint8_t *outBytes, + uint8_t *temp, int32_t pos, + UErrorCode *pErrorCode) { + const NonContiguousEnumToOffset *inMap; + NonContiguousEnumToOffset *outMap, *tempMap; + int32_t size; + + tempMap=(NonContiguousEnumToOffset *)(temp+pos); + if(tempMap->count!=0) { + /* this map was swapped already */ + size=tempMap->getSize(); + return size; + } + + inMap=(const NonContiguousEnumToOffset *)(inBytes+pos); + outMap=(NonContiguousEnumToOffset *)(outBytes+pos); + + tempMap->count=udata_readInt32(ds, inMap->count); + size=tempMap->getSize(); + + if(length>=0) { + if(length<(pos+size)) { + if(length<(int32_t)sizeof(PropertyAliases)) { + udata_printError(ds, "upname_swap(NonContiguousEnumToOffset): too few bytes (%d after header)\n" + " for pnames.icu NonContiguousEnumToOffset[%d] at %d\n", + length, tempMap->count, pos); + *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; + return 0; + } + } + + /* swap count and _enumArray[] */ + length=(1+tempMap->count)*sizeof(EnumValue); + ds->swapArray32(ds, inMap, length, + outMap, pErrorCode); + + /* swap _offsetArray[] */ + pos+=length; + ds->swapArray16(ds, inBytes+pos, tempMap->count*sizeof(Offset), + outBytes+pos, pErrorCode); + } + + return size; +} + +struct NameAndIndex { + Offset name, index; +}; + +U_CDECL_BEGIN +typedef int32_t U_CALLCONV PropNameCompareFn(const char *name1, const char *name2); + +struct CompareContext { + const char *chars; + PropNameCompareFn *propCompare; +}; + +static int32_t U_CALLCONV +upname_compareRows(const void *context, const void *left, const void *right) { + CompareContext *cmp=(CompareContext *)context; + return cmp->propCompare(cmp->chars+((const NameAndIndex *)left)->name, + cmp->chars+((const NameAndIndex *)right)->name); +} +U_CDECL_END + +int32_t +NameToEnum::swap(const UDataSwapper *ds, + const uint8_t *inBytes, int32_t length, uint8_t *outBytes, + uint8_t *temp, int32_t pos, + UErrorCode *pErrorCode) { + const NameToEnum *inMap; + NameToEnum *outMap, *tempMap; + + const EnumValue *inEnumArray; + EnumValue *outEnumArray; + + const Offset *inNameArray; + Offset *outNameArray; + + NameAndIndex *sortArray; + CompareContext cmp; + + int32_t i, size, oldIndex; + + tempMap=(NameToEnum *)(temp+pos); + if(tempMap->count!=0) { + /* this map was swapped already */ + size=tempMap->getSize(); + return size; + } + + inMap=(const NameToEnum *)(inBytes+pos); + outMap=(NameToEnum *)(outBytes+pos); + + tempMap->count=udata_readInt32(ds, inMap->count); + size=tempMap->getSize(); + + if(length>=0) { + if(length<(pos+size)) { + if(length<(int32_t)sizeof(PropertyAliases)) { + udata_printError(ds, "upname_swap(NameToEnum): too few bytes (%d after header)\n" + " for pnames.icu NameToEnum[%d] at %d\n", + length, tempMap->count, pos); + *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; + return 0; + } + } + + /* swap count */ + ds->swapArray32(ds, inMap, 4, outMap, pErrorCode); + + inEnumArray=inMap->getEnumArray(); + outEnumArray=outMap->getEnumArray(); + + inNameArray=(const Offset *)(inEnumArray+tempMap->count); + outNameArray=(Offset *)(outEnumArray+tempMap->count); + + if(ds->inCharset==ds->outCharset) { + /* no need to sort, just swap the enum/name arrays */ + ds->swapArray32(ds, inEnumArray, tempMap->count*4, outEnumArray, pErrorCode); + ds->swapArray16(ds, inNameArray, tempMap->count*2, outNameArray, pErrorCode); + return size; + } + + /* + * The name and enum arrays are sorted by names and must be resorted + * if inCharset!=outCharset. + * We use the corresponding part of the temp array to sort an array + * of pairs of name offsets and sorting indexes. + * Then the sorting indexes are used to permutate-swap the name and enum arrays. + * + * The outBytes must already contain the swapped strings. + */ + sortArray=(NameAndIndex *)tempMap->getEnumArray(); + for(i=0; i<tempMap->count; ++i) { + sortArray[i].name=udata_readInt16(ds, inNameArray[i]); + sortArray[i].index=(Offset)i; + } + + /* + * use a stable sort to avoid shuffling of equal strings, + * which makes testing harder + */ + cmp.chars=(const char *)outBytes; + if (ds->outCharset==U_ASCII_FAMILY) { + cmp.propCompare=uprv_compareASCIIPropertyNames; + } + else { + cmp.propCompare=uprv_compareEBCDICPropertyNames; + } + uprv_sortArray(sortArray, tempMap->count, sizeof(NameAndIndex), + upname_compareRows, &cmp, + TRUE, pErrorCode); + if(U_FAILURE(*pErrorCode)) { + udata_printError(ds, "upname_swap(NameToEnum).uprv_sortArray(%d items) failed\n", + tempMap->count); + return 0; + } + + /* copy/swap/permutate _enumArray[] and _nameArray[] */ + if(inEnumArray!=outEnumArray) { + for(i=0; i<tempMap->count; ++i) { + oldIndex=sortArray[i].index; + ds->swapArray32(ds, inEnumArray+oldIndex, 4, outEnumArray+i, pErrorCode); + ds->swapArray16(ds, inNameArray+oldIndex, 2, outNameArray+i, pErrorCode); + } + } else { + /* + * in-place swapping: need to permutate into a temporary array + * and then copy back to not destroy the data + */ + EnumValue *tempEnumArray; + Offset *oldIndexes; + + /* write name offsets directly from sortArray */ + for(i=0; i<tempMap->count; ++i) { + ds->writeUInt16((uint16_t *)outNameArray+i, (uint16_t)sortArray[i].name); + } + + /* + * compress the oldIndexes into a separate array to make space for tempEnumArray + * the tempMap _nameArray becomes oldIndexes[], getting the index + * values from the 2D sortArray[], + * while sortArray=tempMap _enumArray[] becomes tempEnumArray[] + * this saves us allocating more memory + * + * it works because sizeof(NameAndIndex)<=sizeof(EnumValue) + * and because the nameArray[] can be used for oldIndexes[] + */ + tempEnumArray=(EnumValue *)sortArray; + oldIndexes=(Offset *)(sortArray+tempMap->count); + + /* copy sortArray[].index values into oldIndexes[] */ + for(i=0; i<tempMap->count; ++i) { + oldIndexes[i]=sortArray[i].index; + } + + /* permutate inEnumArray[] into tempEnumArray[] */ + for(i=0; i<tempMap->count; ++i) { + ds->swapArray32(ds, inEnumArray+oldIndexes[i], 4, tempEnumArray+i, pErrorCode); + } + + /* copy tempEnumArray[] to outEnumArray[] */ + uprv_memcpy(outEnumArray, tempEnumArray, tempMap->count*4); + } + } + + return size; +} + +int32_t +PropertyAliases::swap(const UDataSwapper *ds, + const uint8_t *inBytes, int32_t length, uint8_t *outBytes, + UErrorCode *pErrorCode) { + const PropertyAliases *inAliases; + PropertyAliases *outAliases; + PropertyAliases aliases; + + const ValueMap *inValueMaps; + ValueMap *outValueMaps; + ValueMap valueMap; + + uint8_t *temp; + + int32_t i; + + inAliases=(const PropertyAliases *)inBytes; + outAliases=(PropertyAliases *)outBytes; + + /* read the input PropertyAliases - all 16-bit values */ + for(i=0; i<(int32_t)sizeof(PropertyAliases)/2; ++i) { + ((uint16_t *)&aliases)[i]=ds->readUInt16(((const uint16_t *)inBytes)[i]); + } + + if(length>=0) { + if(length<aliases.total_size) { + udata_printError(ds, "upname_swap(): too few bytes (%d after header) for all of pnames.icu\n", + length); + *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; + return 0; + } + + /* copy the data for inaccessible bytes */ + if(inBytes!=outBytes) { + uprv_memcpy(outBytes, inBytes, aliases.total_size); + } + + /* swap the PropertyAliases class fields */ + ds->swapArray16(ds, inAliases, sizeof(PropertyAliases), outAliases, pErrorCode); + + /* swap the name groups */ + ds->swapArray16(ds, inBytes+aliases.nameGroupPool_offset, + aliases.stringPool_offset-aliases.nameGroupPool_offset, + outBytes+aliases.nameGroupPool_offset, pErrorCode); + + /* swap the strings */ + udata_swapInvStringBlock(ds, inBytes+aliases.stringPool_offset, + aliases.total_size-aliases.stringPool_offset, + outBytes+aliases.stringPool_offset, pErrorCode); + + /* + * alloc uint8_t temp[total_size] and reset it + * swap each top-level struct, put at least the count fields into temp + * use subclass-specific swap() functions + * enumerate value maps, for each + * if temp does not have count!=0 yet + * read count, put it into temp + * swap the array(s) + * resort strings in name->enum maps + * swap value maps + */ + temp=(uint8_t *)uprv_malloc(aliases.total_size); + if(temp==NULL) { + udata_printError(ds, "upname_swap(): unable to allocate temp memory (%d bytes)\n", + aliases.total_size); + *pErrorCode=U_MEMORY_ALLOCATION_ERROR; + return 0; + } + uprv_memset(temp, 0, aliases.total_size); + + /* swap properties->name groups map */ + NonContiguousEnumToOffset::swap(ds, inBytes, length, outBytes, + temp, aliases.enumToName_offset, pErrorCode); + + /* swap name->properties map */ + NameToEnum::swap(ds, inBytes, length, outBytes, + temp, aliases.nameToEnum_offset, pErrorCode); + + /* swap properties->value maps map */ + NonContiguousEnumToOffset::swap(ds, inBytes, length, outBytes, + temp, aliases.enumToValue_offset, pErrorCode); + + /* enumerate all ValueMaps and swap them */ + inValueMaps=(const ValueMap *)(inBytes+aliases.valueMap_offset); + outValueMaps=(ValueMap *)(outBytes+aliases.valueMap_offset); + + for(i=0; i<aliases.valueMap_count; ++i) { + valueMap.enumToName_offset=udata_readInt16(ds, inValueMaps[i].enumToName_offset); + valueMap.ncEnumToName_offset=udata_readInt16(ds, inValueMaps[i].ncEnumToName_offset); + valueMap.nameToEnum_offset=udata_readInt16(ds, inValueMaps[i].nameToEnum_offset); + + if(valueMap.enumToName_offset!=0) { + EnumToOffset::swap(ds, inBytes, length, outBytes, + temp, valueMap.enumToName_offset, + pErrorCode); + } else if(valueMap.ncEnumToName_offset!=0) { + NonContiguousEnumToOffset::swap(ds, inBytes, length, outBytes, + temp, valueMap.ncEnumToName_offset, + pErrorCode); + } + if(valueMap.nameToEnum_offset!=0) { + NameToEnum::swap(ds, inBytes, length, outBytes, + temp, valueMap.nameToEnum_offset, + pErrorCode); + } + } + + /* swap the ValueMaps array itself */ + ds->swapArray16(ds, inValueMaps, aliases.valueMap_count*sizeof(ValueMap), + outValueMaps, pErrorCode); + + /* name groups and strings were swapped above */ + + /* release temp */ + uprv_free(temp); + } + + return aliases.total_size; +} + +U_CAPI int32_t U_EXPORT2 +upname_swap(const UDataSwapper *ds, + const void *inData, int32_t length, void *outData, + UErrorCode *pErrorCode) { + const UDataInfo *pInfo; + int32_t headerSize; + + const uint8_t *inBytes; + uint8_t *outBytes; + + /* udata_swapDataHeader checks the arguments */ + headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode); + if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { + return 0; + } + + /* check data format and format version */ + pInfo=(const UDataInfo *)((const char *)inData+4); + if(!( + pInfo->dataFormat[0]==0x70 && /* dataFormat="pnam" */ + pInfo->dataFormat[1]==0x6e && + pInfo->dataFormat[2]==0x61 && + pInfo->dataFormat[3]==0x6d && + pInfo->formatVersion[0]==1 + )) { + udata_printError(ds, "upname_swap(): data format %02x.%02x.%02x.%02x (format version %02x) is not recognized as pnames.icu\n", + pInfo->dataFormat[0], pInfo->dataFormat[1], + pInfo->dataFormat[2], pInfo->dataFormat[3], + pInfo->formatVersion[0]); + *pErrorCode=U_UNSUPPORTED_ERROR; + return 0; + } + + inBytes=(const uint8_t *)inData+headerSize; + outBytes=(uint8_t *)outData+headerSize; + + if(length>=0) { + length-=headerSize; + if(length<(int32_t)sizeof(PropertyAliases)) { + udata_printError(ds, "upname_swap(): too few bytes (%d after header) for pnames.icu\n", + length); + *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; + return 0; + } + } + + return headerSize+PropertyAliases::swap(ds, inBytes, length, outBytes, pErrorCode); +} + +//eof |