164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// Copyright (C) 2016 and later: Unicode, Inc. and others. 264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 58de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert* Copyright (C) 1999-2016, International Business Machines Corporation 6fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius* and others. All Rights Reserved. 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer* file name: uresdata.cpp 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" 25103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/utf16.h" 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 28535fd3b470529ba3c4a1d847539e71e4aabf4900Markus Scherer#include "resource.h" 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uarrsort.h" 3024d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer#include "uassert.h" 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucol_swp.h" 3224d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer#include "udataswp.h" 3350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "uinvchar.h" 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uresdata.h" 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uresimp.h" 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Resource access helpers 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* get a const char* pointer to the key with the keyOffset byte offset from pRoot */ 4250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define RES_GET_KEY16(pResData, keyOffset) \ 4350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ((keyOffset)<(pResData)->localKeyLimit ? \ 4450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (const char *)(pResData)->pRoot+(keyOffset) : \ 4550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (pResData)->poolBundleKeys+(keyOffset)-(pResData)->localKeyLimit) 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 4750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define RES_GET_KEY32(pResData, keyOffset) \ 4850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ((keyOffset)>=0 ? \ 4950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (const char *)(pResData)->pRoot+(keyOffset) : \ 5050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (pResData)->poolBundleKeys+((keyOffset)&0x7fffffff)) 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 5250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define URESDATA_ITEM_NOT_FOUND -1 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 5450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* empty resources, returned when the resource offset is 0 */ 5550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const uint16_t gEmpty16=0; 56103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 57103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const struct { 58103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t length; 59103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t res; 60103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} gEmpty32={ 0, 0 }; 61103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 6250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const struct { 6350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 6450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UChar nul; 6550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UChar pad; 6650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} gEmptyString={ 0, 0, 0 }; 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 6950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * All the type-access functions assume that 7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * the resource is of the expected type. 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 7350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t 7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho_res_findTableItem(const ResourceData *pResData, const uint16_t *keyOffsets, int32_t length, 7550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *key, const char **realKey) { 7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *tableKey; 7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t mid, start, limit; 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int result; 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 8050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* do a binary search for the key */ 8150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho start=0; 8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho limit=length; 8350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while(start<limit) { 8450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho mid = (start + limit) / 2; 8550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho tableKey = RES_GET_KEY16(pResData, keyOffsets[mid]); 8650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (pResData->useNativeStrcmp) { 8750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho result = uprv_strcmp(key, tableKey); 8850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 8950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho result = uprv_compareInvCharsAsAscii(key, tableKey); 9050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 9150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (result < 0) { 9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho limit = mid; 9350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (result > 0) { 9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho start = mid + 1; 9550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* We found it! */ 9750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *realKey=tableKey; 9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return mid; 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return URESDATA_ITEM_NOT_FOUND; /* not found or table is empty. */ 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 10450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t 10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho_res_findTable32Item(const ResourceData *pResData, const int32_t *keyOffsets, int32_t length, 10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *key, const char **realKey) { 10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *tableKey; 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t mid, start, limit; 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int result; 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* do a binary search for the key */ 11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho start=0; 11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho limit=length; 11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while(start<limit) { 11550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho mid = (start + limit) / 2; 11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho tableKey = RES_GET_KEY32(pResData, keyOffsets[mid]); 11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (pResData->useNativeStrcmp) { 11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho result = uprv_strcmp(key, tableKey); 11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho result = uprv_compareInvCharsAsAscii(key, tableKey); 12150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (result < 0) { 12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho limit = mid; 12450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (result > 0) { 12550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho start = mid + 1; 12650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 12750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* We found it! */ 12850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *realKey=tableKey; 12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return mid; 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 13250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return URESDATA_ITEM_NOT_FOUND; /* not found or table is empty. */ 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* helper for res_load() ---------------------------------------------------- */ 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool U_CALLCONV 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruisAcceptable(void *context, 13924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer const char * /*type*/, const char * /*name*/, 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UDataInfo *pInfo) { 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(context, pInfo->formatVersion, 4); 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (UBool)( 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->size>=20 && 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->isBigEndian==U_IS_BIG_ENDIAN && 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->charsetFamily==U_CHARSET_FAMILY && 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->sizeofUChar==U_SIZEOF_UCHAR && 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[0]==0x52 && /* dataFormat="ResB" */ 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[1]==0x65 && 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[2]==0x73 && 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[3]==0x42 && 151c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert (1<=pInfo->formatVersion[0] && pInfo->formatVersion[0]<=3)); 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* semi-public functions ---------------------------------------------------- */ 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 15650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 15750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_init(ResourceData *pResData, 15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UVersionInfo formatVersion, const void *inBytes, int32_t length, 15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *errorCode) { 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResType rootType; 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* get the root resource */ 16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->pRoot=(const int32_t *)inBytes; 16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->rootRes=(Resource)*pResData->pRoot; 16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->p16BitUnits=&gEmpty16; 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* formatVersion 1.1 must have a root item and at least 5 indexes */ 16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(length>=0 && (length/4)<((formatVersion[0]==1 && formatVersion[1]==0) ? 1 : 1+5)) { 16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *errorCode=U_INVALID_FORMAT_ERROR; 17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_unload(pResData); 17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* currently, we accept only resources that have a Table as their roots */ 17554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius rootType=(UResType)RES_GET_TYPE(pResData->rootRes); 17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(!URES_IS_TABLE(rootType)) { 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *errorCode=U_INVALID_FORMAT_ERROR; 17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_unload(pResData); 17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(formatVersion[0]==1 && formatVersion[1]==0) { 18350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->localKeyLimit=0x10000; /* greater than any 16-bit key string offset */ 18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* bundles with formatVersion 1.1 and later contain an indexes[] array */ 18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *indexes=pResData->pRoot+1; 18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t indexLength=indexes[URES_INDEX_LENGTH]&0xff; 18850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexLength<=URES_INDEX_MAX_TABLE_LENGTH) { 18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *errorCode=U_INVALID_FORMAT_ERROR; 19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_unload(pResData); 19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 19350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if( length>=0 && 19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (length<((1+indexLength)<<2) || 19550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length<(indexes[URES_INDEX_BUNDLE_TOP]<<2)) 19650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ) { 19750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *errorCode=U_INVALID_FORMAT_ERROR; 19850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_unload(pResData); 19950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 20050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 20150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexes[URES_INDEX_KEYS_TOP]>(1+indexLength)) { 20250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->localKeyLimit=indexes[URES_INDEX_KEYS_TOP]<<2; 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 204c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(formatVersion[0]>=3) { 205c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert // In formatVersion 1, the indexLength took up this whole int. 206c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert // In version 2, bits 31..8 were reserved and always 0. 207c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert // In version 3, they contain bits 23..0 of the poolStringIndexLimit. 208c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert // Bits 27..24 are in indexes[URES_INDEX_ATTRIBUTES] bits 15..12. 209c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert pResData->poolStringIndexLimit=(int32_t)((uint32_t)indexes[URES_INDEX_LENGTH]>>8); 210c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 21150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexLength>URES_INDEX_ATTRIBUTES) { 21250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t att=indexes[URES_INDEX_ATTRIBUTES]; 21350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->noFallback=(UBool)(att&URES_ATT_NO_FALLBACK); 21450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->isPoolBundle=(UBool)((att&URES_ATT_IS_POOL_BUNDLE)!=0); 21550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->usesPoolBundle=(UBool)((att&URES_ATT_USES_POOL_BUNDLE)!=0); 216c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert pResData->poolStringIndexLimit|=(att&0xf000)<<12; // bits 15..12 -> 27..24 217c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert pResData->poolStringIndex16Limit=(int32_t)((uint32_t)att>>16); 21850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 21950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if((pResData->isPoolBundle || pResData->usesPoolBundle) && indexLength<=URES_INDEX_POOL_CHECKSUM) { 22050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *errorCode=U_INVALID_FORMAT_ERROR; 22150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_unload(pResData); 22250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 22350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if( indexLength>URES_INDEX_16BIT_TOP && 22550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho indexes[URES_INDEX_16BIT_TOP]>indexes[URES_INDEX_KEYS_TOP] 22650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ) { 22750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->p16BitUnits=(const uint16_t *)(pResData->pRoot+indexes[URES_INDEX_KEYS_TOP]); 22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 23050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 23150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(formatVersion[0]==1 || U_CHARSET_FAMILY==U_ASCII_FAMILY) { 23250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 23350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * formatVersion 1: compare key strings in native-charset order 23450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * formatVersion 2 and up: compare key strings in ASCII order 23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 23650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->useNativeStrcmp=TRUE; 23750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 23850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 23950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 24050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI void U_EXPORT2 24150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_read(ResourceData *pResData, 24250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UDataInfo *pInfo, const void *inBytes, int32_t length, 24350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *errorCode) { 24450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UVersionInfo formatVersion; 24550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 24650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memset(pResData, 0, sizeof(ResourceData)); 24750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_FAILURE(*errorCode)) { 24850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 24950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 25050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(!isAcceptable(formatVersion, NULL, NULL, pInfo)) { 25150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *errorCode=U_INVALID_FORMAT_ERROR; 25250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 25350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 25450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_init(pResData, formatVersion, inBytes, length, errorCode); 25550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 25650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 25750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CFUNC void 25850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_load(ResourceData *pResData, 25950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *path, const char *name, UErrorCode *errorCode) { 26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UVersionInfo formatVersion; 26150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 26250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memset(pResData, 0, sizeof(ResourceData)); 26350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 26450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* load the ResourceBundle file */ 26550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pResData->data=udata_openChoice(path, "res", name, isAcceptable, formatVersion, errorCode); 26650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_FAILURE(*errorCode)) { 26750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* get its memory and initialize *pResData */ 27150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_init(pResData, formatVersion, udata_getMemory(pResData->data), -1, errorCode); 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC void 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querures_unload(ResourceData *pResData) { 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pResData->data!=NULL) { 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_close(pResData->data); 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pResData->data=NULL; 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 28250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const int8_t gPublicTypes[URES_LIMIT] = { 28350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_STRING, 28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_BINARY, 28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_TABLE, 28650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_ALIAS, 28750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 28850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_TABLE, /* URES_TABLE32 */ 28950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_TABLE, /* URES_TABLE16 */ 29050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_STRING, /* URES_STRING_V2 */ 29150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_INT, 29250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 29350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_ARRAY, 29450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_ARRAY, /* URES_ARRAY16 */ 29550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_NONE, 29650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_NONE, 29750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 29850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_NONE, 29950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_NONE, 30050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_INT_VECTOR, 30150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho URES_NONE 30250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 30350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 30450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI UResType U_EXPORT2 30550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getPublicType(Resource res) { 30650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return (UResType)gPublicTypes[RES_GET_TYPE(res)]; 30750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 30850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 30950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI const UChar * U_EXPORT2 31050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getString(const ResourceData *pResData, Resource res, int32_t *pLength) { 31150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *p; 31250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(res); 31350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 31450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(RES_GET_TYPE(res)==URES_STRING_V2) { 31550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t first; 31624d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if((int32_t)offset<pResData->poolStringIndexLimit) { 317c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert p=(const UChar *)pResData->poolBundleStrings+offset; 318c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } else { 319c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert p=(const UChar *)pResData->p16BitUnits+(offset-pResData->poolStringIndexLimit); 320c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 32150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho first=*p; 32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(!U16_IS_TRAIL(first)) { 32350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=u_strlen(p); 32450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if(first<0xdfef) { 32550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=first&0x3ff; 32650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ++p; 32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if(first<0xdfff) { 32850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=((first-0xdfef)<<16)|p[1]; 32950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p+=2; 33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 33150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=((int32_t)p[1]<<16)|p[2]; 33250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p+=3; 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if(res==offset) /* RES_GET_TYPE(res)==URES_STRING */ { 33550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *p32= res==0 ? &gEmptyString.length : pResData->pRoot+res; 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 34824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherernamespace { 34924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 35024d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer/** 35124d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer * CLDR string value (three empty-set symbols)=={2205, 2205, 2205} 35224d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer * prevents fallback to the parent bundle. 35324d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer * TODO: combine with other code that handles this marker, use EMPTY_SET constant. 35424d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer * TODO: maybe move to uresbund.cpp? 35524d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer */ 35624d55684271a8d3118a71a3eb4769a0431dc9d54Markus SchererUBool isNoInheritanceMarker(const ResourceData *pResData, Resource res) { 35724d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer uint32_t offset=RES_GET_OFFSET(res); 35824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if (offset == 0) { 35924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer // empty string 36024d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } else if (res == offset) { 36124d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer const int32_t *p32=pResData->pRoot+res; 36224d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer int32_t length=*p32; 36324d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer const UChar *p=(const UChar *)p32; 36424d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return length == 3 && p[2] == 0x2205 && p[3] == 0x2205 && p[4] == 0x2205; 36524d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } else if (RES_GET_TYPE(res) == URES_STRING_V2) { 36624d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer const UChar *p; 36724d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if((int32_t)offset<pResData->poolStringIndexLimit) { 36824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer p=(const UChar *)pResData->poolBundleStrings+offset; 36924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } else { 37024d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer p=(const UChar *)pResData->p16BitUnits+(offset-pResData->poolStringIndexLimit); 37124d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 37224d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer int32_t first=*p; 37324d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if (first == 0x2205) { // implicit length 37424d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return p[1] == 0x2205 && p[2] == 0x2205 && p[3] == 0; 37524d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } else if (first == 0xdc03) { // explicit length 3 (should not occur) 37624d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return p[1] == 0x2205 && p[2] == 0x2205 && p[3] == 0x2205; 37724d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } else { 37824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer // Assume that the string has not been stored with more length units than necessary. 37924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return FALSE; 38024d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 38124d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 38224d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return FALSE; 38324d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer} 38424d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 38564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubertint32_t getStringArray(const ResourceData *pResData, const icu::ResourceArray &array, 38664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert icu::UnicodeString *dest, int32_t capacity, 38764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert UErrorCode &errorCode) { 38864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(U_FAILURE(errorCode)) { 38964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return 0; 39064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 39164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(dest == NULL ? capacity != 0 : capacity < 0) { 39264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert errorCode = U_ILLEGAL_ARGUMENT_ERROR; 39364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return 0; 39464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 39564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert int32_t length = array.getSize(); 39664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(length == 0) { 39764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return 0; 39864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 39964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(length > capacity) { 40064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert errorCode = U_BUFFER_OVERFLOW_ERROR; 40164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return length; 40264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 40364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert for(int32_t i = 0; i < length; ++i) { 40464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert int32_t sLength; 40564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert const UChar *s = res_getString(pResData, array.internalGetResource(pResData, i), &sLength); 40664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(s == NULL) { 40764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert errorCode = U_RESOURCE_TYPE_MISMATCH; 40864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return 0; 40964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 41064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert dest[i].setTo(TRUE, s, sLength); 41164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 41264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return length; 41364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert} 41464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 41524d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer} // namespace 41624d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 41750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI const UChar * U_EXPORT2 41850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getAlias(const ResourceData *pResData, Resource res, int32_t *pLength) { 41950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *p; 42050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(res); 42150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 42250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(RES_GET_TYPE(res)==URES_ALIAS) { 42350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *p32= offset==0 ? &gEmptyString.length : pResData->pRoot+offset; 42450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p32++; 42550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=(const UChar *)p32; 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 42750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=NULL; 42850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=0; 42950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 43050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pLength) { 43150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pLength=length; 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 43350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return p; 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 43650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI const uint8_t * U_EXPORT2 43750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getBinary(const ResourceData *pResData, Resource res, int32_t *pLength) { 43850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const uint8_t *p; 43950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(res); 44050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 44150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(RES_GET_TYPE(res)==URES_BINARY) { 442103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const int32_t *p32= offset==0 ? (const int32_t*)&gEmpty32 : pResData->pRoot+offset; 44350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p32++; 44450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=(const uint8_t *)p32; 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 44650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=NULL; 44750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=0; 44850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 44950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pLength) { 45050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pLength=length; 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 45250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return p; 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 45650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI const int32_t * U_EXPORT2 45750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getIntVector(const ResourceData *pResData, Resource res, int32_t *pLength) { 45850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *p; 45950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(res); 46050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 46150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(RES_GET_TYPE(res)==URES_INT_VECTOR) { 462103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius p= offset==0 ? (const int32_t *)&gEmpty32 : pResData->pRoot+offset; 46350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p++; 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 46550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho p=NULL; 46650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=0; 46750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 46850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pLength) { 46950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pLength=length; 47050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 47150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return p; 47250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 47350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 47450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI int32_t U_EXPORT2 47550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_countArrayItems(const ResourceData *pResData, Resource res) { 47650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(res); 47750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch(RES_GET_TYPE(res)) { 47850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_STRING: 47950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_STRING_V2: 48050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_BINARY: 48150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ALIAS: 48250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_INT: 48350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_INT_VECTOR: 48450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 1; 48550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ARRAY: 48650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE32: 48750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return offset==0 ? 0 : *(pResData->pRoot+offset); 48850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE: 48950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return offset==0 ? 0 : *((const uint16_t *)(pResData->pRoot+offset)); 49050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ARRAY16: 49150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE16: 49250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return pResData->p16BitUnits[offset]; 49350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 49450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 49824d55684271a8d3118a71a3eb4769a0431dc9d54Markus SchererU_NAMESPACE_BEGIN 49924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 50024d55684271a8d3118a71a3eb4769a0431dc9d54Markus SchererResourceDataValue::~ResourceDataValue() {} 50124d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 50224d55684271a8d3118a71a3eb4769a0431dc9d54Markus SchererUResType ResourceDataValue::getType() const { 50324d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return res_getPublicType(res); 50424d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer} 50524d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 50624d55684271a8d3118a71a3eb4769a0431dc9d54Markus Schererconst UChar *ResourceDataValue::getString(int32_t &length, UErrorCode &errorCode) const { 50724d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(U_FAILURE(errorCode)) { 50824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return NULL; 50924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 51024d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer const UChar *s = res_getString(pResData, res, &length); 51124d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(s == NULL) { 51224d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer errorCode = U_RESOURCE_TYPE_MISMATCH; 51324d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 51424d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return s; 51524d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer} 51624d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 51724d55684271a8d3118a71a3eb4769a0431dc9d54Markus Schererconst UChar *ResourceDataValue::getAliasString(int32_t &length, UErrorCode &errorCode) const { 51824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(U_FAILURE(errorCode)) { 51924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return NULL; 52024d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 52124d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer const UChar *s = res_getAlias(pResData, res, &length); 52224d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(s == NULL) { 52324d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer errorCode = U_RESOURCE_TYPE_MISMATCH; 52424d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 52524d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return s; 52624d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer} 52724d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 52824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Schererint32_t ResourceDataValue::getInt(UErrorCode &errorCode) const { 52924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(U_FAILURE(errorCode)) { 53024d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return 0; 53124d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 53224d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(RES_GET_TYPE(res) != URES_INT) { 53324d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer errorCode = U_RESOURCE_TYPE_MISMATCH; 53424d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 53524d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return RES_GET_INT(res); 53624d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer} 53724d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 53824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Schereruint32_t ResourceDataValue::getUInt(UErrorCode &errorCode) const { 53924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(U_FAILURE(errorCode)) { 54024d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return 0; 54124d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 54224d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(RES_GET_TYPE(res) != URES_INT) { 54324d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer errorCode = U_RESOURCE_TYPE_MISMATCH; 54424d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 54524d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return RES_GET_UINT(res); 54624d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer} 54724d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 54824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Schererconst int32_t *ResourceDataValue::getIntVector(int32_t &length, UErrorCode &errorCode) const { 54924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(U_FAILURE(errorCode)) { 55024d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return NULL; 55124d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 55224d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer const int32_t *iv = res_getIntVector(pResData, res, &length); 55324d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(iv == NULL) { 55424d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer errorCode = U_RESOURCE_TYPE_MISMATCH; 55524d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 55624d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return iv; 55724d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer} 55824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 55924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Schererconst uint8_t *ResourceDataValue::getBinary(int32_t &length, UErrorCode &errorCode) const { 56024d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(U_FAILURE(errorCode)) { 56124d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return NULL; 56224d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 56324d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer const uint8_t *b = res_getBinary(pResData, res, &length); 56424d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(b == NULL) { 56524d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer errorCode = U_RESOURCE_TYPE_MISMATCH; 56624d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 56724d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return b; 56824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer} 56924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 57064339d36f8bd4db5025fe2988eda22b491a9219cFredrik RoubertResourceArray ResourceDataValue::getArray(UErrorCode &errorCode) const { 57164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(U_FAILURE(errorCode)) { 57264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return ResourceArray(); 57364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 57464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert const uint16_t *items16 = NULL; 57564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert const Resource *items32 = NULL; 57664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert uint32_t offset=RES_GET_OFFSET(res); 57764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert int32_t length = 0; 57864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert switch(RES_GET_TYPE(res)) { 57964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert case URES_ARRAY: 58064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if (offset!=0) { // empty if offset==0 58164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert items32 = (const Resource *)pResData->pRoot+offset; 58264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert length = *items32++; 58364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 58464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert break; 58564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert case URES_ARRAY16: 58664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert items16 = pResData->p16BitUnits+offset; 58764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert length = *items16++; 58864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert break; 58964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert default: 59064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert errorCode = U_RESOURCE_TYPE_MISMATCH; 59164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return ResourceArray(); 59264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 59364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return ResourceArray(items16, items32, length); 59464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert} 59564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 59664339d36f8bd4db5025fe2988eda22b491a9219cFredrik RoubertResourceTable ResourceDataValue::getTable(UErrorCode &errorCode) const { 59764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(U_FAILURE(errorCode)) { 59864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return ResourceTable(); 59964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 60064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert const uint16_t *keys16 = NULL; 60164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert const int32_t *keys32 = NULL; 60264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert const uint16_t *items16 = NULL; 60364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert const Resource *items32 = NULL; 60464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert uint32_t offset = RES_GET_OFFSET(res); 60564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert int32_t length = 0; 60664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert switch(RES_GET_TYPE(res)) { 60764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert case URES_TABLE: 60864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if (offset != 0) { // empty if offset==0 60964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert keys16 = (const uint16_t *)(pResData->pRoot+offset); 61064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert length = *keys16++; 61164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert items32 = (const Resource *)(keys16+length+(~length&1)); 61264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 61364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert break; 61464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert case URES_TABLE16: 61564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert keys16 = pResData->p16BitUnits+offset; 61664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert length = *keys16++; 61764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert items16 = keys16 + length; 61864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert break; 61964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert case URES_TABLE32: 62064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if (offset != 0) { // empty if offset==0 62164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert keys32 = pResData->pRoot+offset; 62264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert length = *keys32++; 62364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert items32 = (const Resource *)keys32 + length; 62464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 62564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert break; 62664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert default: 62764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert errorCode = U_RESOURCE_TYPE_MISMATCH; 62864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return ResourceTable(); 62964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 63064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return ResourceTable(keys16, keys32, items16, items32, length); 63164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert} 63264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 63364339d36f8bd4db5025fe2988eda22b491a9219cFredrik RoubertUBool ResourceDataValue::isNoInheritanceMarker() const { 63464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return ::isNoInheritanceMarker(pResData, res); 63564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert} 63664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 63764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubertint32_t ResourceDataValue::getStringArray(UnicodeString *dest, int32_t capacity, 63864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert UErrorCode &errorCode) const { 63964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return ::getStringArray(pResData, getArray(errorCode), dest, capacity, errorCode); 64064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert} 64164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 64264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubertint32_t ResourceDataValue::getStringArrayOrStringAsArray(UnicodeString *dest, int32_t capacity, 64364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert UErrorCode &errorCode) const { 64464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(URES_IS_ARRAY(res)) { 64564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return ::getStringArray(pResData, getArray(errorCode), dest, capacity, errorCode); 64664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 64764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(U_FAILURE(errorCode)) { 64864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return 0; 64964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 65064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(dest == NULL ? capacity != 0 : capacity < 0) { 65164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert errorCode = U_ILLEGAL_ARGUMENT_ERROR; 65264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return 0; 65364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 65464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(capacity < 1) { 65564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert errorCode = U_BUFFER_OVERFLOW_ERROR; 65664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return 1; 65764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 65864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert int32_t sLength; 65964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert const UChar *s = res_getString(pResData, res, &sLength); 66064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(s != NULL) { 66164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert dest[0].setTo(TRUE, s, sLength); 66264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return 1; 66364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 66464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert errorCode = U_RESOURCE_TYPE_MISMATCH; 66564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return 0; 66664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert} 66764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 66864339d36f8bd4db5025fe2988eda22b491a9219cFredrik RoubertUnicodeString ResourceDataValue::getStringOrFirstOfArray(UErrorCode &errorCode) const { 66964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert UnicodeString us; 67064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(U_FAILURE(errorCode)) { 67164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return us; 67264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 67364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert int32_t sLength; 67464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert const UChar *s = res_getString(pResData, res, &sLength); 67564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(s != NULL) { 67664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert us.setTo(TRUE, s, sLength); 67764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return us; 67864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 67964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert ResourceArray array = getArray(errorCode); 68064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(U_FAILURE(errorCode)) { 68164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return us; 68264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 68364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(array.getSize() > 0) { 68464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert s = res_getString(pResData, array.internalGetResource(pResData, 0), &sLength); 68564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(s != NULL) { 68664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert us.setTo(TRUE, s, sLength); 68764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return us; 68864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 68964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } 69064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert errorCode = U_RESOURCE_TYPE_MISMATCH; 69164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return us; 69264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert} 69364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert 69424d55684271a8d3118a71a3eb4769a0431dc9d54Markus SchererU_NAMESPACE_END 69524d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 696c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertstatic Resource 697c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik RoubertmakeResourceFrom16(const ResourceData *pResData, int32_t res16) { 698c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if(res16<pResData->poolStringIndex16Limit) { 699c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert // Pool string, nothing to do. 700c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } else { 701c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert // Local string, adjust the 16-bit offset to a regular one, 702c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert // with a larger pool string index limit. 703c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert res16=res16-pResData->poolStringIndex16Limit+pResData->poolStringIndexLimit; 704c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 705c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return URES_MAKE_RESOURCE(URES_STRING_V2, res16); 706c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert} 707c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert 70850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI Resource U_EXPORT2 70950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getTableItemByKey(const ResourceData *pResData, Resource table, 71050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t *indexR, const char **key) { 71150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(table); 71250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 71350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t idx; 71450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(key == NULL || *key == NULL) { 71550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return RES_BOGUS; 71650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 71750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch(RES_GET_TYPE(table)) { 71850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE: { 719103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (offset!=0) { /* empty if offset==0 */ 720103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const uint16_t *p= (const uint16_t *)(pResData->pRoot+offset); 721103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius length=*p++; 722103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *indexR=idx=_res_findTableItem(pResData, p, length, *key, key); 723103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(idx>=0) { 724103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const Resource *p32=(const Resource *)(p+length+(~length&1)); 725103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return p32[idx]; 726103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 72850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 72950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 73050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE16: { 73150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const uint16_t *p=pResData->p16BitUnits+offset; 73250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p++; 73350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *indexR=idx=_res_findTableItem(pResData, p, length, *key, key); 73450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(idx>=0) { 735c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return makeResourceFrom16(pResData, p[length+idx]); 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 73750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 73850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 73950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE32: { 740103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (offset!=0) { /* empty if offset==0 */ 741103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const int32_t *p= pResData->pRoot+offset; 742103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius length=*p++; 743103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *indexR=idx=_res_findTable32Item(pResData, p, length, *key, key); 744103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(idx>=0) { 745103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return (Resource)p[length+idx]; 746103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 74850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 74950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 75050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 75150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 75250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 75350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return RES_BOGUS; 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 75650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI Resource U_EXPORT2 75750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getTableItemByIndex(const ResourceData *pResData, Resource table, 75850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t indexR, const char **key) { 75950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(table); 76050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length; 761103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(indexR>=0); /* to ensure the index is not negative */ 76250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch(RES_GET_TYPE(table)) { 76350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE: { 764103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (offset != 0) { /* empty if offset==0 */ 765103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const uint16_t *p= (const uint16_t *)(pResData->pRoot+offset); 766103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius length=*p++; 767103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(indexR<length) { 768103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const Resource *p32=(const Resource *)(p+length+(~length&1)); 769103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(key!=NULL) { 770103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *key=RES_GET_KEY16(pResData, p[indexR]); 771103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 772103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return p32[indexR]; 77350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 77450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 77550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 77650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 77750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE16: { 77850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const uint16_t *p=pResData->p16BitUnits+offset; 77950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho length=*p++; 78050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexR<length) { 78150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(key!=NULL) { 78250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *key=RES_GET_KEY16(pResData, p[indexR]); 78350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 784c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return makeResourceFrom16(pResData, p[length+indexR]); 78550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 78650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 78750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 78850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE32: { 789103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (offset != 0) { /* empty if offset==0 */ 790103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const int32_t *p= pResData->pRoot+offset; 791103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius length=*p++; 792103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(indexR<length) { 793103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(key!=NULL) { 794103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *key=RES_GET_KEY32(pResData, p[indexR]); 795103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 796103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return (Resource)p[length+indexR]; 79750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 79850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 79950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 80050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 80150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 80250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 80350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 80450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return RES_BOGUS; 80550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 80650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 80750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI Resource U_EXPORT2 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querures_getResource(const ResourceData *pResData, const char *key) { 80950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *realKey=key; 810b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t idx; 81150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return res_getTableItemByKey(pResData, pResData->rootRes, &idx, &realKey); 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 81424d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 81564339d36f8bd4db5025fe2988eda22b491a9219cFredrik RoubertUBool icu::ResourceTable::getKeyAndValue(int32_t i, 81664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert const char *&key, icu::ResourceValue &value) const { 81764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(0 <= i && i < length) { 81864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert icu::ResourceDataValue &rdValue = static_cast<icu::ResourceDataValue &>(value); 81924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if (keys16 != NULL) { 82064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert key = RES_GET_KEY16(rdValue.pResData, keys16[i]); 82124d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } else { 82264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert key = RES_GET_KEY32(rdValue.pResData, keys32[i]); 82324d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 82424d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer Resource res; 82524d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if (items16 != NULL) { 82664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert res = makeResourceFrom16(rdValue.pResData, items16[i]); 82724d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } else { 82824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer res = items32[i]; 82924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 83064339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert rdValue.setResource(res); 83164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return TRUE; 83224d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 83364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return FALSE; 83424d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer} 83524d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 83650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_CAPI Resource U_EXPORT2 83750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getArrayItem(const ResourceData *pResData, Resource array, int32_t indexR) { 83850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t offset=RES_GET_OFFSET(array); 839103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(indexR>=0); /* to ensure the index is not negative */ 84050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch(RES_GET_TYPE(array)) { 84150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ARRAY: { 842103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (offset!=0) { /* empty if offset==0 */ 843103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const int32_t *p= pResData->pRoot+offset; 844103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(indexR<*p) { 845103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return (Resource)p[1+indexR]; 846103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 84750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 84850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 84950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 85050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ARRAY16: { 85150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const uint16_t *p=pResData->p16BitUnits+offset; 85250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexR<*p) { 853c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return makeResourceFrom16(pResData, p[1+indexR]); 85450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 85550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 85650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 85750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 85850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 85950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 86050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return RES_BOGUS; 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 86364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubertuint32_t icu::ResourceArray::internalGetResource(const ResourceData *pResData, int32_t i) const { 86464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if (items16 != NULL) { 86564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return makeResourceFrom16(pResData, items16[i]); 86664339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert } else { 86764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return items32[i]; 86824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 86964339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert} 87024d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 87164339d36f8bd4db5025fe2988eda22b491a9219cFredrik RoubertUBool icu::ResourceArray::getValue(int32_t i, icu::ResourceValue &value) const { 87264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert if(0 <= i && i < length) { 87364339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert icu::ResourceDataValue &rdValue = static_cast<icu::ResourceDataValue &>(value); 87464339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert rdValue.setResource(internalGetResource(rdValue.pResData, i)); 87564339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return TRUE; 87624d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 87764339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert return FALSE; 87824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer} 87924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC Resource 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querures_findResource(const ResourceData *pResData, Resource r, char** path, const char** key) { 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *pathP = *path, *nextSepP = *path; 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *closeIndex = NULL; 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource t1 = r; 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource t2; 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t indexR = 0; 88754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UResType type = (UResType)RES_GET_TYPE(t1); 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if you come in with an empty path, you'll be getting back the same resource */ 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!uprv_strlen(pathP)) { 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return r; 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* one needs to have an aggregate resource in order to search in it */ 89550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(!URES_IS_CONTAINER(type)) { 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return RES_BOGUS; 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 89950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while(nextSepP && *pathP && t1 != RES_BOGUS && URES_IS_CONTAINER(type)) { 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Iteration stops if: the path has been consumed, we found a non-existing 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * resource (t1 == RES_BOGUS) or we found a scalar resource (including alias) 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nextSepP = uprv_strchr(pathP, RES_PATH_SEPARATOR); 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if there are more separators, terminate string 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and set path to the remaining part of the string 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(nextSepP != NULL) { 90824d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(nextSepP == pathP) { 90924d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer // Empty key string. 91024d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer return RES_BOGUS; 91124d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer } 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *nextSepP = 0; /* overwrite the separator with a NUL to terminate the key */ 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *path = nextSepP+1; 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *path = uprv_strchr(pathP, 0); 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if the resource is a table */ 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* try the key based access */ 92050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(URES_IS_TABLE(type)) { 92150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *key = pathP; 92250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho t2 = res_getTableItemByKey(pResData, t1, &indexR, key); 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(t2 == RES_BOGUS) { 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if we fail to get the resource by key, maybe we got an index */ 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexR = uprv_strtol(pathP, &closeIndex, 10); 92624d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(*closeIndex == 0) { 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if we indeed have an index, try to get the item by index */ 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t2 = res_getTableItemByIndex(pResData, t1, indexR, key); 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 93150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if(URES_IS_ARRAY(type)) { 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexR = uprv_strtol(pathP, &closeIndex, 10); 93324d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(*closeIndex == 0) { 93450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho t2 = res_getArrayItem(pResData, t1, indexR); 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t2 = RES_BOGUS; /* have an array, but don't have a valid index */ 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *key = NULL; 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { /* can't do much here, except setting t2 to bogus */ 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t2 = RES_BOGUS; 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru t1 = t2; 94354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius type = (UResType)RES_GET_TYPE(t1); 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* position pathP to next resource key/index */ 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pathP = *path; 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return t1; 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* resource bundle swapping ------------------------------------------------- */ 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Need to always enumerate the entire item tree, 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * track the lowest address of any item to use as the limit for char keys[], 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * track the highest address of any item to return the size of the data. 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We should have thought of storing those in the data... 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * It is possible to extend the data structure by putting additional values 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * in places that are inaccessible by ordinary enumeration of the item tree. 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * For example, additional integers could be stored at the beginning or 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * end of the key strings; this could be indicated by a minor version number, 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * and the data swapping would have to know about these values. 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * The data structure does not forbid keys to be shared, so we must swap 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * all keys once instead of each key when it is referenced. 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * These swapping functions assume that a resource bundle always has a length 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * that is a multiple of 4 bytes. 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Currently, this is trivially true because genrb writes bundle tree leaves 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * physically first, before their branches, so that the root table with its 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * array of resource items (uint32_t values) is always last. 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* definitions for table sorting ------------------------ */ 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * row of a temporary array 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * gets platform-endian key string indexes and sorting indexes; 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * after sorting this array by keys, the actual key/value arrays are permutated 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * according to the sorting indexes 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct Row { 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keyIndex, sortIndex; 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} Row; 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 98864339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubertstatic int32_t U_CALLCONV 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruures_compareRows(const void *context, const void *left, const void *right) { 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *keyChars=(const char *)context; 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (int32_t)uprv_strcmp(keyChars+((const Row *)left)->keyIndex, 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keyChars+((const Row *)right)->keyIndex); 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querutypedef struct TempTable { 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *keyChars; 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Row *rows; 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t *resort; 99950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t *resFlags; 100050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t localKeyLimit; 100150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint8_t majorFormatVersion; 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} TempTable; 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruenum { 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru STACK_ROW_CAPACITY=200 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 100850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* The table item key string is not locally available. */ 100950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char *const gUnknownKey=""; 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* resource table key for collation binaries: "%%CollationBin" */ 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const UChar gCollationBinKey[]={ 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x25, 0x25, 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0x42, 0x69, 0x6e, 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * swap one resource item 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruures_swapResource(const UDataSwapper *ds, 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const Resource *inBundle, Resource *outBundle, 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource res, /* caller swaps res itself */ 102650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *key, 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TempTable *pTempTable, 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const Resource *p; 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource *q; 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t offset, count; 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 103350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch(RES_GET_TYPE(res)) { 103450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE16: 103550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_STRING_V2: 103650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_INT: 103750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ARRAY16: 103850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* integer, or points to 16-bit units, nothing to do here */ 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 104050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 104150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* all other types use an offset to point to their data */ 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset=(int32_t)RES_GET_OFFSET(res); 104650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(offset==0) { 104750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* special offset indicating an empty item */ 104850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 104950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 105050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pTempTable->resFlags[offset>>5]&((uint32_t)1<<(offset&0x1f))) { 105150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* we already swapped this resource item */ 105250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 105350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 105450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* mark it as swapped now */ 105550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pTempTable->resFlags[offset>>5]|=((uint32_t)1<<(offset&0x1f)); 105650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 105750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p=inBundle+offset; 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru q=outBundle+offset; 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(RES_GET_TYPE(res)) { 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_ALIAS: 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* physically same value layout as string, fall through */ 10648de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert U_FALLTHROUGH; 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_STRING: 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=udata_readInt32(ds, (int32_t)*p); 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap length */ 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, p, 4, q, pErrorCode); 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap each UChar (the terminating NUL would not change) */ 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, p+1, 2*count, q+1, pErrorCode); 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_BINARY: 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=udata_readInt32(ds, (int32_t)*p); 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap length */ 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, p, 4, q, pErrorCode); 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* no need to swap or copy bytes - ures_swap() copied them all */ 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap known formats */ 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION 108050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if( key!=NULL && /* the binary is in a table */ 108150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (key!=gUnknownKey ? 108250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* its table key string is "%%CollationBin" */ 108350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 0==ds->compareInvChars(ds, key, -1, 1084f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gCollationBinKey, UPRV_LENGTHOF(gCollationBinKey)-1) : 108550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* its table key string is unknown but it looks like a collation binary */ 108650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ucol_looksLikeCollationBinary(ds, p+1, count)) 108750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ) { 1088fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ucol_swap(ds, p+1, count, q+1, pErrorCode); 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 109050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_TABLE: 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_TABLE32: 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint16_t *pKey16; 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t *qKey16; 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const int32_t *pKey32; 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t *qKey32; 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource item; 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i, oldIndex; 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(RES_GET_TYPE(res)==URES_TABLE) { 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get table item count */ 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pKey16=(const uint16_t *)p; 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru qKey16=(uint16_t *)q; 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=ds->readUInt16(*pKey16); 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pKey32=qKey32=NULL; 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap count */ 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, pKey16++, 2, qKey16++, pErrorCode); 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset+=((1+count)+1)/2; 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* get table item count */ 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pKey32=(const int32_t *)p; 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru qKey32=(int32_t *)q; 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=udata_readInt32(ds, *pKey32); 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pKey16=qKey16=NULL; 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap count */ 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, pKey32++, 4, qKey32++, pErrorCode); 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru offset+=1+count; 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(count==0) { 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru p=inBundle+offset; /* pointer to table resources */ 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru q=outBundle+offset; 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* recurse */ 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 113950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *itemKey=gUnknownKey; 114050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pKey16!=NULL) { 114150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t keyOffset=ds->readUInt16(pKey16[i]); 114250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(keyOffset<pTempTable->localKeyLimit) { 114350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho itemKey=(const char *)outBundle+keyOffset; 114450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 114650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t keyOffset=udata_readInt32(ds, pKey32[i]); 114750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(keyOffset>=0) { 114850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho itemKey=(const char *)outBundle+keyOffset; 114950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru item=ds->readUInt32(p[i]); 115250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_swapResource(ds, inBundle, outBundle, item, itemKey, pTempTable, pErrorCode); 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "ures_swapResource(table res=%08x)[%d].recurse(%08x) failed\n", 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res, i, item); 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 116050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(pTempTable->majorFormatVersion>1 || ds->inCharset==ds->outCharset) { 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* no need to sort, just swap the offset/value arrays */ 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pKey16!=NULL) { 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, pKey16, count*2, qKey16, pErrorCode); 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, p, count*4, q, pErrorCode); 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap key offsets and items as one array */ 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, pKey32, count*2*4, qKey32, pErrorCode); 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * We need to sort tables by outCharset key strings because they 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * sort differently for different charset families. 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * ures_swap() already set pTempTable->keyChars appropriately. 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * First we set up a temporary table with the key indexes and 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * sorting indexes and sort that. 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Then we permutate and copy/swap the actual values. 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pKey16!=NULL) { 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pTempTable->rows[i].keyIndex=ds->readUInt16(pKey16[i]); 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pTempTable->rows[i].sortIndex=i; 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pTempTable->rows[i].keyIndex=udata_readInt32(ds, pKey32[i]); 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pTempTable->rows[i].sortIndex=i; 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_sortArray(pTempTable->rows, count, sizeof(Row), 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_compareRows, pTempTable->keyChars, 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, pErrorCode); 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "ures_swapResource(table res=%08x).uprv_sortArray(%d items) failed\n", 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res, count); 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * copy/swap/permutate items 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * If we swap in-place, then the permutation must use another 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * temporary array (pTempTable->resort) 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * before the results are copied to the outBundle. 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* keys */ 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pKey16!=NULL) { 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint16_t *rKey16; 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pKey16!=qKey16) { 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rKey16=qKey16; 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rKey16=(uint16_t *)pTempTable->resort; 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldIndex=pTempTable->rows[i].sortIndex; 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray16(ds, pKey16+oldIndex, 2, rKey16+i, pErrorCode); 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(qKey16!=rKey16) { 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(qKey16, rKey16, 2*count); 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t *rKey32; 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pKey32!=qKey32) { 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rKey32=qKey32; 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rKey32=pTempTable->resort; 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldIndex=pTempTable->rows[i].sortIndex; 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, pKey32+oldIndex, 4, rKey32+i, pErrorCode); 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(qKey32!=rKey32) { 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(qKey32, rKey32, 4*count); 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* resources */ 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource *r; 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(p!=q) { 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru r=q; 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru r=(Resource *)pTempTable->resort; 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldIndex=pTempTable->rows[i].sortIndex; 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, p+oldIndex, 4, r+i, pErrorCode); 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(q!=r) { 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(q, r, 4*count); 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_ARRAY: 1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource item; 1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i; 1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=udata_readInt32(ds, (int32_t)*p); 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap length */ 1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, p++, 4, q++, pErrorCode); 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* recurse */ 1270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0; i<count; ++i) { 1271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru item=ds->readUInt32(p[i]); 127250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_swapResource(ds, inBundle, outBundle, item, NULL, pTempTable, pErrorCode); 1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "ures_swapResource(array res=%08x)[%d].recurse(%08x) failed\n", 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res, i, item); 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap items */ 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, p, 4*count, q, pErrorCode); 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_INT_VECTOR: 1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count=udata_readInt32(ds, (int32_t)*p); 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap length and each integer */ 1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ds->swapArray32(ds, p, 4*(1+count), q, pErrorCode); 1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* also catches RES_BOGUS */ 1291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 1297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruures_swap(const UDataSwapper *ds, 1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const void *inData, int32_t length, void *outData, 1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *pErrorCode) { 1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UDataInfo *pInfo; 1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const Resource *inBundle; 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource rootRes; 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t headerSize, maxTableLength; 1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Row rows[STACK_ROW_CAPACITY]; 1306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t resort[STACK_ROW_CAPACITY]; 1307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TempTable tempTable; 1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 130950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *inIndexes; 131050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* the following integers count Resource item offsets (4 bytes each), not bytes */ 131250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t bundleLength, indexLength, keysBottom, keysTop, resBottom, top; 1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* udata_swapDataHeader checks the arguments */ 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode); 1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* check data format and format version */ 1321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo=(const UDataInfo *)((const char *)inData+4); 1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!( 1323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[0]==0x52 && /* dataFormat="ResB" */ 1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[1]==0x65 && 1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[2]==0x73 && 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[3]==0x42 && 1327c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert /* formatVersion 1.1+ or 2.x or 3.x */ 1328c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert ((pInfo->formatVersion[0]==1 && pInfo->formatVersion[1]>=1) || 1329c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert pInfo->formatVersion[0]==2 || pInfo->formatVersion[0]==3) 1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru )) { 133150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_printError(ds, "ures_swap(): data format %02x.%02x.%02x.%02x (format version %02x.%02x) is not a resource bundle\n", 1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[0], pInfo->dataFormat[1], 1333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pInfo->dataFormat[2], pInfo->dataFormat[3], 133450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pInfo->formatVersion[0], pInfo->formatVersion[1]); 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_UNSUPPORTED_ERROR; 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 133850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho tempTable.majorFormatVersion=pInfo->formatVersion[0]; 1339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* a resource bundle must contain at least one resource item */ 1341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length<0) { 1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bundleLength=-1; 1343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bundleLength=(length-headerSize)/4; 1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* formatVersion 1.1 must have a root item and at least 5 indexes */ 134750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(bundleLength<(1+5)) { 1348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "ures_swap(): too few bytes (%d after header) for a resource bundle\n", 1349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru length-headerSize); 1350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inBundle=(const Resource *)((const char *)inData+headerSize); 1356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rootRes=ds->readUInt32(*inBundle); 1357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 135850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* formatVersion 1.1 adds the indexes[] array */ 135950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho inIndexes=(const int32_t *)(inBundle+1); 1360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 136150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho indexLength=udata_readInt32(ds, inIndexes[URES_INDEX_LENGTH])&0xff; 136250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexLength<=URES_INDEX_MAX_TABLE_LENGTH) { 136350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_printError(ds, "ures_swap(): too few indexes for a 1.1+ resource bundle\n"); 136450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 136550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 136650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 136750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho keysBottom=1+indexLength; 136850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho keysTop=udata_readInt32(ds, inIndexes[URES_INDEX_KEYS_TOP]); 136950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(indexLength>URES_INDEX_16BIT_TOP) { 137050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resBottom=udata_readInt32(ds, inIndexes[URES_INDEX_16BIT_TOP]); 137150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 137250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resBottom=keysTop; 137350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 137450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho top=udata_readInt32(ds, inIndexes[URES_INDEX_BUNDLE_TOP]); 137550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho maxTableLength=udata_readInt32(ds, inIndexes[URES_INDEX_MAX_TABLE_LENGTH]); 1376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 137750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(0<=bundleLength && bundleLength<top) { 137850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_printError(ds, "ures_swap(): resource top %d exceeds bundle length %d\n", 137950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho top, bundleLength); 138050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 138150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 138250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 138350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(keysTop>(1+indexLength)) { 138450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho tempTable.localKeyLimit=keysTop<<2; 138550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 138650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho tempTable.localKeyLimit=0; 1387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(length>=0) { 1390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Resource *outBundle=(Resource *)((char *)outData+headerSize); 1391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 139250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* track which resources we have already swapped */ 139350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t stackResFlags[STACK_ROW_CAPACITY]; 139450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t resFlagsLength; 139550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 139650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 139750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * We need one bit per 4 resource bundle bytes so that we can track 139850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * every possible Resource for whether we have swapped it already. 139950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Multiple Resource words can refer to the same bundle offsets 140050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * for sharing identical values. 140150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * We could optimize this by allocating only for locations above 140250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * where Resource values are stored (above keys & strings). 140350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 140450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resFlagsLength=(length+31)>>5; /* number of bytes needed */ 140550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resFlagsLength=(resFlagsLength+3)&~3; /* multiple of 4 bytes for uint32_t */ 140624d55684271a8d3118a71a3eb4769a0431dc9d54Markus Scherer if(resFlagsLength<=(int32_t)sizeof(stackResFlags)) { 140750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho tempTable.resFlags=stackResFlags; 140850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 140950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho tempTable.resFlags=(uint32_t *)uprv_malloc(resFlagsLength); 141050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(tempTable.resFlags==NULL) { 141150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_printError(ds, "ures_swap(): unable to allocate memory for tracking resources\n"); 141250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 141350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 141450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 141550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 141650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memset(tempTable.resFlags, 0, resFlagsLength); 141750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* copy the bundle for binary and inaccessible data */ 1419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(inData!=outData) { 1420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(outBundle, inBundle, 4*top); 1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap the key strings, but not the padding bytes (0xaa) after the last string and its NUL */ 142450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_swapInvStringBlock(ds, inBundle+keysBottom, 4*(keysTop-keysBottom), 142550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho outBundle+keysBottom, pErrorCode); 1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 142750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_printError(ds, "ures_swap().udata_swapInvStringBlock(keys[%d]) failed\n", 4*(keysTop-keysBottom)); 1428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 143150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* swap the 16-bit units (strings, table16, array16) */ 143250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(keysTop<resBottom) { 143350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ds->swapArray16(ds, inBundle+keysTop, (resBottom-keysTop)*4, outBundle+keysTop, pErrorCode); 143450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_FAILURE(*pErrorCode)) { 143550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_printError(ds, "ures_swap().swapArray16(16-bit units[%d]) failed\n", 2*(resBottom-keysTop)); 143650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 143750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 143850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 143950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* allocate the temporary table for sorting resource tables */ 1441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tempTable.keyChars=(const char *)outBundle; /* sort by outCharset */ 144250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(tempTable.majorFormatVersion>1 || maxTableLength<=STACK_ROW_CAPACITY) { 1443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tempTable.rows=rows; 1444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tempTable.resort=resort; 1445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tempTable.rows=(Row *)uprv_malloc(maxTableLength*sizeof(Row)+maxTableLength*4); 1447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tempTable.rows==NULL) { 1448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "ures_swap(): unable to allocate memory for sorting tables (max length: %d)\n", 1449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru maxTableLength); 1450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 145150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(tempTable.resFlags!=stackResFlags) { 145250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(tempTable.resFlags); 145350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 1454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tempTable.resort=(int32_t *)(tempTable.rows+maxTableLength); 1457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap the resources */ 146050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_swapResource(ds, inBundle, outBundle, rootRes, NULL, &tempTable, pErrorCode); 1461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 1462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_printError(ds, "ures_swapResource(root res=%08x) failed\n", 1463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rootRes); 1464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tempTable.rows!=rows) { 1467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(tempTable.rows); 1468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 146950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(tempTable.resFlags!=stackResFlags) { 147050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(tempTable.resFlags); 147150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 1472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* swap the root resource and indexes */ 147450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ds->swapArray32(ds, inBundle, keysBottom*4, outBundle, pErrorCode); 1475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return headerSize+4*top; 1478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1479