16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* * 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 1999-2012, International Business Machines Corporation * 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* and others. All Rights Reserved. * 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* * 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* file name: uresdata.c 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* encoding: US-ASCII 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* tab size: 8 (not used) 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* indentation:4 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created on: 1999dec08 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created by: Markus W. Scherer 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Modification History: 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Date Name Description 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 06/20/2000 helena OS/400 port changes; mostly typecast. 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 06/24/02 weiv Added support for resource sharing 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/udata.h" 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h" 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utf16.h" 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cstring.h" 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uarrsort.h" 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "udataswp.h" 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucol_swp.h" 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uinvchar.h" 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uresdata.h" 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uresimp.h" 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h" 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Resource access helpers 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* get a const char* pointer to the key with the keyOffset byte offset from pRoot */ 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define RES_GET_KEY16(pResData, keyOffset) \ 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((keyOffset)<(pResData)->localKeyLimit ? \ 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (const char *)(pResData)->pRoot+(keyOffset) : \ 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (pResData)->poolBundleKeys+(keyOffset)-(pResData)->localKeyLimit) 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define RES_GET_KEY32(pResData, keyOffset) \ 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((keyOffset)>=0 ? \ 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (const char *)(pResData)->pRoot+(keyOffset) : \ 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (pResData)->poolBundleKeys+((keyOffset)&0x7fffffff)) 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define URESDATA_ITEM_NOT_FOUND -1 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* empty resources, returned when the resource offset is 0 */ 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const uint16_t gEmpty16=0; 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const struct { 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length; 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t res; 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} gEmpty32={ 0, 0 }; 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const struct { 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length; 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar nul; 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar pad; 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} gEmptyString={ 0, 0, 0 }; 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * All the type-access functions assume that 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the resource is of the expected type. 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org_res_findTableItem(const ResourceData *pResData, const uint16_t *keyOffsets, int32_t length, 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *key, const char **realKey) { 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *tableKey; 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t mid, start, limit; 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int result; 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* do a binary search for the key */ 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=0; 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=length; 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(start<limit) { 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mid = (start + limit) / 2; 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tableKey = RES_GET_KEY16(pResData, keyOffsets[mid]); 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pResData->useNativeStrcmp) { 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = uprv_strcmp(key, tableKey); 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = uprv_compareInvCharsAsAscii(key, tableKey); 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (result < 0) { 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit = mid; 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (result > 0) { 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start = mid + 1; 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* We found it! */ 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *realKey=tableKey; 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return mid; 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return URESDATA_ITEM_NOT_FOUND; /* not found or table is empty. */ 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org_res_findTable32Item(const ResourceData *pResData, const int32_t *keyOffsets, int32_t length, 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *key, const char **realKey) { 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *tableKey; 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t mid, start, limit; 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int result; 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* do a binary search for the key */ 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=0; 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=length; 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(start<limit) { 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mid = (start + limit) / 2; 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tableKey = RES_GET_KEY32(pResData, keyOffsets[mid]); 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (pResData->useNativeStrcmp) { 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = uprv_strcmp(key, tableKey); 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = uprv_compareInvCharsAsAscii(key, tableKey); 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (result < 0) { 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit = mid; 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (result > 0) { 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start = mid + 1; 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* We found it! */ 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *realKey=tableKey; 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return mid; 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return URESDATA_ITEM_NOT_FOUND; /* not found or table is empty. */ 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* helper for res_load() ---------------------------------------------------- */ 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool U_CALLCONV 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgisAcceptable(void *context, 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *type, const char *name, 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UDataInfo *pInfo) { 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(context, pInfo->formatVersion, 4); 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (UBool)( 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->size>=20 && 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->isBigEndian==U_IS_BIG_ENDIAN && 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->charsetFamily==U_CHARSET_FAMILY && 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->sizeofUChar==U_SIZEOF_UCHAR && 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->dataFormat[0]==0x52 && /* dataFormat="ResB" */ 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->dataFormat[1]==0x65 && 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->dataFormat[2]==0x73 && 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->dataFormat[3]==0x42 && 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (pInfo->formatVersion[0]==1 || pInfo->formatVersion[0]==2)); 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* semi-public functions ---------------------------------------------------- */ 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_init(ResourceData *pResData, 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UVersionInfo formatVersion, const void *inBytes, int32_t length, 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *errorCode) { 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResType rootType; 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* get the root resource */ 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pResData->pRoot=(const int32_t *)inBytes; 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pResData->rootRes=(Resource)*pResData->pRoot; 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pResData->p16BitUnits=&gEmpty16; 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* formatVersion 1.1 must have a root item and at least 5 indexes */ 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length>=0 && (length/4)<((formatVersion[0]==1 && formatVersion[1]==0) ? 1 : 1+5)) { 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *errorCode=U_INVALID_FORMAT_ERROR; 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org res_unload(pResData); 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* currently, we accept only resources that have a Table as their roots */ 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rootType=(UResType)RES_GET_TYPE(pResData->rootRes); 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!URES_IS_TABLE(rootType)) { 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *errorCode=U_INVALID_FORMAT_ERROR; 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org res_unload(pResData); 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(formatVersion[0]==1 && formatVersion[1]==0) { 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pResData->localKeyLimit=0x10000; /* greater than any 16-bit key string offset */ 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* bundles with formatVersion 1.1 and later contain an indexes[] array */ 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t *indexes=pResData->pRoot+1; 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t indexLength=indexes[URES_INDEX_LENGTH]&0xff; 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(indexLength<=URES_INDEX_MAX_TABLE_LENGTH) { 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *errorCode=U_INVALID_FORMAT_ERROR; 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org res_unload(pResData); 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( length>=0 && 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (length<((1+indexLength)<<2) || 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length<(indexes[URES_INDEX_BUNDLE_TOP]<<2)) 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *errorCode=U_INVALID_FORMAT_ERROR; 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org res_unload(pResData); 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(indexes[URES_INDEX_KEYS_TOP]>(1+indexLength)) { 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pResData->localKeyLimit=indexes[URES_INDEX_KEYS_TOP]<<2; 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(indexLength>URES_INDEX_ATTRIBUTES) { 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t att=indexes[URES_INDEX_ATTRIBUTES]; 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pResData->noFallback=(UBool)(att&URES_ATT_NO_FALLBACK); 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pResData->isPoolBundle=(UBool)((att&URES_ATT_IS_POOL_BUNDLE)!=0); 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pResData->usesPoolBundle=(UBool)((att&URES_ATT_USES_POOL_BUNDLE)!=0); 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((pResData->isPoolBundle || pResData->usesPoolBundle) && indexLength<=URES_INDEX_POOL_CHECKSUM) { 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *errorCode=U_INVALID_FORMAT_ERROR; 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org res_unload(pResData); 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( indexLength>URES_INDEX_16BIT_TOP && 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org indexes[URES_INDEX_16BIT_TOP]>indexes[URES_INDEX_KEYS_TOP] 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pResData->p16BitUnits=(const uint16_t *)(pResData->pRoot+indexes[URES_INDEX_KEYS_TOP]); 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(formatVersion[0]==1 || U_CHARSET_FAMILY==U_ASCII_FAMILY) { 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * formatVersion 1: compare key strings in native-charset order 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * formatVersion 2 and up: compare key strings in ASCII order 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pResData->useNativeStrcmp=TRUE; 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_read(ResourceData *pResData, 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UDataInfo *pInfo, const void *inBytes, int32_t length, 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *errorCode) { 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UVersionInfo formatVersion; 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memset(pResData, 0, sizeof(ResourceData)); 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*errorCode)) { 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!isAcceptable(formatVersion, NULL, NULL, pInfo)) { 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *errorCode=U_INVALID_FORMAT_ERROR; 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org res_init(pResData, formatVersion, inBytes, length, errorCode); 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC void 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_load(ResourceData *pResData, 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *path, const char *name, UErrorCode *errorCode) { 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UVersionInfo formatVersion; 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memset(pResData, 0, sizeof(ResourceData)); 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* load the ResourceBundle file */ 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pResData->data=udata_openChoice(path, "res", name, isAcceptable, formatVersion, errorCode); 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*errorCode)) { 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* get its memory and initialize *pResData */ 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org res_init(pResData, formatVersion, udata_getMemory(pResData->data), -1, errorCode); 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC void 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_unload(ResourceData *pResData) { 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pResData->data!=NULL) { 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udata_close(pResData->data); 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pResData->data=NULL; 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int8_t gPublicTypes[URES_LIMIT] = { 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_STRING, 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_BINARY, 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_TABLE, 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_ALIAS, 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_TABLE, /* URES_TABLE32 */ 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_TABLE, /* URES_TABLE16 */ 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_STRING, /* URES_STRING_V2 */ 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_INT, 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_ARRAY, 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_ARRAY, /* URES_ARRAY16 */ 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_NONE, 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_NONE, 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_NONE, 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_NONE, 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_INT_VECTOR, 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org URES_NONE 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UResType U_EXPORT2 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_getPublicType(Resource res) { 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (UResType)gPublicTypes[RES_GET_TYPE(res)]; 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const UChar * U_EXPORT2 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_getString(const ResourceData *pResData, Resource res, int32_t *pLength) { 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *p; 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t offset=RES_GET_OFFSET(res); 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length; 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(RES_GET_TYPE(res)==URES_STRING_V2) { 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t first; 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p=(const UChar *)(pResData->p16BitUnits+offset); 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org first=*p; 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!U16_IS_TRAIL(first)) { 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=u_strlen(p); 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(first<0xdfef) { 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=first&0x3ff; 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++p; 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(first<0xdfff) { 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=((first-0xdfef)<<16)|p[1]; 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p+=2; 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=((int32_t)p[1]<<16)|p[2]; 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p+=3; 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(res==offset) /* RES_GET_TYPE(res)==URES_STRING */ { 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t *p32= res==0 ? &gEmptyString.length : pResData->pRoot+res; 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=*p32++; 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p=(const UChar *)p32; 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p=NULL; 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=0; 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pLength) { 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pLength=length; 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return p; 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const UChar * U_EXPORT2 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_getAlias(const ResourceData *pResData, Resource res, int32_t *pLength) { 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *p; 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t offset=RES_GET_OFFSET(res); 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length; 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(RES_GET_TYPE(res)==URES_ALIAS) { 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t *p32= offset==0 ? &gEmptyString.length : pResData->pRoot+offset; 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=*p32++; 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p=(const UChar *)p32; 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p=NULL; 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=0; 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pLength) { 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pLength=length; 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return p; 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const uint8_t * U_EXPORT2 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_getBinary(const ResourceData *pResData, Resource res, int32_t *pLength) { 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint8_t *p; 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t offset=RES_GET_OFFSET(res); 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length; 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(RES_GET_TYPE(res)==URES_BINARY) { 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t *p32= offset==0 ? (const int32_t*)&gEmpty32 : pResData->pRoot+offset; 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=*p32++; 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p=(const uint8_t *)p32; 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p=NULL; 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=0; 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pLength) { 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pLength=length; 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return p; 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const int32_t * U_EXPORT2 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_getIntVector(const ResourceData *pResData, Resource res, int32_t *pLength) { 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t *p; 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t offset=RES_GET_OFFSET(res); 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length; 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(RES_GET_TYPE(res)==URES_INT_VECTOR) { 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p= offset==0 ? (const int32_t *)&gEmpty32 : pResData->pRoot+offset; 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=*p++; 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p=NULL; 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=0; 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pLength) { 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pLength=length; 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return p; 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_countArrayItems(const ResourceData *pResData, Resource res) { 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t offset=RES_GET_OFFSET(res); 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(RES_GET_TYPE(res)) { 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_STRING: 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_STRING_V2: 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_BINARY: 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_ALIAS: 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_INT: 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_INT_VECTOR: 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 1; 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_ARRAY: 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_TABLE32: 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return offset==0 ? 0 : *(pResData->pRoot+offset); 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_TABLE: 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return offset==0 ? 0 : *((const uint16_t *)(pResData->pRoot+offset)); 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_ARRAY16: 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_TABLE16: 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pResData->p16BitUnits[offset]; 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI Resource U_EXPORT2 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_getTableItemByKey(const ResourceData *pResData, Resource table, 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *indexR, const char **key) { 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t offset=RES_GET_OFFSET(table); 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length; 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t idx; 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(key == NULL || *key == NULL) { 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return RES_BOGUS; 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(RES_GET_TYPE(table)) { 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_TABLE: { 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (offset!=0) { /* empty if offset==0 */ 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint16_t *p= (const uint16_t *)(pResData->pRoot+offset); 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=*p++; 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *indexR=idx=_res_findTableItem(pResData, p, length, *key, key); 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(idx>=0) { 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Resource *p32=(const Resource *)(p+length+(~length&1)); 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return p32[idx]; 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_TABLE16: { 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint16_t *p=pResData->p16BitUnits+offset; 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=*p++; 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *indexR=idx=_res_findTableItem(pResData, p, length, *key, key); 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(idx>=0) { 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return URES_MAKE_RESOURCE(URES_STRING_V2, p[length+idx]); 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_TABLE32: { 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (offset!=0) { /* empty if offset==0 */ 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t *p= pResData->pRoot+offset; 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=*p++; 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *indexR=idx=_res_findTable32Item(pResData, p, length, *key, key); 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(idx>=0) { 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (Resource)p[length+idx]; 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return RES_BOGUS; 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI Resource U_EXPORT2 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_getTableItemByIndex(const ResourceData *pResData, Resource table, 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t indexR, const char **key) { 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t offset=RES_GET_OFFSET(table); 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length; 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(indexR>=0); /* to ensure the index is not negative */ 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(RES_GET_TYPE(table)) { 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_TABLE: { 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (offset != 0) { /* empty if offset==0 */ 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint16_t *p= (const uint16_t *)(pResData->pRoot+offset); 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=*p++; 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(indexR<length) { 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Resource *p32=(const Resource *)(p+length+(~length&1)); 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(key!=NULL) { 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *key=RES_GET_KEY16(pResData, p[indexR]); 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return p32[indexR]; 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_TABLE16: { 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint16_t *p=pResData->p16BitUnits+offset; 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=*p++; 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(indexR<length) { 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(key!=NULL) { 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *key=RES_GET_KEY16(pResData, p[indexR]); 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return URES_MAKE_RESOURCE(URES_STRING_V2, p[length+indexR]); 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_TABLE32: { 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (offset != 0) { /* empty if offset==0 */ 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t *p= pResData->pRoot+offset; 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length=*p++; 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(indexR<length) { 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(key!=NULL) { 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *key=RES_GET_KEY32(pResData, p[indexR]); 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (Resource)p[length+indexR]; 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return RES_BOGUS; 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI Resource U_EXPORT2 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_getResource(const ResourceData *pResData, const char *key) { 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *realKey=key; 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t idx; 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return res_getTableItemByKey(pResData, pResData->rootRes, &idx, &realKey); 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI Resource U_EXPORT2 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_getArrayItem(const ResourceData *pResData, Resource array, int32_t indexR) { 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t offset=RES_GET_OFFSET(array); 5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(indexR>=0); /* to ensure the index is not negative */ 5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(RES_GET_TYPE(array)) { 5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_ARRAY: { 5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (offset!=0) { /* empty if offset==0 */ 5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t *p= pResData->pRoot+offset; 5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(indexR<*p) { 5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (Resource)p[1+indexR]; 5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_ARRAY16: { 5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint16_t *p=pResData->p16BitUnits+offset; 5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(indexR<*p) { 5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return URES_MAKE_RESOURCE(URES_STRING_V2, p[1+indexR]); 5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return RES_BOGUS; 5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC Resource 5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgres_findResource(const ResourceData *pResData, Resource r, char** path, const char** key) { 5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we pass in a path. CollationElements/Sequence or zoneStrings/3/2 etc. 5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * iterates over a path and stops when a scalar resource is found. This 5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * CAN be an alias. Path gets set to the part that has not yet been processed. 5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *pathP = *path, *nextSepP = *path; 5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char *closeIndex = NULL; 5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Resource t1 = r; 5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Resource t2; 5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t indexR = 0; 5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UResType type = (UResType)RES_GET_TYPE(t1); 5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* if you come in with an empty path, you'll be getting back the same resource */ 5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!uprv_strlen(pathP)) { 5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return r; 5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* one needs to have an aggregate resource in order to search in it */ 5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!URES_IS_CONTAINER(type)) { 5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return RES_BOGUS; 5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(nextSepP && *pathP && t1 != RES_BOGUS && URES_IS_CONTAINER(type)) { 5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Iteration stops if: the path has been consumed, we found a non-existing 5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * resource (t1 == RES_BOGUS) or we found a scalar resource (including alias) 5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org nextSepP = uprv_strchr(pathP, RES_PATH_SEPARATOR); 5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* if there are more separators, terminate string 5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and set path to the remaining part of the string 5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(nextSepP != NULL) { 5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *nextSepP = 0; /* overwrite the separator with a NUL to terminate the key */ 5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *path = nextSepP+1; 5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *path = uprv_strchr(pathP, 0); 5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* if the resource is a table */ 5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* try the key based access */ 5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(URES_IS_TABLE(type)) { 5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *key = pathP; 5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t2 = res_getTableItemByKey(pResData, t1, &indexR, key); 5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(t2 == RES_BOGUS) { 5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* if we fail to get the resource by key, maybe we got an index */ 5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org indexR = uprv_strtol(pathP, &closeIndex, 10); 5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(closeIndex != pathP) { 5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* if we indeed have an index, try to get the item by index */ 5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t2 = res_getTableItemByIndex(pResData, t1, indexR, key); 6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(URES_IS_ARRAY(type)) { 6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org indexR = uprv_strtol(pathP, &closeIndex, 10); 6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(closeIndex != pathP) { 6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t2 = res_getArrayItem(pResData, t1, indexR); 6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t2 = RES_BOGUS; /* have an array, but don't have a valid index */ 6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *key = NULL; 6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { /* can't do much here, except setting t2 to bogus */ 6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t2 = RES_BOGUS; 6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t1 = t2; 6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org type = (UResType)RES_GET_TYPE(t1); 6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* position pathP to next resource key/index */ 6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pathP = *path; 6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return t1; 6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* resource bundle swapping ------------------------------------------------- */ 6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Need to always enumerate the entire item tree, 6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * track the lowest address of any item to use as the limit for char keys[], 6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * track the highest address of any item to return the size of the data. 6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We should have thought of storing those in the data... 6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * It is possible to extend the data structure by putting additional values 6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * in places that are inaccessible by ordinary enumeration of the item tree. 6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * For example, additional integers could be stored at the beginning or 6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * end of the key strings; this could be indicated by a minor version number, 6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and the data swapping would have to know about these values. 6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The data structure does not forbid keys to be shared, so we must swap 6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * all keys once instead of each key when it is referenced. 6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * These swapping functions assume that a resource bundle always has a length 6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * that is a multiple of 4 bytes. 6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Currently, this is trivially true because genrb writes bundle tree leaves 6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * physically first, before their branches, so that the root table with its 6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * array of resource items (uint32_t values) is always last. 6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* definitions for table sorting ------------------------ */ 6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * row of a temporary array 6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * gets platform-endian key string indexes and sorting indexes; 6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * after sorting this array by keys, the actual key/value arrays are permutated 6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * according to the sorting indexes 6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtypedef struct Row { 6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t keyIndex, sortIndex; 6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} Row; 6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t 6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgures_compareRows(const void *context, const void *left, const void *right) { 6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *keyChars=(const char *)context; 6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (int32_t)uprv_strcmp(keyChars+((const Row *)left)->keyIndex, 6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org keyChars+((const Row *)right)->keyIndex); 6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtypedef struct TempTable { 6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *keyChars; 6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Row *rows; 6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *resort; 6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t *resFlags; 6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t localKeyLimit; 6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint8_t majorFormatVersion; 6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} TempTable; 6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgenum { 6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org STACK_ROW_CAPACITY=200 6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* The table item key string is not locally available. */ 6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const char *const gUnknownKey=""; 6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* resource table key for collation binaries: "%%CollationBin" */ 6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar gCollationBinKey[]={ 6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x25, 0x25, 6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x42, 0x69, 0x6e, 6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0 6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * swap one resource item 6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void 6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgures_swapResource(const UDataSwapper *ds, 6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Resource *inBundle, Resource *outBundle, 6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Resource res, /* caller swaps res itself */ 6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *key, 6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TempTable *pTempTable, 6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Resource *p; 7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Resource *q; 7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t offset, count; 7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(RES_GET_TYPE(res)) { 7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_TABLE16: 7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_STRING_V2: 7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_INT: 7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_ARRAY16: 7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* integer, or points to 16-bit units, nothing to do here */ 7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* all other types use an offset to point to their data */ 7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offset=(int32_t)RES_GET_OFFSET(res); 7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(offset==0) { 7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* special offset indicating an empty item */ 7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pTempTable->resFlags[offset>>5]&((uint32_t)1<<(offset&0x1f))) { 7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we already swapped this resource item */ 7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* mark it as swapped now */ 7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pTempTable->resFlags[offset>>5]|=((uint32_t)1<<(offset&0x1f)); 7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p=inBundle+offset; 7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org q=outBundle+offset; 7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(RES_GET_TYPE(res)) { 7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_ALIAS: 7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* physically same value layout as string, fall through */ 7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_STRING: 7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count=udata_readInt32(ds, (int32_t)*p); 7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* swap length */ 7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray32(ds, p, 4, q, pErrorCode); 7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* swap each UChar (the terminating NUL would not change) */ 7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray16(ds, p+1, 2*count, q+1, pErrorCode); 7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_BINARY: 7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count=udata_readInt32(ds, (int32_t)*p); 7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* swap length */ 7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray32(ds, p, 4, q, pErrorCode); 7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no need to swap or copy bytes - ures_swap() copied them all */ 7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* swap known formats */ 7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_COLLATION 7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( key!=NULL && /* the binary is in a table */ 7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (key!=gUnknownKey ? 7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* its table key string is "%%CollationBin" */ 7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0==ds->compareInvChars(ds, key, -1, 7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gCollationBinKey, LENGTHOF(gCollationBinKey)-1) : 7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* its table key string is unknown but it looks like a collation binary */ 7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucol_looksLikeCollationBinary(ds, p+1, count)) 7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucol_swapBinary(ds, p+1, count, q+1, pErrorCode); 7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_TABLE: 7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_TABLE32: 7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint16_t *pKey16; 7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint16_t *qKey16; 7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t *pKey32; 7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *qKey32; 7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Resource item; 7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, oldIndex; 7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(RES_GET_TYPE(res)==URES_TABLE) { 7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* get table item count */ 7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pKey16=(const uint16_t *)p; 7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org qKey16=(uint16_t *)q; 7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count=ds->readUInt16(*pKey16); 7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pKey32=qKey32=NULL; 7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* swap count */ 7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray16(ds, pKey16++, 2, qKey16++, pErrorCode); 7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offset+=((1+count)+1)/2; 7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* get table item count */ 7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pKey32=(const int32_t *)p; 7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org qKey32=(int32_t *)q; 7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count=udata_readInt32(ds, *pKey32); 7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pKey16=qKey16=NULL; 7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* swap count */ 7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray32(ds, pKey32++, 4, qKey32++, pErrorCode); 7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org offset+=1+count; 7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(count==0) { 8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org p=inBundle+offset; /* pointer to table resources */ 8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org q=outBundle+offset; 8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* recurse */ 8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<count; ++i) { 8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *itemKey=gUnknownKey; 8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pKey16!=NULL) { 8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t keyOffset=ds->readUInt16(pKey16[i]); 8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(keyOffset<pTempTable->localKeyLimit) { 8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org itemKey=(const char *)outBundle+keyOffset; 8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t keyOffset=udata_readInt32(ds, pKey32[i]); 8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(keyOffset>=0) { 8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org itemKey=(const char *)outBundle+keyOffset; 8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org item=ds->readUInt32(p[i]); 8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_swapResource(ds, inBundle, outBundle, item, itemKey, pTempTable, pErrorCode); 8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udata_printError(ds, "ures_swapResource(table res=%08x)[%d].recurse(%08x) failed\n", 8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org res, i, item); 8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pTempTable->majorFormatVersion>1 || ds->inCharset==ds->outCharset) { 8316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* no need to sort, just swap the offset/value arrays */ 8326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pKey16!=NULL) { 8336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray16(ds, pKey16, count*2, qKey16, pErrorCode); 8346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray32(ds, p, count*4, q, pErrorCode); 8356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 8366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* swap key offsets and items as one array */ 8376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray32(ds, pKey32, count*2*4, qKey32, pErrorCode); 8386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 8406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 8436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We need to sort tables by outCharset key strings because they 8446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * sort differently for different charset families. 8456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * ures_swap() already set pTempTable->keyChars appropriately. 8466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * First we set up a temporary table with the key indexes and 8476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * sorting indexes and sort that. 8486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Then we permutate and copy/swap the actual values. 8496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pKey16!=NULL) { 8516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<count; ++i) { 8526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pTempTable->rows[i].keyIndex=ds->readUInt16(pKey16[i]); 8536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pTempTable->rows[i].sortIndex=i; 8546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 8566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<count; ++i) { 8576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pTempTable->rows[i].keyIndex=udata_readInt32(ds, pKey32[i]); 8586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pTempTable->rows[i].sortIndex=i; 8596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_sortArray(pTempTable->rows, count, sizeof(Row), 8626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_compareRows, pTempTable->keyChars, 8636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FALSE, pErrorCode); 8646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 8656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udata_printError(ds, "ures_swapResource(table res=%08x).uprv_sortArray(%d items) failed\n", 8666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org res, count); 8676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 8686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 8716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * copy/swap/permutate items 8726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 8736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * If we swap in-place, then the permutation must use another 8746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * temporary array (pTempTable->resort) 8756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * before the results are copied to the outBundle. 8766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 8776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* keys */ 8786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pKey16!=NULL) { 8796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint16_t *rKey16; 8806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pKey16!=qKey16) { 8826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rKey16=qKey16; 8836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 8846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rKey16=(uint16_t *)pTempTable->resort; 8856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<count; ++i) { 8876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org oldIndex=pTempTable->rows[i].sortIndex; 8886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray16(ds, pKey16+oldIndex, 2, rKey16+i, pErrorCode); 8896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(qKey16!=rKey16) { 8916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(qKey16, rKey16, 2*count); 8926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 8946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *rKey32; 8956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pKey32!=qKey32) { 8976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rKey32=qKey32; 8986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 8996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rKey32=pTempTable->resort; 9006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<count; ++i) { 9026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org oldIndex=pTempTable->rows[i].sortIndex; 9036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray32(ds, pKey32+oldIndex, 4, rKey32+i, pErrorCode); 9046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(qKey32!=rKey32) { 9066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(qKey32, rKey32, 4*count); 9076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* resources */ 9116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 9126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Resource *r; 9136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(p!=q) { 9166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org r=q; 9176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 9186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org r=(Resource *)pTempTable->resort; 9196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<count; ++i) { 9216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org oldIndex=pTempTable->rows[i].sortIndex; 9226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray32(ds, p+oldIndex, 4, r+i, pErrorCode); 9236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(q!=r) { 9256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(q, r, 4*count); 9266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 9306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_ARRAY: 9316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 9326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Resource item; 9336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i; 9346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count=udata_readInt32(ds, (int32_t)*p); 9366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* swap length */ 9376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray32(ds, p++, 4, q++, pErrorCode); 9386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* recurse */ 9406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<count; ++i) { 9416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org item=ds->readUInt32(p[i]); 9426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_swapResource(ds, inBundle, outBundle, item, NULL, pTempTable, pErrorCode); 9436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 9446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udata_printError(ds, "ures_swapResource(array res=%08x)[%d].recurse(%08x) failed\n", 9456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org res, i, item); 9466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 9476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* swap items */ 9516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray32(ds, p, 4*count, q, pErrorCode); 9526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 9546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case URES_INT_VECTOR: 9556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count=udata_readInt32(ds, (int32_t)*p); 9566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* swap length and each integer */ 9576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray32(ds, p, 4*(1+count), q, pErrorCode); 9586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 9596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 9606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* also catches RES_BOGUS */ 9616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_UNSUPPORTED_ERROR; 9626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 9636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 9676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgures_swap(const UDataSwapper *ds, 9686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const void *inData, int32_t length, void *outData, 9696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 9706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UDataInfo *pInfo; 9716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Resource *inBundle; 9726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Resource rootRes; 9736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t headerSize, maxTableLength; 9746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Row rows[STACK_ROW_CAPACITY]; 9766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t resort[STACK_ROW_CAPACITY]; 9776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TempTable tempTable; 9786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t *inIndexes; 9806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* the following integers count Resource item offsets (4 bytes each), not bytes */ 9826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t bundleLength, indexLength, keysBottom, keysTop, resBottom, top; 9836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* udata_swapDataHeader checks the arguments */ 9856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org headerSize=udata_swapDataHeader(ds, inData, length, outData, pErrorCode); 9866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 9876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 9886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check data format and format version */ 9916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo=(const UDataInfo *)((const char *)inData+4); 9926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!( 9936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->dataFormat[0]==0x52 && /* dataFormat="ResB" */ 9946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->dataFormat[1]==0x65 && 9956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->dataFormat[2]==0x73 && 9966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->dataFormat[3]==0x42 && 9976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((pInfo->formatVersion[0]==1 && pInfo->formatVersion[1]>=1) || /* formatVersion 1.1+ or 2.x */ 9986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->formatVersion[0]==2) 9996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org )) { 10006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udata_printError(ds, "ures_swap(): data format %02x.%02x.%02x.%02x (format version %02x.%02x) is not a resource bundle\n", 10016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->dataFormat[0], pInfo->dataFormat[1], 10026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->dataFormat[2], pInfo->dataFormat[3], 10036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pInfo->formatVersion[0], pInfo->formatVersion[1]); 10046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_UNSUPPORTED_ERROR; 10056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 10066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempTable.majorFormatVersion=pInfo->formatVersion[0]; 10086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* a resource bundle must contain at least one resource item */ 10106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length<0) { 10116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bundleLength=-1; 10126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 10136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org bundleLength=(length-headerSize)/4; 10146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* formatVersion 1.1 must have a root item and at least 5 indexes */ 10166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(bundleLength<(1+5)) { 10176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udata_printError(ds, "ures_swap(): too few bytes (%d after header) for a resource bundle\n", 10186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length-headerSize); 10196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 10206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 10216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org inBundle=(const Resource *)((const char *)inData+headerSize); 10256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rootRes=ds->readUInt32(*inBundle); 10266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* formatVersion 1.1 adds the indexes[] array */ 10286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org inIndexes=(const int32_t *)(inBundle+1); 10296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org indexLength=udata_readInt32(ds, inIndexes[URES_INDEX_LENGTH])&0xff; 10316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(indexLength<=URES_INDEX_MAX_TABLE_LENGTH) { 10326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udata_printError(ds, "ures_swap(): too few indexes for a 1.1+ resource bundle\n"); 10336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 10346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 10356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org keysBottom=1+indexLength; 10376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org keysTop=udata_readInt32(ds, inIndexes[URES_INDEX_KEYS_TOP]); 10386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(indexLength>URES_INDEX_16BIT_TOP) { 10396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resBottom=udata_readInt32(ds, inIndexes[URES_INDEX_16BIT_TOP]); 10406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 10416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resBottom=keysTop; 10426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org top=udata_readInt32(ds, inIndexes[URES_INDEX_BUNDLE_TOP]); 10446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org maxTableLength=udata_readInt32(ds, inIndexes[URES_INDEX_MAX_TABLE_LENGTH]); 10456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(0<=bundleLength && bundleLength<top) { 10476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udata_printError(ds, "ures_swap(): resource top %d exceeds bundle length %d\n", 10486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org top, bundleLength); 10496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 10506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 10516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(keysTop>(1+indexLength)) { 10536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempTable.localKeyLimit=keysTop<<2; 10546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 10556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempTable.localKeyLimit=0; 10566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(length>=0) { 10596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Resource *outBundle=(Resource *)((char *)outData+headerSize); 10606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* track which resources we have already swapped */ 10626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t stackResFlags[STACK_ROW_CAPACITY]; 10636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t resFlagsLength; 10646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 10666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We need one bit per 4 resource bundle bytes so that we can track 10676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * every possible Resource for whether we have swapped it already. 10686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Multiple Resource words can refer to the same bundle offsets 10696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * for sharing identical values. 10706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * We could optimize this by allocating only for locations above 10716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * where Resource values are stored (above keys & strings). 10726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 10736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resFlagsLength=(length+31)>>5; /* number of bytes needed */ 10746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resFlagsLength=(resFlagsLength+3)&~3; /* multiple of 4 bytes for uint32_t */ 10756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(resFlagsLength<=sizeof(stackResFlags)) { 10766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempTable.resFlags=stackResFlags; 10776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 10786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempTable.resFlags=(uint32_t *)uprv_malloc(resFlagsLength); 10796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(tempTable.resFlags==NULL) { 10806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udata_printError(ds, "ures_swap(): unable to allocate memory for tracking resources\n"); 10816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 10826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 10836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memset(tempTable.resFlags, 0, resFlagsLength); 10866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* copy the bundle for binary and inaccessible data */ 10886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(inData!=outData) { 10896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(outBundle, inBundle, 4*top); 10906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* swap the key strings, but not the padding bytes (0xaa) after the last string and its NUL */ 10936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udata_swapInvStringBlock(ds, inBundle+keysBottom, 4*(keysTop-keysBottom), 10946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org outBundle+keysBottom, pErrorCode); 10956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 10966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udata_printError(ds, "ures_swap().udata_swapInvStringBlock(keys[%d]) failed\n", 4*(keysTop-keysBottom)); 10976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 10986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* swap the 16-bit units (strings, table16, array16) */ 11016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(keysTop<resBottom) { 11026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray16(ds, inBundle+keysTop, (resBottom-keysTop)*4, outBundle+keysTop, pErrorCode); 11036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 11046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udata_printError(ds, "ures_swap().swapArray16(16-bit units[%d]) failed\n", 2*(resBottom-keysTop)); 11056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 11066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* allocate the temporary table for sorting resource tables */ 11106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempTable.keyChars=(const char *)outBundle; /* sort by outCharset */ 11116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(tempTable.majorFormatVersion>1 || maxTableLength<=STACK_ROW_CAPACITY) { 11126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempTable.rows=rows; 11136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempTable.resort=resort; 11146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 11156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempTable.rows=(Row *)uprv_malloc(maxTableLength*sizeof(Row)+maxTableLength*4); 11166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(tempTable.rows==NULL) { 11176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udata_printError(ds, "ures_swap(): unable to allocate memory for sorting tables (max length: %d)\n", 11186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org maxTableLength); 11196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 11206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(tempTable.resFlags!=stackResFlags) { 11216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(tempTable.resFlags); 11226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 11246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempTable.resort=(int32_t *)(tempTable.rows+maxTableLength); 11266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* swap the resources */ 11296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ures_swapResource(ds, inBundle, outBundle, rootRes, NULL, &tempTable, pErrorCode); 11306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 11316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org udata_printError(ds, "ures_swapResource(root res=%08x) failed\n", 11326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rootRes); 11336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(tempTable.rows!=rows) { 11366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(tempTable.rows); 11376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(tempTable.resFlags!=stackResFlags) { 11396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(tempTable.resFlags); 11406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* swap the root resource and indexes */ 11436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ds->swapArray32(ds, inBundle, keysBottom*4, outBundle, pErrorCode); 11446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return headerSize+4*top; 11476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1148