diff options
Diffstat (limited to 'Build/source/libs/icu-xetex/common/ucol_swp.c')
-rw-r--r-- | Build/source/libs/icu-xetex/common/ucol_swp.c | 87 |
1 files changed, 81 insertions, 6 deletions
diff --git a/Build/source/libs/icu-xetex/common/ucol_swp.c b/Build/source/libs/icu-xetex/common/ucol_swp.c index 18e2c2cad08..3b8ac14c30f 100644 --- a/Build/source/libs/icu-xetex/common/ucol_swp.c +++ b/Build/source/libs/icu-xetex/common/ucol_swp.c @@ -1,7 +1,7 @@ /* ******************************************************************************* * -* Copyright (C) 2003, International Business Machines +* Copyright (C) 2003-2006, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -16,17 +16,92 @@ * Swap collation binaries. */ -#include "unicode/utypes.h" - -#if !UCONFIG_NO_COLLATION - #include "unicode/udata.h" /* UDataInfo */ -#include "cmemory.h" #include "utrie.h" #include "udataswp.h" +#include "cmemory.h" #include "ucol_imp.h" #include "ucol_swp.h" +/* swapping ----------------------------------------------------------------- */ + +/* + * This performs data swapping for a folded trie (see utrie.c for details). + */ + +U_CAPI int32_t U_EXPORT2 +utrie_swap(const UDataSwapper *ds, + const void *inData, int32_t length, void *outData, + UErrorCode *pErrorCode) { + const UTrieHeader *inTrie; + UTrieHeader trie; + int32_t size; + UBool dataIs32; + + if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { + return 0; + } + if(ds==NULL || inData==NULL || (length>=0 && outData==NULL)) { + *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + + /* setup and swapping */ + if(length>=0 && length<sizeof(UTrieHeader)) { + *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; + return 0; + } + + inTrie=(const UTrieHeader *)inData; + trie.signature=ds->readUInt32(inTrie->signature); + trie.options=ds->readUInt32(inTrie->options); + trie.indexLength=udata_readInt32(ds, inTrie->indexLength); + trie.dataLength=udata_readInt32(ds, inTrie->dataLength); + + if( trie.signature!=0x54726965 || + (trie.options&UTRIE_OPTIONS_SHIFT_MASK)!=UTRIE_SHIFT || + ((trie.options>>UTRIE_OPTIONS_INDEX_SHIFT)&UTRIE_OPTIONS_SHIFT_MASK)!=UTRIE_INDEX_SHIFT || + trie.indexLength<UTRIE_BMP_INDEX_LENGTH || + (trie.indexLength&(UTRIE_SURROGATE_BLOCK_COUNT-1))!=0 || + trie.dataLength<UTRIE_DATA_BLOCK_LENGTH || + (trie.dataLength&(UTRIE_DATA_GRANULARITY-1))!=0 || + ((trie.options&UTRIE_OPTIONS_LATIN1_IS_LINEAR)!=0 && trie.dataLength<(UTRIE_DATA_BLOCK_LENGTH+0x100)) + ) { + *pErrorCode=U_INVALID_FORMAT_ERROR; /* not a UTrie */ + return 0; + } + + dataIs32=(UBool)((trie.options&UTRIE_OPTIONS_DATA_IS_32_BIT)!=0); + size=sizeof(UTrieHeader)+trie.indexLength*2+trie.dataLength*(dataIs32?4:2); + + if(length>=0) { + UTrieHeader *outTrie; + + if(length<size) { + *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; + return 0; + } + + outTrie=(UTrieHeader *)outData; + + /* swap the header */ + ds->swapArray32(ds, inTrie, sizeof(UTrieHeader), outTrie, pErrorCode); + + /* swap the index and the data */ + if(dataIs32) { + ds->swapArray16(ds, inTrie+1, trie.indexLength*2, outTrie+1, pErrorCode); + ds->swapArray32(ds, (const uint16_t *)(inTrie+1)+trie.indexLength, trie.dataLength*4, + (uint16_t *)(outTrie+1)+trie.indexLength, pErrorCode); + } else { + ds->swapArray16(ds, inTrie+1, (trie.indexLength+trie.dataLength)*2, outTrie+1, pErrorCode); + } + } + + return size; +} + +#if !UCONFIG_NO_COLLATION + /* swap a header-less collation binary, inside a resource bundle or ucadata.icu */ U_CAPI int32_t U_EXPORT2 ucol_swapBinary(const UDataSwapper *ds, |