1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 4b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* Copyright (C) 2000-2011, International Business Machines 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* File reslist.c 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification History: 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Date Name Description 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 02/21/00 weiv Creation. 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <assert.h> 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h> 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "reslist.h" 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unewdata.h" 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ures.h" 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/putil.h" 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "errmsg.h" 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "uarrsort.h" 2750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "uinvchar.h" 2850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 2950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* 3050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Align binary data at a 16-byte offset from the start of the resource bundle, 3150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * to be safe for any data type it may contain. 3250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define BIN_ALIGNMENT 16 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool gIncludeCopyright = FALSE; 3650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool gUsePoolBundle = FALSE; 3750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t gFormatVersion = 2; 3850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 3950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UChar gEmptyString = 0; 4050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 4150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* How do we store string values? */ 4250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoenum { 4350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho STRINGS_UTF16_V1, /* formatVersion 1: int length + UChars + NUL + padding to 4 bytes */ 4450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho STRINGS_UTF16_V2 /* formatVersion 2: optional length in 1..3 UChars + UChars + NUL */ 4550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 4650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 4750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoenum { 4850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho MAX_IMPLICIT_STRING_LENGTH = 40 /* do not store the length explicitly for such strings */ 4950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 51c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru/* 52c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru * res_none() returns the address of kNoResource, 53c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru * for use in non-error cases when no resource is to be added to the bundle. 54c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru * (NULL is used in error cases.) 55c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru */ 5650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const struct SResource kNoResource = { URES_NONE }; 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 5850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UDataInfo dataInfo= { 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sizeof(UDataInfo), 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0, 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_IS_BIG_ENDIAN, 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_CHARSET_FAMILY, 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sizeof(UChar), 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 0, 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 6750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho {0x52, 0x65, 0x73, 0x42}, /* dataFormat="ResB" */ 6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho {1, 3, 0, 0}, /* formatVersion */ 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {1, 4, 0, 0} /* dataVersion take a look at version inside parsed resb*/ 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 7250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const UVersionInfo gFormatVersions[3] = { /* indexed by a major-formatVersion integer */ 7350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho { 0, 0, 0, 0 }, 7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho { 1, 3, 0, 0 }, 7550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho { 2, 0, 0, 0 } 7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint8_t calcPadding(uint32_t size) { 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* returns space we need to pad */ 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (uint8_t) ((size % sizeof(uint32_t)) ? (sizeof(uint32_t) - (size % sizeof(uint32_t))) : 0); 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid setIncludeCopyright(UBool val){ 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gIncludeCopyright=val; 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool getIncludeCopyright(void){ 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return gIncludeCopyright; 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 9250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid setFormatVersion(int32_t formatVersion) { 9350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho gFormatVersion = formatVersion; 9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 9650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid setUsePoolBundle(UBool use) { 9750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho gUsePoolBundle = use; 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 10050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 10150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehobundle_compactStrings(struct SRBRoot *bundle, UErrorCode *status); 10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Writing Functions */ 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* 10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * type_write16() functions write resource values into f16BitUnits 10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * and determine the resource item word, if possible. 10850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 10950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 11050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_write16(struct SRBRoot *bundle, struct SResource *res, 11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status); 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* 11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * type_preWrite() functions calculate ("preflight") and advance the *byteOffset 11550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * by the size of their data in the binary file and 11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * determine the resource item word. 11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Most type_preWrite() functions may add any number of bytes, but res_preWrite() 11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * will always pad it to a multiple of 4. 11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * The resource item type may be a related subtype of the fType. 12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 12150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * The type_preWrite() and type_write() functions start and end at the same 12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * byteOffset values. 12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Prewriting allows bundle_write() to determine the root resource item word, 12450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * before actually writing the bundle contents to the file, 12550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * which is necessary because the root item is stored at the beginning. 12650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 12750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 12850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_preWrite(uint32_t *byteOffset, 12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle, struct SResource *res, 13050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status); 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 13250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* 13350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * type_write() functions write their data to mem and update the byteOffset 13450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * in parallel. 13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * (A kingdom for C++ and polymorphism...) 13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 13750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 13850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_write(UNewDataMemory *mem, uint32_t *byteOffset, 13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle, struct SResource *res, 14050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status); 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 14250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic uint16_t * 14350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoreserve16BitUnits(struct SRBRoot *bundle, int32_t length, UErrorCode *status) { 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return NULL; 14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 14750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if ((bundle->f16BitUnitsLength + length) > bundle->f16BitUnitsCapacity) { 14850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint16_t *newUnits; 14950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t capacity = 2 * bundle->f16BitUnitsCapacity + length + 1024; 15050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho capacity &= ~1; /* ensures padding fits if f16BitUnitsLength needs it */ 15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho newUnits = (uint16_t *)uprv_malloc(capacity * 2); 15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (newUnits == NULL) { 15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *status = U_MEMORY_ALLOCATION_ERROR; 15450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return NULL; 15550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 15650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->f16BitUnitsLength > 0) { 15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memcpy(newUnits, bundle->f16BitUnits, bundle->f16BitUnitsLength * 2); 15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho newUnits[0] = 0; 16050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnitsLength = 1; 16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(bundle->f16BitUnits); 16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnits = newUnits; 16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnitsCapacity = capacity; 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return bundle->f16BitUnits + bundle->f16BitUnitsLength; 16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 16950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t 17050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehomakeRes16(uint32_t resWord) { 17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t type, offset; 17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (resWord == 0) { 17350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; /* empty string */ 17450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho type = RES_GET_TYPE(resWord); 17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho offset = RES_GET_OFFSET(resWord); 17750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (type == URES_STRING_V2 && offset <= 0xffff) { 17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return (int32_t)offset; 17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 18050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return -1; 18150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 18350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t 18450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehomapKey(struct SRBRoot *bundle, int32_t oldpos) { 18550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const KeyMapEntry *map = bundle->fKeyMap; 18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t i, start, limit; 18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 18850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* do a binary search for the old, pre-bundle_compactKeys() key offset */ 18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho start = bundle->fPoolBundleKeysCount; 19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho limit = start + bundle->fKeysCount; 19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while (start < limit - 1) { 19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho i = (start + limit) / 2; 19350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (oldpos < map[i].oldpos) { 19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho limit = i; 19550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 19650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho start = i; 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 19850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 19950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho assert(oldpos == map[start].oldpos); 20050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return map[start].newpos; 20150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 20350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic uint16_t 20450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehomakeKey16(struct SRBRoot *bundle, int32_t key) { 20550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (key >= 0) { 20650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return (uint16_t)key; 20750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 20850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return (uint16_t)(key + bundle->fLocalKeyLimit); /* offset in the pool bundle */ 20950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 21050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 21250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* 21350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Only called for UTF-16 v1 strings and duplicate UTF-16 v2 strings. 21450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * For unique UTF-16 v2 strings, res_write16() sees fRes != RES_BOGUS 21550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * and exits early. 21650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 21750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 21850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostring_write16(struct SRBRoot *bundle, struct SResource *res, UErrorCode *status) { 21950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *same; 22050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if ((same = res->u.fString.fSame) != NULL) { 22150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* This is a duplicate. */ 22250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (same->fRes == RES_BOGUS) { 22350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* The original has not been visited yet. */ 22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho string_write16(bundle, same, status); 22550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 22650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = same->fRes; 22750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fWritten = same->fWritten; 22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 23150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 23250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoarray_write16(struct SRBRoot *bundle, struct SResource *res, 23350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 23450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *current; 23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t res16 = 0; 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 23750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(*status)) { 23850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 23950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 24050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (res->u.fArray.fCount == 0 && gFormatVersion > 1) { 24150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_EMPTY_RESOURCE(URES_ARRAY); 24250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fWritten = TRUE; 24350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 24450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 24550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (current = res->u.fArray.fFirst; current != NULL; current = current->fNext) { 24650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_write16(bundle, current, status); 24750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res16 |= makeRes16(current->fRes); 24850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 24950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_SUCCESS(*status) && res->u.fArray.fCount <= 0xffff && res16 >= 0 && gFormatVersion > 1) { 25050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint16_t *p16 = reserve16BitUnits(bundle, 1 + res->u.fArray.fCount, status); 25150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_SUCCESS(*status)) { 25250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_RESOURCE(URES_ARRAY16, bundle->f16BitUnitsLength); 25350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *p16++ = (uint16_t)res->u.fArray.fCount; 25450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (current = res->u.fArray.fFirst; current != NULL; current = current->fNext) { 25550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *p16++ = (uint16_t)makeRes16(current->fRes); 25650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 25750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnitsLength += 1 + res->u.fArray.fCount; 25850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fWritten = TRUE; 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 26150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 26350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 26450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotable_write16(struct SRBRoot *bundle, struct SResource *res, 26550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 26650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *current; 26750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t maxKey = 0, maxPoolKey = 0x80000000; 26850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t res16 = 0; 26950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool hasLocalKeys = FALSE, hasPoolKeys = FALSE; 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 27150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(*status)) { 27250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 27350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 27450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (res->u.fTable.fCount == 0 && gFormatVersion > 1) { 27550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_EMPTY_RESOURCE(URES_TABLE); 27650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fWritten = TRUE; 27750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 27850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 27950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Find the smallest table type that fits the data. */ 28050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) { 28150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t key; 28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_write16(bundle, current, status); 28350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->fKeyMap == NULL) { 28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho key = current->fKey; 28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 28650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho key = current->fKey = mapKey(bundle, current->fKey); 28750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 28850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (key >= 0) { 28950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho hasLocalKeys = TRUE; 29050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (key > maxKey) { 29150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho maxKey = key; 29250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 29350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 29450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho hasPoolKeys = TRUE; 29550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (key > maxPoolKey) { 29650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho maxPoolKey = key; 29750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 29850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 29950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res16 |= makeRes16(current->fRes); 30050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 30150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(*status)) { 30250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 30350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 30450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(res->u.fTable.fCount > (uint32_t)bundle->fMaxTableLength) { 30550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fMaxTableLength = res->u.fTable.fCount; 30650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 30750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho maxPoolKey &= 0x7fffffff; 30850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (res->u.fTable.fCount <= 0xffff && 30950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (!hasLocalKeys || maxKey < bundle->fLocalKeyLimit) && 31050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (!hasPoolKeys || maxPoolKey < (0x10000 - bundle->fLocalKeyLimit)) 31150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ) { 31250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (res16 >= 0 && gFormatVersion > 1) { 31350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint16_t *p16 = reserve16BitUnits(bundle, 1 + res->u.fTable.fCount * 2, status); 31450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_SUCCESS(*status)) { 31550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 16-bit count, key offsets and values */ 31650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_RESOURCE(URES_TABLE16, bundle->f16BitUnitsLength); 31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *p16++ = (uint16_t)res->u.fTable.fCount; 31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) { 31950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *p16++ = makeKey16(bundle, current->fKey); 32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 32150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) { 32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *p16++ = (uint16_t)makeRes16(current->fRes); 32350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 32450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnitsLength += 1 + res->u.fTable.fCount * 2; 32550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fWritten = TRUE; 32650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 32850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 16-bit count, 16-bit key offsets, 32-bit values */ 32950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fTable.fType = URES_TABLE; 33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 33250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 32-bit count, key offsets and values */ 33350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fTable.fType = URES_TABLE32; 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 33750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 33850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_write16(struct SRBRoot *bundle, struct SResource *res, 33950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(*status) || res == NULL) { 34150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 34250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 34350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (res->fRes != RES_BOGUS) { 34450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 34550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * The resource item word was already precomputed, which means 34650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * no further data needs to be written. 34750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * This might be an integer, or an empty or UTF-16 v2 string, 34850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * an empty binary, etc. 34950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 35250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch (res->fType) { 35350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_STRING: 35450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho string_write16(bundle, res, status); 35550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 35650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ARRAY: 35750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho array_write16(bundle, res, status); 35850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 35950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE: 36050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho table_write16(bundle, res, status); 36150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 36250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 36350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Only a few resource types write 16-bit units. */ 36450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 36550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 36650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 36850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* 36950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Only called for UTF-16 v1 strings. 37050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * For UTF-16 v2 strings, res_preWrite() sees fRes != RES_BOGUS 37150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * and exits early. 37250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 37350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 37450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostring_preWrite(uint32_t *byteOffset, 37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle, struct SResource *res, 37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Write the UTF-16 v1 string. */ 37850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_RESOURCE(URES_STRING, *byteOffset >> 2); 37950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += 4 + (res->u.fString.fLength + 1) * U_SIZEOF_UCHAR; 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 38250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 38350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehobin_preWrite(uint32_t *byteOffset, 38450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle, struct SResource *res, 38550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t pad = 0; 38750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t dataStart = *byteOffset + sizeof(res->u.fBinaryValue.fLength); 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dataStart % BIN_ALIGNMENT) { 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pad = (BIN_ALIGNMENT - dataStart % BIN_ALIGNMENT); 39150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += pad; /* pad == 4 or 8 or 12 */ 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 39350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_RESOURCE(URES_BINARY, *byteOffset >> 2); 39450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += 4 + res->u.fBinaryValue.fLength; 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 39750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 39850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoarray_preWrite(uint32_t *byteOffset, 39950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle, struct SResource *res, 40050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 40150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *current; 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 40350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(*status)) { 40450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 40550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 40650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (current = res->u.fArray.fFirst; current != NULL; current = current->fNext) { 40750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_preWrite(byteOffset, bundle, current, status); 40850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 40950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_RESOURCE(URES_ARRAY, *byteOffset >> 2); 41050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += (1 + res->u.fArray.fCount) * 4; 41150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 41350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 41450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehotable_preWrite(uint32_t *byteOffset, 41550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle, struct SResource *res, 41650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 41750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *current; 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 42050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 42250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) { 42350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_preWrite(byteOffset, bundle, current, status); 42450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 42550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (res->u.fTable.fType == URES_TABLE) { 42650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 16-bit count, 16-bit key offsets, 32-bit values */ 42750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_RESOURCE(URES_TABLE, *byteOffset >> 2); 42850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += 2 + res->u.fTable.fCount * 6; 42950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 43050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 32-bit count, key offsets and values */ 43150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_RESOURCE(URES_TABLE32, *byteOffset >> 2); 43250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += 4 + res->u.fTable.fCount * 8; 43350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 43450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 43650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 43750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_preWrite(uint32_t *byteOffset, 43850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle, struct SResource *res, 43950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 44050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(*status) || res == NULL) { 44150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 44250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 44350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (res->fRes != RES_BOGUS) { 44450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 44550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * The resource item word was already precomputed, which means 44650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * no further data needs to be written. 44750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * This might be an integer, or an empty or UTF-16 v2 string, 44850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * an empty binary, etc. 44950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 45050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 45150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 45250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch (res->fType) { 45350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_STRING: 45450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho string_preWrite(byteOffset, bundle, res, status); 45550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 45650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ALIAS: 45750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_RESOURCE(URES_ALIAS, *byteOffset >> 2); 45850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += 4 + (res->u.fString.fLength + 1) * U_SIZEOF_UCHAR; 45950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 46050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_INT_VECTOR: 46150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (res->u.fIntVector.fCount == 0 && gFormatVersion > 1) { 46250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_EMPTY_RESOURCE(URES_INT_VECTOR); 46350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fWritten = TRUE; 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 46550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_RESOURCE(URES_INT_VECTOR, *byteOffset >> 2); 46650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += (1 + res->u.fIntVector.fCount) * 4; 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 46850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 46950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_BINARY: 47050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bin_preWrite(byteOffset, bundle, res, status); 47150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 47250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_INT: 47350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 47450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ARRAY: 47550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho array_preWrite(byteOffset, bundle, res, status); 47650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 47750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE: 47850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho table_preWrite(byteOffset, bundle, res, status); 47950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 48050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 48150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *status = U_INTERNAL_PROGRAM_ERROR; 48250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 48350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 48450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += calcPadding(*byteOffset); 48550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 48750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* 48850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Only called for UTF-16 v1 strings. For UTF-16 v2 strings, 48950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * res_write() sees fWritten and exits early. 49050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 49150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void string_write(UNewDataMemory *mem, uint32_t *byteOffset, 49250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle, struct SResource *res, 49350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 49450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Write the UTF-16 v1 string. */ 49550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length = res->u.fString.fLength; 49650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_write32(mem, length); 49750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_writeUString(mem, res->u.fString.fChars, length + 1); 49850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += 4 + (length + 1) * U_SIZEOF_UCHAR; 49950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fWritten = TRUE; 50050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 50250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void alias_write(UNewDataMemory *mem, uint32_t *byteOffset, 50350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle, struct SResource *res, 50450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 50550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length = res->u.fString.fLength; 50650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_write32(mem, length); 50750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_writeUString(mem, res->u.fString.fChars, length + 1); 50850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += 4 + (length + 1) * U_SIZEOF_UCHAR; 50950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 51150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void array_write(UNewDataMemory *mem, uint32_t *byteOffset, 51250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle, struct SResource *res, 51350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 51450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t i; 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 51650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *current = NULL; 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 51850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(*status)) { 51950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 52050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 52150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (i = 0, current = res->u.fArray.fFirst; current != NULL; ++i, current = current->fNext) { 52250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_write(mem, byteOffset, bundle, current, status); 52350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 52450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho assert(i == res->u.fArray.fCount); 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 52650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_write32(mem, res->u.fArray.fCount); 52750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (current = res->u.fArray.fFirst; current != NULL; current = current->fNext) { 52850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_write32(mem, current->fRes); 52950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 53050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += (1 + res->u.fArray.fCount) * 4; 53150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 53350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void intvector_write(UNewDataMemory *mem, uint32_t *byteOffset, 53450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle, struct SResource *res, 53550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 53650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t i = 0; 53750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_write32(mem, res->u.fIntVector.fCount); 53850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for(i = 0; i<res->u.fIntVector.fCount; i++) { 53950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_write32(mem, res->u.fIntVector.fArray[i]); 54050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 54150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += (1 + res->u.fIntVector.fCount) * 4; 54250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 54450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void bin_write(UNewDataMemory *mem, uint32_t *byteOffset, 54550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle, struct SResource *res, 54650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 54750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t pad = 0; 54850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t dataStart = *byteOffset + sizeof(res->u.fBinaryValue.fLength); 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 55050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (dataStart % BIN_ALIGNMENT) { 55150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pad = (BIN_ALIGNMENT - dataStart % BIN_ALIGNMENT); 55250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_writePadding(mem, pad); /* pad == 4 or 8 or 12 */ 55350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += pad; 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 55650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_write32(mem, res->u.fBinaryValue.fLength); 55750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (res->u.fBinaryValue.fLength > 0) { 55850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_writeBlock(mem, res->u.fBinaryValue.fData, res->u.fBinaryValue.fLength); 55950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 56050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += 4 + res->u.fBinaryValue.fLength; 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 56350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void table_write(UNewDataMemory *mem, uint32_t *byteOffset, 56450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle, struct SResource *res, 56550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 56650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *current; 56750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t i; 56850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 57050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 57250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (i = 0, current = res->u.fTable.fFirst; current != NULL; ++i, current = current->fNext) { 57350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho assert(i < res->u.fTable.fCount); 57450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_write(mem, byteOffset, bundle, current, status); 57550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 57650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho assert(i == res->u.fTable.fCount); 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 57850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(res->u.fTable.fType == URES_TABLE) { 57950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_write16(mem, (uint16_t)res->u.fTable.fCount); 58050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) { 58150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_write16(mem, makeKey16(bundle, current->fKey)); 58250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 58350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += (1 + res->u.fTable.fCount)* 2; 58450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if ((res->u.fTable.fCount & 1) == 0) { 58550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 16-bit count and even number of 16-bit key offsets need padding before 32-bit resource items */ 58650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_writePadding(mem, 2); 58750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += 2; 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 58950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else /* URES_TABLE32 */ { 59050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_write32(mem, res->u.fTable.fCount); 59150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) { 59250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_write32(mem, (uint32_t)current->fKey); 59350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 59450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += (1 + res->u.fTable.fCount)* 4; 59550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 59650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) { 59750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_write32(mem, current->fRes); 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 59950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += res->u.fTable.fCount * 4; 60050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 60250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid res_write(UNewDataMemory *mem, uint32_t *byteOffset, 60350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle, struct SResource *res, 60450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 60550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint8_t paddingSize; 60650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 60750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(*status) || res == NULL) { 60850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 60950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 61050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (res->fWritten) { 61150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho assert(res->fRes != RES_BOGUS); 61250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 61350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 61450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch (res->fType) { 61550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_STRING: 61650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho string_write (mem, byteOffset, bundle, res, status); 61750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 61850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ALIAS: 61950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho alias_write (mem, byteOffset, bundle, res, status); 62050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 62150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_INT_VECTOR: 62250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho intvector_write (mem, byteOffset, bundle, res, status); 62350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 62450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_BINARY: 62550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bin_write (mem, byteOffset, bundle, res, status); 62650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 62750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_INT: 62850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; /* fRes was set by int_open() */ 62950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_ARRAY: 63050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho array_write (mem, byteOffset, bundle, res, status); 63150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 63250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case URES_TABLE: 63350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho table_write (mem, byteOffset, bundle, res, status); 63450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 63550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 63650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *status = U_INTERNAL_PROGRAM_ERROR; 63750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 63850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 63950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho paddingSize = calcPadding(*byteOffset); 64050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (paddingSize > 0) { 64150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_writePadding(mem, paddingSize); 64250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *byteOffset += paddingSize; 64350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 64450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fWritten = TRUE; 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 64750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid bundle_write(struct SRBRoot *bundle, 64850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *outputDir, const char *outputPkg, 64950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char *writtenFilename, int writtenFilenameLen, 65050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode *status) { 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UNewDataMemory *mem = NULL; 65250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uint32_t byteOffset = 0; 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t top, size; 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char dataName[1024]; 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t indexes[URES_INDEX_TOP]; 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 65750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle_compactKeys(bundle, status); 65850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 65950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Add padding bytes to fKeys so that fKeysTop is 4-aligned. 66050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Safe because the capacity is a multiple of 4. 66150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 66250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while (bundle->fKeysTop & 3) { 66350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fKeys[bundle->fKeysTop++] = (char)0xaa; 66450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 66550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 66650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * In URES_TABLE, use all local key offsets that fit into 16 bits, 66750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * and use the remaining 16-bit offsets for pool key offsets 66850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * if there are any. 66950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * If there are no local keys, then use the whole 16-bit space 67050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * for pool key offsets. 67150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Note: This cannot be changed without changing the major formatVersion. 67250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 67350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->fKeysBottom < bundle->fKeysTop) { 67450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->fKeysTop <= 0x10000) { 67550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fLocalKeyLimit = bundle->fKeysTop; 67650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 67750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fLocalKeyLimit = 0x10000; 67850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 67950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 68050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fLocalKeyLimit = 0; 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 68350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle_compactStrings(bundle, status); 68450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_write16(bundle, bundle->fRoot, status); 68550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->f16BitUnitsLength & 1) { 68650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnits[bundle->f16BitUnitsLength++] = 0xaaaa; /* pad to multiple of 4 bytes */ 68750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 68850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* all keys have been mapped */ 68950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(bundle->fKeyMap); 69050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fKeyMap = NULL; 69150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 69250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho byteOffset = bundle->fKeysTop + bundle->f16BitUnitsLength * 2; 69350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_preWrite(&byteOffset, bundle, bundle->fRoot, status); 69450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 69550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* total size including the root item */ 69650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho top = byteOffset; 69750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 70250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (writtenFilename && writtenFilenameLen) { 70350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *writtenFilename = 0; 70450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 70550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (writtenFilename) { 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t off = 0, len = 0; 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (outputDir) { 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = (int32_t)uprv_strlen(outputDir); 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len > writtenFilenameLen) { 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = writtenFilenameLen; 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(writtenFilename, outputDir, len); 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (writtenFilenameLen -= len) { 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru off += len; 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru writtenFilename[off] = U_FILE_SEP_CHAR; 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (--writtenFilenameLen) { 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++off; 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(outputPkg != NULL) 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(writtenFilename+off, outputPkg); 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru off += (int32_t)uprv_strlen(outputPkg); 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru writtenFilename[off] = '_'; 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++off; 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = (int32_t)uprv_strlen(bundle->fLocale); 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len > writtenFilenameLen) { 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = writtenFilenameLen; 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(writtenFilename + off, bundle->fLocale, len); 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (writtenFilenameLen -= len) { 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru off += len; 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = 5; 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (len > writtenFilenameLen) { 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = writtenFilenameLen; 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strncpy(writtenFilename + off, ".res", len); 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(outputPkg) 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(dataName, outputPkg); 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(dataName, "_"); 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcat(dataName, bundle->fLocale); 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(dataName, bundle->fLocale); 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 75650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memcpy(dataInfo.formatVersion, gFormatVersions + gFormatVersion, sizeof(UVersionInfo)); 75750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru mem = udata_create(outputDir, "res", dataName, &dataInfo, (gIncludeCopyright==TRUE)? U_COPYRIGHT_STRING:NULL, status); 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)){ 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* write the root item */ 76450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_write32(mem, bundle->fRoot->fRes); 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * formatVersion 1.1 (ICU 2.8): 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * write int32_t indexes[] after root and before the strings 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * to make it easier to parse resource bundles in icuswap or from Java etc. 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memset(indexes, 0, sizeof(indexes)); 77250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho indexes[URES_INDEX_LENGTH]= bundle->fIndexLength; 77350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho indexes[URES_INDEX_KEYS_TOP]= bundle->fKeysTop>>2; 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexes[URES_INDEX_RESOURCES_TOP]= (int32_t)(top>>2); 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexes[URES_INDEX_BUNDLE_TOP]= indexes[URES_INDEX_RESOURCES_TOP]; 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexes[URES_INDEX_MAX_TABLE_LENGTH]= bundle->fMaxTableLength; 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * formatVersion 1.2 (ICU 3.6): 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * write indexes[URES_INDEX_ATTRIBUTES] with URES_ATT_NO_FALLBACK set or not set 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * the memset() above initialized all indexes[] to 0 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 78350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->noFallback) { 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru indexes[URES_INDEX_ATTRIBUTES]=URES_ATT_NO_FALLBACK; 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 78650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 78750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * formatVersion 2.0 (ICU 4.4): 78850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * more compact string value storage, optional pool bundle 78950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 79050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (URES_INDEX_16BIT_TOP < bundle->fIndexLength) { 79150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho indexes[URES_INDEX_16BIT_TOP] = (bundle->fKeysTop>>2) + (bundle->f16BitUnitsLength>>1); 79250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 79350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (URES_INDEX_POOL_CHECKSUM < bundle->fIndexLength) { 79450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->fIsPoolBundle) { 79550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho indexes[URES_INDEX_ATTRIBUTES] |= URES_ATT_IS_POOL_BUNDLE | URES_ATT_NO_FALLBACK; 79650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho indexes[URES_INDEX_POOL_CHECKSUM] = 79750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (int32_t)computeCRC((char *)(bundle->fKeys + bundle->fKeysBottom), 79850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (uint32_t)(bundle->fKeysTop - bundle->fKeysBottom), 79950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 0); 80050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (gUsePoolBundle) { 80150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho indexes[URES_INDEX_ATTRIBUTES] |= URES_ATT_USES_POOL_BUNDLE; 80250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho indexes[URES_INDEX_POOL_CHECKSUM] = bundle->fPoolChecksum; 80350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 80450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* write the indexes[] */ 80750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_writeBlock(mem, indexes, bundle->fIndexLength*4); 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* write the table key strings */ 81050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_writeBlock(mem, bundle->fKeys+bundle->fKeysBottom, 81150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fKeysTop-bundle->fKeysBottom); 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 81350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* write the v2 UTF-16 strings, URES_TABLE16 and URES_ARRAY16 */ 81450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho udata_writeBlock(mem, bundle->f16BitUnits, bundle->f16BitUnitsLength*2); 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* write all of the bundle contents: the root item and its children */ 81750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho byteOffset = bundle->fKeysTop + bundle->f16BitUnitsLength * 2; 81850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_write(mem, &byteOffset, bundle, bundle->fRoot, status); 81950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho assert(byteOffset == top); 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size = udata_finish(mem, status); 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(top != size) { 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "genrb error: wrote %u bytes but counted %u\n", 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (int)size, (int)top); 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Opening Functions */ 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 83150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* gcc 4.2 complained "no previous prototype for res_open" without this prototype... */ 83250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostruct SResource* res_open(struct SRBRoot *bundle, const char *tag, 83350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const struct UString* comment, UErrorCode* status); 83450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 83550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostruct SResource* res_open(struct SRBRoot *bundle, const char *tag, 83650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const struct UString* comment, UErrorCode* status){ 83750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *res; 83850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t key = bundle_addtag(bundle, tag, status); 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res = (struct SResource *) uprv_malloc(sizeof(struct SResource)); 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (res == NULL) { 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memset(res, 0, sizeof(struct SResource)); 84950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fKey = key; 85050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = RES_BOGUS; 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 852c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ustr_init(&res->fComment); 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(comment != NULL){ 854c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ustr_cpy(&res->fComment, comment, status); 85550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(*status)) { 85650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_close(res); 85750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return NULL; 85850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return res; 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 862c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 863c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustruct SResource* res_none() { 86450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return (struct SResource*)&kNoResource; 865c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru} 866c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 86750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostruct SResource* table_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status) { 86850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *res = res_open(bundle, tag, comment, status); 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->fType = URES_TABLE; 87350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fTable.fRoot = bundle; 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return res; 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct SResource* array_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status) { 87850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *res = res_open(bundle, tag, comment, status); 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->fType = URES_ARRAY; 88350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return res; 88450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 88650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t U_CALLCONV 88750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostring_hash(const UHashTok key) { 88850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const struct SResource *res = (struct SResource *)key.pointer; 88950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return uhash_hashUCharsN(res->u.fString.fChars, res->u.fString.fLength); 89050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 89250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool U_CALLCONV 89350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostring_comp(const UHashTok key1, const UHashTok key2) { 89450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const struct SResource *res1 = (struct SResource *)key1.pointer; 89550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const struct SResource *res2 = (struct SResource *)key2.pointer; 89650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0 == u_strCompare(res1->u.fString.fChars, res1->u.fString.fLength, 89750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res2->u.fString.fChars, res2->u.fString.fLength, 89850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho FALSE); 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 901b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostruct SResource *string_open(struct SRBRoot *bundle, const char *tag, const UChar *value, int32_t len, const struct UString* comment, UErrorCode *status) { 90250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *res = res_open(bundle, tag, comment, status); 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->fType = URES_STRING; 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 90850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (len == 0 && gFormatVersion > 1) { 90950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fString.fChars = &gEmptyString; 91050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = 0; 91150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fWritten = TRUE; 91250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return res; 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->u.fString.fLength = len; 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 91750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (gFormatVersion > 1) { 91850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* check for duplicates */ 91950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fString.fChars = (UChar *)value; 92050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->fStringSet == NULL) { 92150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode localStatus = U_ZERO_ERROR; /* if failure: just don't detect dups */ 92250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fStringSet = uhash_open(string_hash, string_comp, string_comp, &localStatus); 92350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 92450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fString.fSame = uhash_get(bundle->fStringSet, res); 92550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 92750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (res->u.fString.fSame == NULL) { 92850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* this is a new string */ 92950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fString.fChars = (UChar *) uprv_malloc(sizeof(UChar) * (len + 1)); 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 93150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (res->u.fString.fChars == NULL) { 93250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *status = U_MEMORY_ALLOCATION_ERROR; 93350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(res); 93450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return NULL; 93550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 93750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memcpy(res->u.fString.fChars, value, sizeof(UChar) * len); 93850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fString.fChars[len] = 0; 93950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->fStringSet != NULL) { 94050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* put it into the set for finding duplicates */ 94150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uhash_put(bundle->fStringSet, res, res, status); 94250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 94350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 94450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->fStringsForm != STRINGS_UTF16_V1) { 94550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (len <= MAX_IMPLICIT_STRING_LENGTH && !U16_IS_TRAIL(value[0]) && len == u_strlen(value)) { 94650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 94750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * This string will be stored without an explicit length. 94850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Runtime will detect !U16_IS_TRAIL(value[0]) and call u_strlen(). 94950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 95050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fString.fNumCharsForLength = 0; 95150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (len <= 0x3ee) { 95250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fString.fNumCharsForLength = 1; 95350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (len <= 0xfffff) { 95450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fString.fNumCharsForLength = 2; 95550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 95650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fString.fNumCharsForLength = 3; 95750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 95850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnitsLength += res->u.fString.fNumCharsForLength + len + 1; /* +1 for the NUL */ 95950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 96050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 96150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* this is a duplicate of fSame */ 96250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *same = res->u.fString.fSame; 96350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fString.fChars = same->u.fString.fChars; 96450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return res; 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* TODO: make alias_open and string_open use the same code */ 969b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostruct SResource *alias_open(struct SRBRoot *bundle, const char *tag, UChar *value, int32_t len, const struct UString* comment, UErrorCode *status) { 97050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *res = res_open(bundle, tag, comment, status); 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->fType = URES_ALIAS; 97550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (len == 0 && gFormatVersion > 1) { 97650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fString.fChars = &gEmptyString; 97750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_EMPTY_RESOURCE(URES_ALIAS); 97850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fWritten = TRUE; 97950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return res; 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->u.fString.fLength = len; 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->u.fString.fChars = (UChar *) uprv_malloc(sizeof(UChar) * (len + 1)); 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (res->u.fString.fChars == NULL) { 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(res); 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(res->u.fString.fChars, value, sizeof(UChar) * (len + 1)); 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return res; 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 994b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostruct SResource* intvector_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status) { 99550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *res = res_open(bundle, tag, comment, status); 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->fType = URES_INT_VECTOR; 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->u.fIntVector.fCount = 0; 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->u.fIntVector.fArray = (uint32_t *) uprv_malloc(sizeof(uint32_t) * RESLIST_MAX_INT_VECTOR); 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (res->u.fIntVector.fArray == NULL) { 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(res); 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return res; 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1011b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostruct SResource *int_open(struct SRBRoot *bundle, const char *tag, int32_t value, const struct UString* comment, UErrorCode *status) { 101250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *res = res_open(bundle, tag, comment, status); 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->fType = URES_INT; 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->u.fIntValue.fValue = value; 101850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_RESOURCE(URES_INT, value & 0x0FFFFFFF); 101950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fWritten = TRUE; 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return res; 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct SResource *bin_open(struct SRBRoot *bundle, const char *tag, uint32_t length, uint8_t *data, const char* fileName, const struct UString* comment, UErrorCode *status) { 102450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *res = res_open(bundle, tag, comment, status); 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->fType = URES_BINARY; 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->u.fBinaryValue.fLength = length; 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->u.fBinaryValue.fFileName = NULL; 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fileName!=NULL && uprv_strcmp(fileName, "") !=0){ 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->u.fBinaryValue.fFileName = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(fileName)+1)); 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_strcpy(res->u.fBinaryValue.fFileName,fileName); 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (length > 0) { 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->u.fBinaryValue.fData = (uint8_t *) uprv_malloc(sizeof(uint8_t) * length); 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (res->u.fBinaryValue.fData == NULL) { 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(res); 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(res->u.fBinaryValue.fData, data, length); 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->u.fBinaryValue.fData = NULL; 104950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (gFormatVersion > 1) { 105050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_EMPTY_RESOURCE(URES_BINARY); 105150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fWritten = TRUE; 105250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return res; 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 105850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostruct SRBRoot *bundle_open(const struct UString* comment, UBool isPoolBundle, UErrorCode *status) { 105950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SRBRoot *bundle; 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bundle = (struct SRBRoot *) uprv_malloc(sizeof(struct SRBRoot)); 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bundle == NULL) { 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memset(bundle, 0, sizeof(struct SRBRoot)); 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 107250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fKeys = (char *) uprv_malloc(sizeof(char) * KEY_SPACE_SIZE); 107350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fRoot = table_open(bundle, NULL, comment, status); 107450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->fKeys == NULL || bundle->fRoot == NULL || U_FAILURE(*status)) { 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(*status)) { 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 107850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle_close(bundle, status); 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 108250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fLocale = NULL; 108350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fKeysCapacity = KEY_SPACE_SIZE; 108450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* formatVersion 1.1: start fKeysTop after the root item and indexes[] */ 108550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fIsPoolBundle = isPoolBundle; 108650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (gUsePoolBundle || isPoolBundle) { 108750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fIndexLength = URES_INDEX_POOL_CHECKSUM + 1; 108850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (gFormatVersion >= 2) { 108950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fIndexLength = URES_INDEX_16BIT_TOP + 1; 109050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else /* formatVersion 1 */ { 109150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fIndexLength = URES_INDEX_ATTRIBUTES + 1; 109250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 109350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fKeysBottom = (1 /* root */ + bundle->fIndexLength) * 4; 109450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memset(bundle->fKeys, 0, bundle->fKeysBottom); 109550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fKeysTop = bundle->fKeysBottom; 109650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 109750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (gFormatVersion == 1) { 109850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fStringsForm = STRINGS_UTF16_V1; 109950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 110050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fStringsForm = STRINGS_UTF16_V2; 110150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 110250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return bundle; 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Closing Functions */ 1107c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void table_close(struct SResource *table) { 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *current = NULL; 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *prev = NULL; 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru current = table->u.fTable.fFirst; 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (current != NULL) { 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru prev = current; 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru current = current->fNext; 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1117c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(prev); 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru table->u.fTable.fFirst = NULL; 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1123c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void array_close(struct SResource *array) { 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *current = NULL; 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *prev = NULL; 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(array==NULL){ 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru current = array->u.fArray.fFirst; 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (current != NULL) { 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru prev = current; 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru current = current->fNext; 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1136c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru res_close(prev); 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru array->u.fArray.fFirst = NULL; 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1141c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void string_close(struct SResource *string) { 114250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (string->u.fString.fChars != NULL && 114350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho string->u.fString.fChars != &gEmptyString && 114450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho string->u.fString.fSame == NULL 114550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ) { 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(string->u.fString.fChars); 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru string->u.fString.fChars =NULL; 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1151c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void alias_close(struct SResource *alias) { 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (alias->u.fString.fChars != NULL) { 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(alias->u.fString.fChars); 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru alias->u.fString.fChars =NULL; 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1158c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void intvector_close(struct SResource *intvector) { 1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (intvector->u.fIntVector.fArray != NULL) { 1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(intvector->u.fIntVector.fArray); 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru intvector->u.fIntVector.fArray =NULL; 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1165c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void int_close(struct SResource *intres) { 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Intentionally left blank */ 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1169c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void bin_close(struct SResource *binres) { 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (binres->u.fBinaryValue.fData != NULL) { 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(binres->u.fBinaryValue.fData); 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru binres->u.fBinaryValue.fData = NULL; 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1176c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruvoid res_close(struct SResource *res) { 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (res != NULL) { 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(res->fType) { 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_STRING: 1180c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru string_close(res); 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_ALIAS: 1183c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru alias_close(res); 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_INT_VECTOR: 1186c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru intvector_close(res); 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_BINARY: 1189c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru bin_close(res); 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_INT: 1192c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int_close(res); 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_ARRAY: 1195c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru array_close(res); 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case URES_TABLE: 1198c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru table_close(res); 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Shouldn't happen */ 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1205c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ustr_deinit(&res->fComment); 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(res); 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid bundle_close(struct SRBRoot *bundle, UErrorCode *status) { 121150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res_close(bundle->fRoot); 121250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(bundle->fLocale); 121350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(bundle->fKeys); 121450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(bundle->fKeyMap); 121550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uhash_close(bundle->fStringSet); 121650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(bundle->f16BitUnits); 121750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(bundle); 121850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 122050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid bundle_closeString(struct SRBRoot *bundle, struct SResource *string) { 122150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->fStringSet != NULL) { 122250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uhash_remove(bundle->fStringSet, string); 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 122450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho string_close(string); 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Adding Functions */ 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid table_add(struct SResource *table, struct SResource *res, int linenumber, UErrorCode *status) { 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *current = NULL; 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResource *prev = NULL; 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru struct SResTable *list; 123250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *resKeyString; 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1237c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (res == &kNoResource) { 1238c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return; 1239c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* remember this linenumber to report to the user if there is a duplicate key */ 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->line = linenumber; 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* here we need to traverse the list */ 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru list = &(table->u.fTable); 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++(list->fCount); 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* is list still empty? */ 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (list->fFirst == NULL) { 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru list->fFirst = res; 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->fNext = NULL; 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 125550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho resKeyString = list->fRoot->fKeys + res->fKey; 125650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru current = list->fFirst; 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (current != NULL) { 126050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *currentKeyString = list->fRoot->fKeys + current->fKey; 126150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int diff; 126250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 126350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * formatVersion 1: compare key strings in native-charset order 126450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * formatVersion 2 and up: compare key strings in ASCII order 126550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 126650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (gFormatVersion == 1 || U_CHARSET_FAMILY == U_ASCII_FAMILY) { 126750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho diff = uprv_strcmp(currentKeyString, resKeyString); 126850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 126950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho diff = uprv_compareInvCharsAsAscii(currentKeyString, resKeyString); 127050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 127150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (diff < 0) { 1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru prev = current; 1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru current = current->fNext; 127450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (diff > 0) { 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we're either in front of list, or in middle */ 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (prev == NULL) { 1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* front of the list */ 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru list->fFirst = res; 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* middle of the list */ 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru prev->fNext = res; 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->fNext = current; 1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Key already exists! ERROR! */ 128850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho error(linenumber, "duplicate key '%s' in table, first appeared at line %d", currentKeyString, current->line); 1289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_UNSUPPORTED_ERROR; 1290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* end of list */ 1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru prev->fNext = res; 1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res->fNext = NULL; 1297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid array_add(struct SResource *array, struct SResource *res, UErrorCode *status) { 1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (array->u.fArray.fFirst == NULL) { 1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru array->u.fArray.fFirst = res; 1306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru array->u.fArray.fLast = res; 1307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru array->u.fArray.fLast->fNext = res; 1309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru array->u.fArray.fLast = res; 1310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (array->u.fArray.fCount)++; 1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid intvector_add(struct SResource *intvector, int32_t value, UErrorCode *status) { 1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *(intvector->u.fIntVector.fArray + intvector->u.fIntVector.fCount) = value; 1321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru intvector->u.fIntVector.fCount++; 1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Misc Functions */ 1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid bundle_setlocale(struct SRBRoot *bundle, UChar *locale, UErrorCode *status) { 1327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) { 1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bundle->fLocale!=NULL) { 1333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(bundle->fLocale); 1334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bundle->fLocale= (char*) uprv_malloc(sizeof(char) * (u_strlen(locale)+1)); 1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(bundle->fLocale == NULL) { 1339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /*u_strcpy(bundle->fLocale, locale);*/ 1344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(locale, bundle->fLocale, u_strlen(locale)+1); 1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 134850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const char * 134950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehogetKeyString(const struct SRBRoot *bundle, int32_t key) { 135050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (key < 0) { 135150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return bundle->fPoolBundleKeys + (key & 0x7fffffff); 135250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 135350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return bundle->fKeys + key; 135450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 135550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 135650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 135750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoconst char * 135850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehores_getKeyString(const struct SRBRoot *bundle, const struct SResource *res, char temp[8]) { 135950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (res->fKey == -1) { 136050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return NULL; 136150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 136250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return getKeyString(bundle, res->fKey); 136350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 136450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 136550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoconst char * 136650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehobundle_getKeyBytes(struct SRBRoot *bundle, int32_t *pLength) { 136750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *pLength = bundle->fKeysTop - bundle->fKeysBottom; 136850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return bundle->fKeys + bundle->fKeysBottom; 136950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 1370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 137250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehobundle_addKeyBytes(struct SRBRoot *bundle, const char *keyBytes, int32_t length, UErrorCode *status) { 137350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t keypos; 1374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 1376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 137850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (length < 0 || (keyBytes == NULL && length != 0)) { 137950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *status = U_ILLEGAL_ARGUMENT_ERROR; 1380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 138250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (length == 0) { 138350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return bundle->fKeysTop; 138450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 1385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 138650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho keypos = bundle->fKeysTop; 138750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fKeysTop += length; 138850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->fKeysTop >= bundle->fKeysCapacity) { 1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* overflow - resize the keys buffer */ 1390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bundle->fKeysCapacity += KEY_SPACE_SIZE; 1391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bundle->fKeys = uprv_realloc(bundle->fKeys, bundle->fKeysCapacity); 1392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(bundle->fKeys == NULL) { 1393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 1394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return -1; 1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 139850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_memcpy(bundle->fKeys + keypos, keyBytes, length); 139950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 140050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return keypos; 140150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 140250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 140350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t 140450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehobundle_addtag(struct SRBRoot *bundle, const char *tag, UErrorCode *status) { 140550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t keypos; 140650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 140750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(*status)) { 140850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return -1; 140950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 141050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 141150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (tag == NULL) { 141250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* no error: the root table and array items have no keys */ 141350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return -1; 141450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 141650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho keypos = bundle_addKeyBytes(bundle, tag, (int32_t)(uprv_strlen(tag) + 1), status); 141750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_SUCCESS(*status)) { 141850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ++bundle->fKeysCount; 141950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 1420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return keypos; 1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 142250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 142350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t 142450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehocompareInt32(int32_t lPos, int32_t rPos) { 142550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 142650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Compare possibly-negative key offsets. Don't just return lPos - rPos 142750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * because that is prone to negative-integer underflows. 142850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 142950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (lPos < rPos) { 143050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return -1; 143150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (lPos > rPos) { 143250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 1; 143350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 143450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 143550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 143650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 143750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 143850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t U_CALLCONV 143950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehocompareKeySuffixes(const void *context, const void *l, const void *r) { 144050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const struct SRBRoot *bundle=(const struct SRBRoot *)context; 144150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t lPos = ((const KeyMapEntry *)l)->oldpos; 144250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t rPos = ((const KeyMapEntry *)r)->oldpos; 144350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *lStart = getKeyString(bundle, lPos); 144450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *lLimit = lStart; 144550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *rStart = getKeyString(bundle, rPos); 144650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *rLimit = rStart; 144750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t diff; 144850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while (*lLimit != 0) { ++lLimit; } 144950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while (*rLimit != 0) { ++rLimit; } 145050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* compare keys in reverse character order */ 145150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while (lStart < lLimit && rStart < rLimit) { 145250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho diff = (int32_t)(uint8_t)*--lLimit - (int32_t)(uint8_t)*--rLimit; 145350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (diff != 0) { 145450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return diff; 145550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 145650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 145750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* sort equal suffixes by descending key length */ 145850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho diff = (int32_t)(rLimit - rStart) - (int32_t)(lLimit - lStart); 145950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (diff != 0) { 146050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return diff; 146150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 146250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Sort pool bundle keys first (negative oldpos), and otherwise keys in parsing order. */ 146350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return compareInt32(lPos, rPos); 146450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 146550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 146650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t U_CALLCONV 146750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehocompareKeyNewpos(const void *context, const void *l, const void *r) { 146850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return compareInt32(((const KeyMapEntry *)l)->newpos, ((const KeyMapEntry *)r)->newpos); 146950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 147050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 147150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t U_CALLCONV 147250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehocompareKeyOldpos(const void *context, const void *l, const void *r) { 147350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return compareInt32(((const KeyMapEntry *)l)->oldpos, ((const KeyMapEntry *)r)->oldpos); 147450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 147550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 147650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 147750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehobundle_compactKeys(struct SRBRoot *bundle, UErrorCode *status) { 147850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho KeyMapEntry *map; 147950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char *keys; 148050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t i; 148150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t keysCount = bundle->fPoolBundleKeysCount + bundle->fKeysCount; 148250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(*status) || bundle->fKeysCount == 0 || bundle->fKeyMap != NULL) { 148350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 148450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 148550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho map = (KeyMapEntry *)uprv_malloc(keysCount * sizeof(KeyMapEntry)); 148650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (map == NULL) { 148750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *status = U_MEMORY_ALLOCATION_ERROR; 148850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 148950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 149050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho keys = (char *)bundle->fPoolBundleKeys; 149150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (i = 0; i < bundle->fPoolBundleKeysCount; ++i) { 149250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho map[i].oldpos = 149350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (int32_t)(keys - bundle->fPoolBundleKeys) | 0x80000000; /* negative oldpos */ 149450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho map[i].newpos = 0; 149550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while (*keys != 0) { ++keys; } /* skip the key */ 149650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ++keys; /* skip the NUL */ 149750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 149850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho keys = bundle->fKeys + bundle->fKeysBottom; 149950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (; i < keysCount; ++i) { 150050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho map[i].oldpos = (int32_t)(keys - bundle->fKeys); 150150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho map[i].newpos = 0; 150250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while (*keys != 0) { ++keys; } /* skip the key */ 150350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ++keys; /* skip the NUL */ 150450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 150550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Sort the keys so that each one is immediately followed by all of its suffixes. */ 150650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_sortArray(map, keysCount, (int32_t)sizeof(KeyMapEntry), 150750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho compareKeySuffixes, bundle, FALSE, status); 150850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 150950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Make suffixes point into earlier, longer strings that contain them 151050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * and mark the old, now unused suffix bytes as deleted. 151150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 151250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_SUCCESS(*status)) { 151350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho keys = bundle->fKeys; 151450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (i = 0; i < keysCount;) { 151550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 151650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * This key is not a suffix of the previous one; 151750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * keep this one and delete the following ones that are 151850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * suffixes of this one. 151950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 152050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *key; 152150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *keyLimit; 152250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t j = i + 1; 152350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho map[i].newpos = map[i].oldpos; 152450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (j < keysCount && map[j].oldpos < 0) { 152550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Key string from the pool bundle, do not delete. */ 152650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho i = j; 152750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho continue; 152850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 152950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho key = getKeyString(bundle, map[i].oldpos); 153050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (keyLimit = key; *keyLimit != 0; ++keyLimit) {} 153150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (; j < keysCount && map[j].oldpos >= 0; ++j) { 153250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *k; 153350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho char *suffix; 153450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const char *suffixLimit; 153550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t offset; 153650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho suffix = keys + map[j].oldpos; 153750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (suffixLimit = suffix; *suffixLimit != 0; ++suffixLimit) {} 153850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho offset = (int32_t)(keyLimit - key) - (suffixLimit - suffix); 153950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (offset < 0) { 154050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; /* suffix cannot be longer than the original */ 154150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 154250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Is it a suffix of the earlier, longer key? */ 154350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (k = keyLimit; suffix < suffixLimit && *--k == *--suffixLimit;) {} 154450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (suffix == suffixLimit && *k == *suffixLimit) { 154550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho map[j].newpos = map[i].oldpos + offset; /* yes, point to the earlier key */ 154650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* mark the suffix as deleted */ 154750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while (*suffix != 0) { *suffix++ = 1; } 154850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *suffix = 1; 154950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 155050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; /* not a suffix, restart from here */ 155150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 155250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 155350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho i = j; 155450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 155550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 155650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Re-sort by newpos, then modify the key characters array in-place 155750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * to squeeze out unused bytes, and readjust the newpos offsets. 155850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 155950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_sortArray(map, keysCount, (int32_t)sizeof(KeyMapEntry), 156050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho compareKeyNewpos, NULL, FALSE, status); 156150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_SUCCESS(*status)) { 156250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t oldpos, newpos, limit; 156350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho oldpos = newpos = bundle->fKeysBottom; 156450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho limit = bundle->fKeysTop; 156550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* skip key offsets that point into the pool bundle rather than this new bundle */ 156650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (i = 0; i < keysCount && map[i].newpos < 0; ++i) {} 156750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (i < keysCount) { 156850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while (oldpos < limit) { 156950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (keys[oldpos] == 1) { 157050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ++oldpos; /* skip unused bytes */ 157150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 157250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* adjust the new offsets for keys starting here */ 157350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while (i < keysCount && map[i].newpos == oldpos) { 157450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho map[i++].newpos = newpos; 157550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 157650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* move the key characters to their new position */ 157750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho keys[newpos++] = keys[oldpos++]; 157850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 157950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 158050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho assert(i == keysCount); 158150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 158250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fKeysTop = newpos; 158350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Re-sort once more, by old offsets for binary searching. */ 158450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_sortArray(map, keysCount, (int32_t)sizeof(KeyMapEntry), 158550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho compareKeyOldpos, NULL, FALSE, status); 158650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_SUCCESS(*status)) { 158750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* key size reduction by limit - newpos */ 158850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->fKeyMap = map; 158950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho map = NULL; 159050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 159150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 159250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 159350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(map); 159450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 159550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 159650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t U_CALLCONV 159750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehocompareStringSuffixes(const void *context, const void *l, const void *r) { 159850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *left = *((struct SResource **)l); 159950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *right = *((struct SResource **)r); 160050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *lStart = left->u.fString.fChars; 160150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *lLimit = lStart + left->u.fString.fLength; 160250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *rStart = right->u.fString.fChars; 160350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *rLimit = rStart + right->u.fString.fLength; 160450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t diff; 160550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* compare keys in reverse character order */ 160650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while (lStart < lLimit && rStart < rLimit) { 160750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho diff = (int32_t)*--lLimit - (int32_t)*--rLimit; 160850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (diff != 0) { 160950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return diff; 161050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 161150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 161250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* sort equal suffixes by descending string length */ 161350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return right->u.fString.fLength - left->u.fString.fLength; 161450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 161550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 161650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t U_CALLCONV 161750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehocompareStringLengths(const void *context, const void *l, const void *r) { 161850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *left = *((struct SResource **)l); 161950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *right = *((struct SResource **)r); 162050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t diff; 162150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Make "is suffix of another string" compare greater than a non-suffix. */ 162250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho diff = (int)(left->u.fString.fSame != NULL) - (int)(right->u.fString.fSame != NULL); 162350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (diff != 0) { 162450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return diff; 162550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 162650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* sort by ascending string length */ 162750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return left->u.fString.fLength - right->u.fString.fLength; 162850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 162950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 163050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic int32_t 163150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostring_writeUTF16v2(struct SRBRoot *bundle, struct SResource *res, int32_t utf16Length) { 163250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t length = res->u.fString.fLength; 163350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = URES_MAKE_RESOURCE(URES_STRING_V2, utf16Length); 163450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fWritten = TRUE; 163550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch(res->u.fString.fNumCharsForLength) { 163650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case 0: 163750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 163850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case 1: 163950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnits[utf16Length++] = (uint16_t)(0xdc00 + length); 164050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 164150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case 2: 164250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnits[utf16Length] = (uint16_t)(0xdfef + (length >> 16)); 164350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnits[utf16Length + 1] = (uint16_t)length; 164450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho utf16Length += 2; 164550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 164650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case 3: 164750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnits[utf16Length] = 0xdfff; 164850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnits[utf16Length + 1] = (uint16_t)(length >> 16); 164950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnits[utf16Length + 2] = (uint16_t)length; 165050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho utf16Length += 3; 165150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 165250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 165350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; /* will not occur */ 165450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 165550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho u_memcpy(bundle->f16BitUnits + utf16Length, res->u.fString.fChars, length + 1); 165650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return utf16Length + length + 1; 165750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 165850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 165950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic void 166050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehobundle_compactStrings(struct SRBRoot *bundle, UErrorCode *status) { 166150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(*status)) { 166250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 166350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 166450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho switch(bundle->fStringsForm) { 166550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho case STRINGS_UTF16_V2: 166650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->f16BitUnitsLength > 0) { 166750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource **array; 166850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t count = uhash_count(bundle->fStringSet); 166950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t i, pos; 167050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 167150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Allocate enough space for the initial NUL and the UTF-16 v2 strings, 167250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * and some extra for URES_TABLE16 and URES_ARRAY16 values. 167350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Round down to an even number. 167450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 167550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t utf16Length = (bundle->f16BitUnitsLength + 20000) & ~1; 167650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnits = (UChar *)uprv_malloc(utf16Length * U_SIZEOF_UCHAR); 167750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho array = (struct SResource **)uprv_malloc(count * sizeof(struct SResource **)); 167850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (bundle->f16BitUnits == NULL || array == NULL) { 167950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(bundle->f16BitUnits); 168050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnits = NULL; 168150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(array); 168250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *status = U_MEMORY_ALLOCATION_ERROR; 168350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 168450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 168550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnitsCapacity = utf16Length; 168650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* insert the initial NUL */ 168750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnits[0] = 0; 168850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho utf16Length = 1; 168950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ++bundle->f16BitUnitsLength; 169050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (pos = -1, i = 0; i < count; ++i) { 169150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho array[i] = (struct SResource *)uhash_nextElement(bundle->fStringSet, &pos)->key.pointer; 169250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 169350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Sort the strings so that each one is immediately followed by all of its suffixes. */ 169450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_sortArray(array, count, (int32_t)sizeof(struct SResource **), 169550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho compareStringSuffixes, NULL, FALSE, status); 169650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 169750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Make suffixes point into earlier, longer strings that contain them. 169850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Temporarily use fSame and fSuffixOffset for suffix strings to 169950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * refer to the remaining ones. 170050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 170150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_SUCCESS(*status)) { 170250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (i = 0; i < count;) { 170350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 170450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * This string is not a suffix of the previous one; 170550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * write this one and subsume the following ones that are 170650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * suffixes of this one. 170750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 170850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *res = array[i]; 170950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *strLimit = res->u.fString.fChars + res->u.fString.fLength; 171050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t j; 171150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (j = i + 1; j < count; ++j) { 171250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *suffixRes = array[j]; 171350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *s; 171450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *suffix = suffixRes->u.fString.fChars; 171550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *suffixLimit = suffix + suffixRes->u.fString.fLength; 171650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t offset = res->u.fString.fLength - suffixRes->u.fString.fLength; 171750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (offset < 0) { 171850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; /* suffix cannot be longer than the original */ 171950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 172050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Is it a suffix of the earlier, longer key? */ 172150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (s = strLimit; suffix < suffixLimit && *--s == *--suffixLimit;) {} 172250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (suffix == suffixLimit && *s == *suffixLimit) { 172350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (suffixRes->u.fString.fNumCharsForLength == 0) { 172450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* yes, point to the earlier string */ 172550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho suffixRes->u.fString.fSame = res; 172650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho suffixRes->u.fString.fSuffixOffset = offset; 172750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 172850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* write the suffix by itself if we need explicit length */ 172950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 173050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 173150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; /* not a suffix, restart from here */ 173250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 173350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 173450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho i = j; 173550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 173650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 173750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* 173850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Re-sort the strings by ascending length (except suffixes last) 173950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * to optimize for URES_TABLE16 and URES_ARRAY16: 174050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Keep as many as possible within reach of 16-bit offsets. 174150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho */ 174250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_sortArray(array, count, (int32_t)sizeof(struct SResource **), 174350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho compareStringLengths, NULL, FALSE, status); 174450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_SUCCESS(*status)) { 174550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Write the non-suffix strings. */ 174650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (i = 0; i < count && array[i]->u.fString.fSame == NULL; ++i) { 174750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho utf16Length = string_writeUTF16v2(bundle, array[i], utf16Length); 174850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 174950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* Write the suffix strings. Make each point to the real string. */ 175050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (; i < count; ++i) { 175150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *res = array[i]; 175250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho struct SResource *same = res->u.fString.fSame; 175350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fRes = same->fRes + same->u.fString.fNumCharsForLength + res->u.fString.fSuffixOffset; 175450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->u.fString.fSame = NULL; 175550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho res->fWritten = TRUE; 175650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 175750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 175850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho assert(utf16Length <= bundle->f16BitUnitsLength); 175950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bundle->f16BitUnitsLength = utf16Length; 176050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho uprv_free(array); 176150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 176250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 176350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho default: 176450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 176550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 176650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 1767