1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* * 450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho* Copyright (C) 1999-2010, International Business Machines Corporation * 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* and others. All Rights Reserved. * 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* * 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* file name: uresdata.c 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* encoding: US-ASCII 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* tab size: 8 (not used) 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* indentation:4 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* created on: 1999dec08 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* created by: Markus W. Scherer 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification History: 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Date Name Description 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 06/20/2000 helena OS/400 port changes; mostly typecast. 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 06/24/02 weiv Added support for resource sharing 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/udata.h" 2450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/ustring.h" 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uarrsort.h" 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "udataswp.h" 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucol_swp.h" 3050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "uinvchar.h" 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uresdata.h" 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uresimp.h" 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Resource access helpers 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* get a const char* pointer to the key with the keyOffset byte offset from pRoot */ 4150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define RES_GET_KEY16(pResData, keyOffset) \ 4250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ((keyOffset)<(pResData)->localKeyLimit ? \ 4350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (const char *)(pResData)->pRoot+(keyOffset) : \ 4450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (pResData)->poolBundleKeys+(keyOffset)-(pResData)->localKeyLimit) 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 4650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define RES_GET_KEY32(pResData, keyOffset) \ 4750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ((keyOffset)>=0 ? \ 4850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (const char *)(pResData)->pRoot+(keyOffset) : \ 4950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (pResData)->poolBundleKeys+((keyOffset)&0x7fffffff)) 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 5150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define URESDATA_ITEM_NOT_FOUND -1 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 5350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* empty resources, returned when the resource offset is 0 */ 5450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const uint16_t gEmpty16=0; 5550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const int32_t gEmpty32=0; 5650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const struct { 5750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UChar nul; 5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UChar pad; 6050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} gEmptyString={ 0, 0, 0 }; 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 6350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * All the type-access functions assume that 6450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * the resource is of the expected type. 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 6750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t 6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho_res_findTableItem(const ResourceData *pResData, const uint16_t *keyOffsets, int32_t length, 6950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *key, const char **realKey) { 7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *tableKey; 7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t mid, start, limit; 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int result; 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* do a binary search for the key */ 7550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho start=0; 7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho limit=length; 7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while(start<limit) { 7850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho mid = (start + limit) / 2; 7950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho tableKey = RES_GET_KEY16(pResData, keyOffsets[mid]); 8050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (pResData->useNativeStrcmp) { 8150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho result = uprv_strcmp(key, tableKey); 8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 8350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho result = uprv_compareInvCharsAsAscii(key, tableKey); 8450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 8550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (result < 0) { 8650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho limit = mid; 8750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (result > 0) { 8850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho start = mid + 1; 8950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 9050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* We found it! */ 9150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *realKey=tableKey; 9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return mid; 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 9550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return URESDATA_ITEM_NOT_FOUND; /* not found or table is empty. */ 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 9850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t 9950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho_res_findTable32Item(const ResourceData *pResData, const int32_t *keyOffsets, int32_t length, 10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *key, const char **realKey) { 10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *tableKey; 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t mid, start, limit; 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int result; 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* do a binary search for the key */ 10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho start=0; 10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho limit=length; 10850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while(start<limit) { 10950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho mid = (start + limit) / 2; 11050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho tableKey = RES_GET_KEY32(pResData, keyOffsets[mid]); 11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (pResData->useNativeStrcmp) { 11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho result = uprv_strcmp(key, tableKey); 11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho result = uprv_compareInvCharsAsAscii(key, tableKey); 11550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (result < 0) { 11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho limit = mid; 11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (result > 0) { 11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho start = mid + 1; 12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 12150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* We found it! */ 12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *realKey=tableKey; 12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return mid; 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 12650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return URESDATA_ITEM_NOT_FOUND; /* not found or table is empty. */ 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* helper for res_load() ---------------------------------------------------- */ 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool U_CALLCONV 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruisAcceptable(void *context, 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *type, const char *name, 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UDataInfo *pInfo) { 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(context, pInfo->formatVersion, 4); 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (UBool)( 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->size>=20 && 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->isBigEndian==U_IS_BIG_ENDIAN && 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->charsetFamily==U_CHARSET_FAMILY && 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->sizeofUChar==U_SIZEOF_UCHAR && 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[0]==0x52 && /* dataFormat="ResB" */ 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[1]==0x65 && 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[2]==0x73 && 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[3]==0x42 && 14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (pInfo->formatVersion[0]==1 || pInfo->formatVersion[0]==2)); 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* semi-public functions ---------------------------------------------------- */ 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 15050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 15150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_init(ResourceData *pResData, 15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UVersionInfo formatVersion, const void *inBytes, int32_t length, 15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *errorCode) { 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResType rootType; 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 15650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* get the root resource */ 15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->pRoot=(const int32_t *)inBytes; 15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->rootRes=(Resource)*pResData->pRoot; 15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->p16BitUnits=&gEmpty16; 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* formatVersion 1.1 must have a root item and at least 5 indexes */ 16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(length>=0 && (length/4)<((formatVersion[0]==1 && formatVersion[1]==0) ? 1 : 1+5)) { 16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *errorCode=U_INVALID_FORMAT_ERROR; 16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_unload(pResData); 16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* currently, we accept only resources that have a Table as their roots */ 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rootType=RES_GET_TYPE(pResData->rootRes); 17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(!URES_IS_TABLE(rootType)) { 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *errorCode=U_INVALID_FORMAT_ERROR; 17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_unload(pResData); 17350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(formatVersion[0]==1 && formatVersion[1]==0) { 17750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->localKeyLimit=0x10000; /* greater than any 16-bit key string offset */ 17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* bundles with formatVersion 1.1 and later contain an indexes[] array */ 18050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *indexes=pResData->pRoot+1; 18150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t indexLength=indexes[URES_INDEX_LENGTH]&0xff; 18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexLength<=URES_INDEX_MAX_TABLE_LENGTH) { 18350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *errorCode=U_INVALID_FORMAT_ERROR; 18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_unload(pResData); 18550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if( length>=0 && 18850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (length<((1+indexLength)<<2) || 18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length<(indexes[URES_INDEX_BUNDLE_TOP]<<2)) 19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ) { 19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *errorCode=U_INVALID_FORMAT_ERROR; 19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_unload(pResData); 19350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 19550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexes[URES_INDEX_KEYS_TOP]>(1+indexLength)) { 19650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->localKeyLimit=indexes[URES_INDEX_KEYS_TOP]<<2; 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 19850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexLength>URES_INDEX_ATTRIBUTES) { 19950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t att=indexes[URES_INDEX_ATTRIBUTES]; 20050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->noFallback=(UBool)(att&URES_ATT_NO_FALLBACK); 20150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->isPoolBundle=(UBool)((att&URES_ATT_IS_POOL_BUNDLE)!=0); 20250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->usesPoolBundle=(UBool)((att&URES_ATT_USES_POOL_BUNDLE)!=0); 20350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 20450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if((pResData->isPoolBundle || pResData->usesPoolBundle) && indexLength<=URES_INDEX_POOL_CHECKSUM) { 20550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *errorCode=U_INVALID_FORMAT_ERROR; 20650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_unload(pResData); 20750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 20850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 20950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if( indexLength>URES_INDEX_16BIT_TOP && 21050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho indexes[URES_INDEX_16BIT_TOP]>indexes[URES_INDEX_KEYS_TOP] 21150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ) { 21250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->p16BitUnits=(const uint16_t *)(pResData->pRoot+indexes[URES_INDEX_KEYS_TOP]); 21350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 21450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 21550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 21650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(formatVersion[0]==1 || U_CHARSET_FAMILY==U_ASCII_FAMILY) { 21750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 21850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * formatVersion 1: compare key strings in native-charset order 21950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * formatVersion 2 and up: compare key strings in ASCII order 22050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 22150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->useNativeStrcmp=TRUE; 22250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 22350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 22550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI void U_EXPORT2 22650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_read(ResourceData *pResData, 22750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UDataInfo *pInfo, const void *inBytes, int32_t length, 22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *errorCode) { 22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UVersionInfo formatVersion; 23050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 23150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memset(pResData, 0, sizeof(ResourceData)); 23250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_FAILURE(*errorCode)) { 23350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 23450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(!isAcceptable(formatVersion, NULL, NULL, pInfo)) { 23650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *errorCode=U_INVALID_FORMAT_ERROR; 23750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 23850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 23950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_init(pResData, formatVersion, inBytes, length, errorCode); 24050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 24150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 24250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CFUNC void 24350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_load(ResourceData *pResData, 24450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *path, const char *name, UErrorCode *errorCode) { 24550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UVersionInfo formatVersion; 24650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 24750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memset(pResData, 0, sizeof(ResourceData)); 24850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 24950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* load the ResourceBundle file */ 25050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->data=udata_openChoice(path, "res", name, isAcceptable, formatVersion, errorCode); 25150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_FAILURE(*errorCode)) { 25250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 25550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* get its memory and initialize *pResData */ 25650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_init(pResData, formatVersion, udata_getMemory(pResData->data), -1, errorCode); 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC void 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querures_unload(ResourceData *pResData) { 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pResData->data!=NULL) { 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_close(pResData->data); 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pResData->data=NULL; 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 26750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const int8_t gPublicTypes[URES_LIMIT] = { 26850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_STRING, 26950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_BINARY, 27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_TABLE, 27150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_ALIAS, 27250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 27350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_TABLE, /* URES_TABLE32 */ 27450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_TABLE, /* URES_TABLE16 */ 27550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_STRING, /* URES_STRING_V2 */ 27650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_INT, 27750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 27850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_ARRAY, 27950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_ARRAY, /* URES_ARRAY16 */ 28050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_NONE, 28150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_NONE, 28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 28350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_NONE, 28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_NONE, 28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_INT_VECTOR, 28650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_NONE 28750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 28850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 28950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI UResType U_EXPORT2 29050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getPublicType(Resource res) { 29150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return (UResType)gPublicTypes[RES_GET_TYPE(res)]; 29250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 29350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 29450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI const UChar * U_EXPORT2 29550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getString(const ResourceData *pResData, Resource res, int32_t *pLength) { 29650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *p; 29750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(res); 29850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 29950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(RES_GET_TYPE(res)==URES_STRING_V2) { 30050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t first; 30150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=(const UChar *)(pResData->p16BitUnits+offset); 30250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho first=*p; 30350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(!U16_IS_TRAIL(first)) { 30450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=u_strlen(p); 30550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if(first<0xdfef) { 30650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=first&0x3ff; 30750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ++p; 30850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if(first<0xdfff) { 30950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=((first-0xdfef)<<16)|p[1]; 31050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p+=2; 31150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 31250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=((int32_t)p[1]<<16)|p[2]; 31350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p+=3; 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 31550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if(res==offset) /* RES_GET_TYPE(res)==URES_STRING */ { 31650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *p32= res==0 ? &gEmptyString.length : pResData->pRoot+res; 31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p32++; 31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=(const UChar *)p32; 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=NULL; 32150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=0; 32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 32350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pLength) { 32450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pLength=length; 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 32650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return p; 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 32950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI const UChar * U_EXPORT2 33050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getAlias(const ResourceData *pResData, Resource res, int32_t *pLength) { 33150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *p; 33250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(res); 33350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(RES_GET_TYPE(res)==URES_ALIAS) { 33550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *p32= offset==0 ? &gEmptyString.length : pResData->pRoot+offset; 33650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p32++; 33750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=(const UChar *)p32; 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 33950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=NULL; 34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=0; 34150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 34250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pLength) { 34350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pLength=length; 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 34550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return p; 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 34850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI const uint8_t * U_EXPORT2 34950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getBinary(const ResourceData *pResData, Resource res, int32_t *pLength) { 35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const uint8_t *p; 35150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(res); 35250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 35350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(RES_GET_TYPE(res)==URES_BINARY) { 35450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *p32= offset==0 ? &gEmpty32 : pResData->pRoot+offset; 35550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p32++; 35650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=(const uint8_t *)p32; 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 35850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=NULL; 35950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=0; 36050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 36150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pLength) { 36250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pLength=length; 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 36450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return p; 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 36850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI const int32_t * U_EXPORT2 36950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getIntVector(const ResourceData *pResData, Resource res, int32_t *pLength) { 37050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *p; 37150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(res); 37250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 37350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(RES_GET_TYPE(res)==URES_INT_VECTOR) { 37450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p= offset==0 ? &gEmpty32 : pResData->pRoot+offset; 37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p++; 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=NULL; 37850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=0; 37950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 38050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pLength) { 38150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pLength=length; 38250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 38350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return p; 38450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 38550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 38650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI int32_t U_EXPORT2 38750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_countArrayItems(const ResourceData *pResData, Resource res) { 38850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(res); 38950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch(RES_GET_TYPE(res)) { 39050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_STRING: 39150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_STRING_V2: 39250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_BINARY: 39350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ALIAS: 39450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_INT: 39550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_INT_VECTOR: 39650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 1; 39750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ARRAY: 39850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE32: 39950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return offset==0 ? 0 : *(pResData->pRoot+offset); 40050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE: 40150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return offset==0 ? 0 : *((const uint16_t *)(pResData->pRoot+offset)); 40250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ARRAY16: 40350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE16: 40450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return pResData->p16BitUnits[offset]; 40550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 40650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 41050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI Resource U_EXPORT2 41150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getTableItemByKey(const ResourceData *pResData, Resource table, 41250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t *indexR, const char **key) { 41350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(table); 41450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 41550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t idx; 41650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(key == NULL || *key == NULL) { 41750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return RES_BOGUS; 41850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 41950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch(RES_GET_TYPE(table)) { 42050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE: { 42150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const uint16_t *p= offset==0 ? &gEmpty16 : (const uint16_t *)(pResData->pRoot+offset); 42250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p++; 42350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *indexR=idx=_res_findTableItem(pResData, p, length, *key, key); 42450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(idx>=0) { 42550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const Resource *p32=(const Resource *)(p+length+(~length&1)); 42650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return p32[idx]; 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 42850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 42950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 43050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE16: { 43150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const uint16_t *p=pResData->p16BitUnits+offset; 43250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p++; 43350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *indexR=idx=_res_findTableItem(pResData, p, length, *key, key); 43450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(idx>=0) { 43550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return URES_MAKE_RESOURCE(URES_STRING_V2, p[length+idx]); 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 43750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 43850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 43950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE32: { 44050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *p= offset==0 ? &gEmpty32 : pResData->pRoot+offset; 44150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p++; 44250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *indexR=idx=_res_findTable32Item(pResData, p, length, *key, key); 44350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(idx>=0) { 44450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return (Resource)p[length+idx]; 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 44650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 44750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 44850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 44950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 45050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 45150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return RES_BOGUS; 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 45450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI Resource U_EXPORT2 45550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getTableItemByIndex(const ResourceData *pResData, Resource table, 45650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t indexR, const char **key) { 45750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(table); 45850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 45950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch(RES_GET_TYPE(table)) { 46050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE: { 46150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const uint16_t *p= offset==0 ? &gEmpty16 : (const uint16_t *)(pResData->pRoot+offset); 46250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p++; 46350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexR<length) { 46450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const Resource *p32=(const Resource *)(p+length+(~length&1)); 46550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(key!=NULL) { 46650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *key=RES_GET_KEY16(pResData, p[indexR]); 46750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 46850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return p32[indexR]; 46950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 47050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 47150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 47250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE16: { 47350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const uint16_t *p=pResData->p16BitUnits+offset; 47450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p++; 47550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexR<length) { 47650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(key!=NULL) { 47750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *key=RES_GET_KEY16(pResData, p[indexR]); 47850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 47950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return URES_MAKE_RESOURCE(URES_STRING_V2, p[length+indexR]); 48050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 48150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 48250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 48350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE32: { 48450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *p= offset==0 ? &gEmpty32 : pResData->pRoot+offset; 48550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p++; 48650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexR<length) { 48750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(key!=NULL) { 48850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *key=RES_GET_KEY32(pResData, p[indexR]); 48950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 49050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return (Resource)p[length+indexR]; 49150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 49250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 49350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 49450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 49550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 49650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 49750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return RES_BOGUS; 49850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 49950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 50050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI Resource U_EXPORT2 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querures_getResource(const ResourceData *pResData, const char *key) { 50250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *realKey=key; 503b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t idx; 50450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return res_getTableItemByKey(pResData, pResData->rootRes, &idx, &realKey); 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 50750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI Resource U_EXPORT2 50850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getArrayItem(const ResourceData *pResData, Resource array, int32_t indexR) { 50950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(array); 51050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch(RES_GET_TYPE(array)) { 51150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ARRAY: { 51250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *p= offset==0 ? &gEmpty32 : pResData->pRoot+offset; 51350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexR<*p) { 51450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return (Resource)p[1+indexR]; 51550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 51650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 51750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 51850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ARRAY16: { 51950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const uint16_t *p=pResData->p16BitUnits+offset; 52050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexR<*p) { 52150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return URES_MAKE_RESOURCE(URES_STRING_V2, p[1+indexR]); 52250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 52350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 52450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 52550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 52650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 52750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 52850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return RES_BOGUS; 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC Resource 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querures_findResource(const ResourceData *pResData, Resource r, char** path, const char** key) { 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we pass in a path. CollationElements/Sequence or zoneStrings/3/2 etc. 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * iterates over a path and stops when a scalar resource is found. This 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * CAN be an alias. Path gets set to the part that has not yet been processed. 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *pathP = *path, *nextSepP = *path; 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *closeIndex = NULL; 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource t1 = r; 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource t2; 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t indexR = 0; 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResType type = RES_GET_TYPE(t1); 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if you come in with an empty path, you'll be getting back the same resource */ 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!uprv_strlen(pathP)) { 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return r; 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* one needs to have an aggregate resource in order to search in it */ 55150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(!URES_IS_CONTAINER(type)) { 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return RES_BOGUS; 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 55550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while(nextSepP && *pathP && t1 != RES_BOGUS && URES_IS_CONTAINER(type)) { 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Iteration stops if: the path has been consumed, we found a non-existing 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * resource (t1 == RES_BOGUS) or we found a scalar resource (including alias) 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nextSepP = uprv_strchr(pathP, RES_PATH_SEPARATOR); 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if there are more separators, terminate string 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and set path to the remaining part of the string 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(nextSepP != NULL) { 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *nextSepP = 0; /* overwrite the separator with a NUL to terminate the key */ 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *path = nextSepP+1; 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *path = uprv_strchr(pathP, 0); 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if the resource is a table */ 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* try the key based access */ 57250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(URES_IS_TABLE(type)) { 57350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *key = pathP; 57450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho t2 = res_getTableItemByKey(pResData, t1, &indexR, key); 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(t2 == RES_BOGUS) { 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if we fail to get the resource by key, maybe we got an index */ 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexR = uprv_strtol(pathP, &closeIndex, 10); 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(closeIndex != pathP) { 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if we indeed have an index, try to get the item by index */ 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t2 = res_getTableItemByIndex(pResData, t1, indexR, key); 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 58350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if(URES_IS_ARRAY(type)) { 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexR = uprv_strtol(pathP, &closeIndex, 10); 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(closeIndex != pathP) { 58650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho t2 = res_getArrayItem(pResData, t1, indexR); 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t2 = RES_BOGUS; /* have an array, but don't have a valid index */ 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *key = NULL; 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { /* can't do much here, except setting t2 to bogus */ 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t2 = RES_BOGUS; 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t1 = t2; 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru type = RES_GET_TYPE(t1); 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* position pathP to next resource key/index */ 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pathP = *path; 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return t1; 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* resource bundle swapping ------------------------------------------------- */ 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Need to always enumerate the entire item tree, 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * track the lowest address of any item to use as the limit for char keys[], 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * track the highest address of any item to return the size of the data. 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We should have thought of storing those in the data... 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * It is possible to extend the data structure by putting additional values 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * in places that are inaccessible by ordinary enumeration of the item tree. 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * For example, additional integers could be stored at the beginning or 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * end of the key strings; this could be indicated by a minor version number, 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and the data swapping would have to know about these values. 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The data structure does not forbid keys to be shared, so we must swap 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * all keys once instead of each key when it is referenced. 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * These swapping functions assume that a resource bundle always has a length 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * that is a multiple of 4 bytes. 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Currently, this is trivially true because genrb writes bundle tree leaves 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * physically first, before their branches, so that the root table with its 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * array of resource items (uint32_t values) is always last. 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* definitions for table sorting ------------------------ */ 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * row of a temporary array 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * gets platform-endian key string indexes and sorting indexes; 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * after sorting this array by keys, the actual key/value arrays are permutated 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * according to the sorting indexes 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct Row { 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keyIndex, sortIndex; 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} Row; 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int32_t 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruures_compareRows(const void *context, const void *left, const void *right) { 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *keyChars=(const char *)context; 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int32_t)uprv_strcmp(keyChars+((const Row *)left)->keyIndex, 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keyChars+((const Row *)right)->keyIndex); 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct TempTable { 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *keyChars; 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Row *rows; 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t *resort; 65150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t *resFlags; 65250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t localKeyLimit; 65350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint8_t majorFormatVersion; 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} TempTable; 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruenum { 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru STACK_ROW_CAPACITY=200 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 66050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* The table item key string is not locally available. */ 66150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char *const gUnknownKey=""; 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* resource table key for collation binaries: "%%CollationBin" */ 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const UChar gCollationBinKey[]={ 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x25, 0x25, 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x42, 0x69, 0x6e, 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * swap one resource item 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruures_swapResource(const UDataSwapper *ds, 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const Resource *inBundle, Resource *outBundle, 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource res, /* caller swaps res itself */ 67850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *key, 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TempTable *pTempTable, 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const Resource *p; 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource *q; 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t offset, count; 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 68550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch(RES_GET_TYPE(res)) { 68650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE16: 68750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_STRING_V2: 68850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_INT: 68950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ARRAY16: 69050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* integer, or points to 16-bit units, nothing to do here */ 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 69250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 69350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* all other types use an offset to point to their data */ 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset=(int32_t)RES_GET_OFFSET(res); 69850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(offset==0) { 69950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* special offset indicating an empty item */ 70050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 70150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 70250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pTempTable->resFlags[offset>>5]&((uint32_t)1<<(offset&0x1f))) { 70350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* we already swapped this resource item */ 70450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 70550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 70650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* mark it as swapped now */ 70750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pTempTable->resFlags[offset>>5]|=((uint32_t)1<<(offset&0x1f)); 70850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 70950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p=inBundle+offset; 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru q=outBundle+offset; 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(RES_GET_TYPE(res)) { 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_ALIAS: 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* physically same value layout as string, fall through */ 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_STRING: 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=udata_readInt32(ds, (int32_t)*p); 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap length */ 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, p, 4, q, pErrorCode); 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap each UChar (the terminating NUL would not change) */ 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, p+1, 2*count, q+1, pErrorCode); 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_BINARY: 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=udata_readInt32(ds, (int32_t)*p); 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap length */ 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, p, 4, q, pErrorCode); 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* no need to swap or copy bytes - ures_swap() copied them all */ 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap known formats */ 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION 73150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if( key!=NULL && /* the binary is in a table */ 73250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (key!=gUnknownKey ? 73350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* its table key string is "%%CollationBin" */ 73450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 0==ds->compareInvChars(ds, key, -1, 73550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho gCollationBinKey, LENGTHOF(gCollationBinKey)-1) : 73650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* its table key string is unknown but it looks like a collation binary */ 73750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ucol_looksLikeCollationBinary(ds, p+1, count)) 73850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ) { 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucol_swapBinary(ds, p+1, count, q+1, pErrorCode); 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 74150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_TABLE: 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_TABLE32: 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint16_t *pKey16; 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t *qKey16; 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const int32_t *pKey32; 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t *qKey32; 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource item; 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i, oldIndex; 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(RES_GET_TYPE(res)==URES_TABLE) { 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get table item count */ 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pKey16=(const uint16_t *)p; 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru qKey16=(uint16_t *)q; 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=ds->readUInt16(*pKey16); 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pKey32=qKey32=NULL; 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap count */ 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, pKey16++, 2, qKey16++, pErrorCode); 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset+=((1+count)+1)/2; 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get table item count */ 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pKey32=(const int32_t *)p; 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru qKey32=(int32_t *)q; 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=udata_readInt32(ds, *pKey32); 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pKey16=qKey16=NULL; 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap count */ 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, pKey32++, 4, qKey32++, pErrorCode); 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset+=1+count; 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(count==0) { 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p=inBundle+offset; /* pointer to table resources */ 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru q=outBundle+offset; 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* recurse */ 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 79050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *itemKey=gUnknownKey; 79150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pKey16!=NULL) { 79250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t keyOffset=ds->readUInt16(pKey16[i]); 79350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(keyOffset<pTempTable->localKeyLimit) { 79450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho itemKey=(const char *)outBundle+keyOffset; 79550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 79750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t keyOffset=udata_readInt32(ds, pKey32[i]); 79850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(keyOffset>=0) { 79950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho itemKey=(const char *)outBundle+keyOffset; 80050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru item=ds->readUInt32(p[i]); 80350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_swapResource(ds, inBundle, outBundle, item, itemKey, pTempTable, pErrorCode); 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "ures_swapResource(table res=%08x)[%d].recurse(%08x) failed\n", 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res, i, item); 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 81150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pTempTable->majorFormatVersion>1 || ds->inCharset==ds->outCharset) { 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* no need to sort, just swap the offset/value arrays */ 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pKey16!=NULL) { 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, pKey16, count*2, qKey16, pErrorCode); 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, p, count*4, q, pErrorCode); 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap key offsets and items as one array */ 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, pKey32, count*2*4, qKey32, pErrorCode); 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We need to sort tables by outCharset key strings because they 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * sort differently for different charset families. 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * ures_swap() already set pTempTable->keyChars appropriately. 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * First we set up a temporary table with the key indexes and 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * sorting indexes and sort that. 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Then we permutate and copy/swap the actual values. 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pKey16!=NULL) { 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pTempTable->rows[i].keyIndex=ds->readUInt16(pKey16[i]); 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pTempTable->rows[i].sortIndex=i; 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pTempTable->rows[i].keyIndex=udata_readInt32(ds, pKey32[i]); 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pTempTable->rows[i].sortIndex=i; 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_sortArray(pTempTable->rows, count, sizeof(Row), 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_compareRows, pTempTable->keyChars, 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, pErrorCode); 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "ures_swapResource(table res=%08x).uprv_sortArray(%d items) failed\n", 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res, count); 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * copy/swap/permutate items 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If we swap in-place, then the permutation must use another 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * temporary array (pTempTable->resort) 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * before the results are copied to the outBundle. 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* keys */ 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pKey16!=NULL) { 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t *rKey16; 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pKey16!=qKey16) { 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rKey16=qKey16; 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rKey16=(uint16_t *)pTempTable->resort; 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldIndex=pTempTable->rows[i].sortIndex; 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, pKey16+oldIndex, 2, rKey16+i, pErrorCode); 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(qKey16!=rKey16) { 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(qKey16, rKey16, 2*count); 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t *rKey32; 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pKey32!=qKey32) { 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rKey32=qKey32; 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rKey32=pTempTable->resort; 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldIndex=pTempTable->rows[i].sortIndex; 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, pKey32+oldIndex, 4, rKey32+i, pErrorCode); 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(qKey32!=rKey32) { 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(qKey32, rKey32, 4*count); 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* resources */ 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource *r; 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(p!=q) { 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru r=q; 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru r=(Resource *)pTempTable->resort; 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldIndex=pTempTable->rows[i].sortIndex; 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, p+oldIndex, 4, r+i, pErrorCode); 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(q!=r) { 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(q, r, 4*count); 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_ARRAY: 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource item; 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i; 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=udata_readInt32(ds, (int32_t)*p); 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap length */ 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, p++, 4, q++, pErrorCode); 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* recurse */ 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru item=ds->readUInt32(p[i]); 92350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_swapResource(ds, inBundle, outBundle, item, NULL, pTempTable, pErrorCode); 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "ures_swapResource(array res=%08x)[%d].recurse(%08x) failed\n", 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res, i, item); 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap items */ 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, p, 4*count, q, pErrorCode); 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_INT_VECTOR: 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=udata_readInt32(ds, (int32_t)*p); 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap length and each integer */ 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, p, 4*(1+count), q, pErrorCode); 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* also catches RES_BOGUS */ 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruures_swap(const UDataSwapper *ds, 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UDataInfo *pInfo; 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const Resource *inBundle; 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource rootRes; 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t headerSize, maxTableLength; 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Row rows[STACK_ROW_CAPACITY]; 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t resort[STACK_ROW_CAPACITY]; 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TempTable tempTable; 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 96050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *inIndexes; 96150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* the following integers count Resource item offsets (4 bytes each), not bytes */ 96350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t bundleLength, indexLength, keysBottom, keysTop, resBottom, top; 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* udata_swapDataHeader checks the arguments */ 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode); 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* check data format and format version */ 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo=(const UDataInfo *)((const char *)inData+4); 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!( 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[0]==0x52 && /* dataFormat="ResB" */ 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[1]==0x65 && 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[2]==0x73 && 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[3]==0x42 && 97850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ((pInfo->formatVersion[0]==1 && pInfo->formatVersion[1]>=1) || /* formatVersion 1.1+ or 2.x */ 97950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pInfo->formatVersion[0]==2) 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru )) { 98150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_printError(ds, "ures_swap(): data format %02x.%02x.%02x.%02x (format version %02x.%02x) is not a resource bundle\n", 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[0], pInfo->dataFormat[1], 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[2], pInfo->dataFormat[3], 98450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pInfo->formatVersion[0], pInfo->formatVersion[1]); 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 98850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho tempTable.majorFormatVersion=pInfo->formatVersion[0]; 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* a resource bundle must contain at least one resource item */ 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length<0) { 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bundleLength=-1; 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bundleLength=(length-headerSize)/4; 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* formatVersion 1.1 must have a root item and at least 5 indexes */ 99750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(bundleLength<(1+5)) { 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "ures_swap(): too few bytes (%d after header) for a resource bundle\n", 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length-headerSize); 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inBundle=(const Resource *)((const char *)inData+headerSize); 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rootRes=ds->readUInt32(*inBundle); 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 100850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* formatVersion 1.1 adds the indexes[] array */ 100950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho inIndexes=(const int32_t *)(inBundle+1); 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 101150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho indexLength=udata_readInt32(ds, inIndexes[URES_INDEX_LENGTH])&0xff; 101250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexLength<=URES_INDEX_MAX_TABLE_LENGTH) { 101350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_printError(ds, "ures_swap(): too few indexes for a 1.1+ resource bundle\n"); 101450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 101550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 101650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 101750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho keysBottom=1+indexLength; 101850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho keysTop=udata_readInt32(ds, inIndexes[URES_INDEX_KEYS_TOP]); 101950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexLength>URES_INDEX_16BIT_TOP) { 102050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resBottom=udata_readInt32(ds, inIndexes[URES_INDEX_16BIT_TOP]); 102150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 102250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resBottom=keysTop; 102350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 102450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho top=udata_readInt32(ds, inIndexes[URES_INDEX_BUNDLE_TOP]); 102550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho maxTableLength=udata_readInt32(ds, inIndexes[URES_INDEX_MAX_TABLE_LENGTH]); 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 102750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(0<=bundleLength && bundleLength<top) { 102850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_printError(ds, "ures_swap(): resource top %d exceeds bundle length %d\n", 102950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho top, bundleLength); 103050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 103150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 103250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 103350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(keysTop>(1+indexLength)) { 103450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho tempTable.localKeyLimit=keysTop<<2; 103550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 103650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho tempTable.localKeyLimit=0; 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length>=0) { 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource *outBundle=(Resource *)((char *)outData+headerSize); 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 104250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* track which resources we have already swapped */ 104350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t stackResFlags[STACK_ROW_CAPACITY]; 104450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t resFlagsLength; 104550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 104650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 104750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * We need one bit per 4 resource bundle bytes so that we can track 104850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * every possible Resource for whether we have swapped it already. 104950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Multiple Resource words can refer to the same bundle offsets 105050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * for sharing identical values. 105150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * We could optimize this by allocating only for locations above 105250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * where Resource values are stored (above keys & strings). 105350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 105450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resFlagsLength=(length+31)>>5; /* number of bytes needed */ 105550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resFlagsLength=(resFlagsLength+3)&~3; /* multiple of 4 bytes for uint32_t */ 105650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(resFlagsLength<=sizeof(stackResFlags)) { 105750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho tempTable.resFlags=stackResFlags; 105850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 105950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho tempTable.resFlags=(uint32_t *)uprv_malloc(resFlagsLength); 106050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(tempTable.resFlags==NULL) { 106150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_printError(ds, "ures_swap(): unable to allocate memory for tracking resources\n"); 106250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 106350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 106450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 106550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 106650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memset(tempTable.resFlags, 0, resFlagsLength); 106750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy the bundle for binary and inaccessible data */ 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(inData!=outData) { 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(outBundle, inBundle, 4*top); 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap the key strings, but not the padding bytes (0xaa) after the last string and its NUL */ 107450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_swapInvStringBlock(ds, inBundle+keysBottom, 4*(keysTop-keysBottom), 107550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho outBundle+keysBottom, pErrorCode); 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 107750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_printError(ds, "ures_swap().udata_swapInvStringBlock(keys[%d]) failed\n", 4*(keysTop-keysBottom)); 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 108150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* swap the 16-bit units (strings, table16, array16) */ 108250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(keysTop<resBottom) { 108350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ds->swapArray16(ds, inBundle+keysTop, (resBottom-keysTop)*4, outBundle+keysTop, pErrorCode); 108450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_FAILURE(*pErrorCode)) { 108550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_printError(ds, "ures_swap().swapArray16(16-bit units[%d]) failed\n", 2*(resBottom-keysTop)); 108650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 108750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 108850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 108950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* allocate the temporary table for sorting resource tables */ 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tempTable.keyChars=(const char *)outBundle; /* sort by outCharset */ 109250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(tempTable.majorFormatVersion>1 || maxTableLength<=STACK_ROW_CAPACITY) { 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tempTable.rows=rows; 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tempTable.resort=resort; 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tempTable.rows=(Row *)uprv_malloc(maxTableLength*sizeof(Row)+maxTableLength*4); 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tempTable.rows==NULL) { 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "ures_swap(): unable to allocate memory for sorting tables (max length: %d)\n", 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxTableLength); 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 110150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(tempTable.resFlags!=stackResFlags) { 110250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(tempTable.resFlags); 110350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tempTable.resort=(int32_t *)(tempTable.rows+maxTableLength); 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap the resources */ 111050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_swapResource(ds, inBundle, outBundle, rootRes, NULL, &tempTable, pErrorCode); 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "ures_swapResource(root res=%08x) failed\n", 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rootRes); 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tempTable.rows!=rows) { 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(tempTable.rows); 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 111950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(tempTable.resFlags!=stackResFlags) { 112050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(tempTable.resFlags); 112150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap the root resource and indexes */ 112450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ds->swapArray32(ds, inBundle, keysBottom*4, outBundle, pErrorCode); 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return headerSize+4*top; 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1129