reslist.c revision c69afcec261fc345fda8daf46f0ea6b4351dc777
1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*******************************************************************************
3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
4c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru*   Copyright (C) 2000-2008, 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
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define BIN_ALIGNMENT 16
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool gIncludeCopyright = FALSE;
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
30c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru/*
31c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru * res_none() returns the address of kNoResource,
32c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru * for use in non-error cases when no resource is to be added to the bundle.
33c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru * (NULL is used in error cases.)
34c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru */
35c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic struct SResource kNoResource = { RES_NONE };
36c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuint32_t res_write(UNewDataMemory *mem, struct SResource *res,
38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   uint32_t usedOffset, UErrorCode *status);
39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const UDataInfo dataInfo= {
41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    sizeof(UDataInfo),
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    0,
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_IS_BIG_ENDIAN,
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_CHARSET_FAMILY,
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    sizeof(UChar),
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    0,
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {0x52, 0x65, 0x73, 0x42},     /* dataFormat="resb" */
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {1, 2, 0, 0},                 /* formatVersion */
51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {1, 4, 0, 0}                  /* dataVersion take a look at version inside parsed resb*/
52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint8_t calcPadding(uint32_t size) {
55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* returns space we need to pad */
56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (uint8_t) ((size % sizeof(uint32_t)) ? (sizeof(uint32_t) - (size % sizeof(uint32_t))) : 0);
57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid setIncludeCopyright(UBool val){
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    gIncludeCopyright=val;
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool getIncludeCopyright(void){
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return gIncludeCopyright;
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Writing Functions */
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint32_t string_write(UNewDataMemory *mem, struct SResource *res,
70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             uint32_t usedOffset, UErrorCode *status) {
71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_write32(mem, res->u.fString.fLength);
72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_writeUString(mem, res->u.fString.fChars, res->u.fString.fLength + 1);
73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_writePadding(mem, calcPadding(res->fSize));
74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return usedOffset;
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Writing Functions */
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint32_t alias_write(UNewDataMemory *mem, struct SResource *res,
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                             uint32_t usedOffset, UErrorCode *status) {
81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_write32(mem, res->u.fString.fLength);
82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_writeUString(mem, res->u.fString.fChars, res->u.fString.fLength + 1);
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_writePadding(mem, calcPadding(res->fSize));
84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return usedOffset;
86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint32_t array_write(UNewDataMemory *mem, struct SResource *res,
89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            uint32_t usedOffset, UErrorCode *status) {
90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t *resources = NULL;
91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t  i         = 0;
92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *current = NULL;
94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (res->u.fArray.fCount > 0) {
100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        resources = (uint32_t *) uprv_malloc(sizeof(uint32_t) * res->u.fArray.fCount);
101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (resources == NULL) {
103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *status = U_MEMORY_ALLOCATION_ERROR;
104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return 0;
105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        current = res->u.fArray.fFirst;
108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        i = 0;
109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        while (current != NULL) {
111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (current->fType == URES_INT) {
112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                resources[i] = (current->fType << 28) | (current->u.fIntValue.fValue & 0xFFFFFFF);
113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else if (current->fType == URES_BINARY) {
114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                uint32_t uo = usedOffset;
115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                usedOffset    = res_write(mem, current, usedOffset, status);
117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                resources[i]  = (current->fType << 28) | (usedOffset >> 2);
118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                usedOffset   += current->fSize + calcPadding(current->fSize) - (usedOffset - uo);
119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                usedOffset    = res_write(mem, current, usedOffset, status);
121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                resources[i]  = (current->fType << 28) | (usedOffset >> 2);
122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                usedOffset   += current->fSize + calcPadding(current->fSize);
123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            i++;
126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            current = current->fNext;
127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* usedOffset += res->fSize + pad; */
130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        udata_write32(mem, res->u.fArray.fCount);
132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        udata_writeBlock(mem, resources, sizeof(uint32_t) * res->u.fArray.fCount);
133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(resources);
134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* array is empty */
136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        udata_write32(mem, 0);
137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return usedOffset;
140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint32_t intvector_write(UNewDataMemory *mem, struct SResource *res,
143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                uint32_t usedOffset, UErrorCode *status) {
144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  uint32_t i = 0;
145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_write32(mem, res->u.fIntVector.fCount);
146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for(i = 0; i<res->u.fIntVector.fCount; i++) {
147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      udata_write32(mem, res->u.fIntVector.fArray[i]);
148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return usedOffset;
151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint32_t bin_write(UNewDataMemory *mem, struct SResource *res,
154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                          uint32_t usedOffset, UErrorCode *status) {
155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t pad       = 0;
156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t extrapad  = calcPadding(res->fSize);
157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t dataStart = usedOffset + sizeof(res->u.fBinaryValue.fLength);
158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (dataStart % BIN_ALIGNMENT) {
160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        pad = (BIN_ALIGNMENT - dataStart % BIN_ALIGNMENT);
161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        udata_writePadding(mem, pad);
162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        usedOffset += pad;
163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_write32(mem, res->u.fBinaryValue.fLength);
166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (res->u.fBinaryValue.fLength > 0) {
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        udata_writeBlock(mem, res->u.fBinaryValue.fData, res->u.fBinaryValue.fLength);
168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_writePadding(mem, (BIN_ALIGNMENT - pad + extrapad));
170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return usedOffset;
172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint32_t int_write(UNewDataMemory *mem, struct SResource *res,
175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                          uint32_t usedOffset, UErrorCode *status) {
176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return usedOffset;
177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic uint32_t table_write(UNewDataMemory *mem, struct SResource *res,
180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            uint32_t usedOffset, UErrorCode *status) {
181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint8_t   pad       = 0;
182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t  i         = 0;
183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint16_t *keys16    = NULL;
184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t  *keys32    = NULL;
185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t *resources = NULL;
186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *current = NULL;
188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    pad = calcPadding(res->fSize);
194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (res->u.fTable.fCount > 0) {
196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(res->fType == URES_TABLE) {
197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            keys16 = (uint16_t *) uprv_malloc(sizeof(uint16_t) * res->u.fTable.fCount);
198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (keys16 == NULL) {
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                *status = U_MEMORY_ALLOCATION_ERROR;
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return 0;
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            keys32 = (int32_t *) uprv_malloc(sizeof(int32_t) * res->u.fTable.fCount);
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (keys32 == NULL) {
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                *status = U_MEMORY_ALLOCATION_ERROR;
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return 0;
207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        resources = (uint32_t *) uprv_malloc(sizeof(uint32_t) * res->u.fTable.fCount);
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (resources == NULL) {
213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_free(keys16);
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_free(keys32);
215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *status = U_MEMORY_ALLOCATION_ERROR;
216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return 0;
217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        current = res->u.fTable.fFirst;
220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        i       = 0;
221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        while (current != NULL) {
223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            assert(i < res->u.fTable.fCount);
224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* where the key is */
226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if(res->fType == URES_TABLE) {
227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                keys16[i] = (uint16_t) current->fKey;
228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                keys32[i] = current->fKey;
230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (current->fType == URES_INT) {
233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                resources[i] = (current->fType << 28) | (current->u.fIntValue.fValue & 0xFFFFFFF);
234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else if (current->fType == URES_BINARY) {
235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                uint32_t uo = usedOffset;
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                usedOffset    = res_write(mem, current, usedOffset, status);
238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                resources[i]  = (current->fType << 28) | (usedOffset >> 2);
239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                usedOffset   += current->fSize + calcPadding(current->fSize) - (usedOffset - uo);
240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                usedOffset    = res_write(mem, current, usedOffset, status);
242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                resources[i]  = (current->fType << 28) | (usedOffset >> 2);
243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                usedOffset   += current->fSize + calcPadding(current->fSize);
244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            i++;
247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            current = current->fNext;
248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(res->fType == URES_TABLE) {
251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_write16(mem, (uint16_t)res->u.fTable.fCount);
252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_writeBlock(mem, keys16, sizeof(uint16_t) * res->u.fTable.fCount);
254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_writePadding(mem, pad);
255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_write32(mem, res->u.fTable.fCount);
257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_writeBlock(mem, keys32, sizeof(int32_t) * res->u.fTable.fCount);
259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        udata_writeBlock(mem, resources, sizeof(uint32_t) * res->u.fTable.fCount);
262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(keys16);
264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(keys32);
265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(resources);
266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* table is empty */
268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(res->fType == URES_TABLE) {
269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_write16(mem, 0);
270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_writePadding(mem, pad);
271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            udata_write32(mem, 0);
273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return usedOffset;
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuint32_t res_write(UNewDataMemory *mem, struct SResource *res,
280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   uint32_t usedOffset, UErrorCode *status) {
281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (res != NULL) {
286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        switch (res->fType) {
287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_STRING:
288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return string_write    (mem, res, usedOffset, status);
289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_ALIAS:
290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return alias_write    (mem, res, usedOffset, status);
291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_INT_VECTOR:
292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return intvector_write (mem, res, usedOffset, status);
293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_BINARY:
294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return bin_write       (mem, res, usedOffset, status);
295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_INT:
296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return int_write       (mem, res, usedOffset, status);
297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_ARRAY:
298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return array_write     (mem, res, usedOffset, status);
299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_TABLE:
300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_TABLE32:
301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return table_write     (mem, res, usedOffset, status);
302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        default:
304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    *status = U_INTERNAL_PROGRAM_ERROR;
309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return 0;
310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid bundle_write(struct SRBRoot *bundle, const char *outputDir, const char *outputPkg, char *writtenFilename, int writtenFilenameLen, UErrorCode *status) {
313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UNewDataMemory *mem        = NULL;
314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint8_t         pad        = 0;
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t        root       = 0;
316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t        usedOffset = 0;
317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uint32_t        top, size;
318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char            dataName[1024];
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t         indexes[URES_INDEX_TOP];
320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (writtenFilename && writtenFilenameLen) {
322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *writtenFilename = 0;
323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (writtenFilename) {
330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru       int32_t off = 0, len = 0;
331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru       if (outputDir) {
332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           len = (int32_t)uprv_strlen(outputDir);
333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           if (len > writtenFilenameLen) {
334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru               len = writtenFilenameLen;
335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           }
336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           uprv_strncpy(writtenFilename, outputDir, len);
337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru       }
338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru       if (writtenFilenameLen -= len) {
339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           off += len;
340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           writtenFilename[off] = U_FILE_SEP_CHAR;
341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           if (--writtenFilenameLen) {
342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru               ++off;
343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru               if(outputPkg != NULL)
344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru               {
345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   uprv_strcpy(writtenFilename+off, outputPkg);
346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   off += (int32_t)uprv_strlen(outputPkg);
347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   writtenFilename[off] = '_';
348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   ++off;
349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru               }
350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru               len = (int32_t)uprv_strlen(bundle->fLocale);
352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru               if (len > writtenFilenameLen) {
353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   len = writtenFilenameLen;
354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru               }
355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru               uprv_strncpy(writtenFilename + off, bundle->fLocale, len);
356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru               if (writtenFilenameLen -= len) {
357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   off += len;
358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   len = 5;
359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   if (len > writtenFilenameLen) {
360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                       len = writtenFilenameLen;
361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   }
362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   uprv_strncpy(writtenFilename +  off, ".res", len);
363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru               }
364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru           }
365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru       }
366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(outputPkg)
369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strcpy(dataName, outputPkg);
371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strcat(dataName, "_");
372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strcat(dataName, bundle->fLocale);
373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else
375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strcpy(dataName, bundle->fLocale);
377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    mem = udata_create(outputDir, "res", dataName, &dataInfo, (gIncludeCopyright==TRUE)? U_COPYRIGHT_STRING:NULL, status);
380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(U_FAILURE(*status)){
381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    pad = calcPadding(bundle->fKeyPoint);
384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    usedOffset = bundle->fKeyPoint + pad ; /* top of the strings */
386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* we're gonna put the main table at the end */
388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    top = usedOffset + bundle->fRoot->u.fTable.fChildrenSize;
389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    root = (top) >> 2 | (bundle->fRoot->fType << 28);
390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* write the root item */
392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_write32(mem, root);
393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* add to top the size of the root item */
395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    top += bundle->fRoot->fSize;
396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    top += calcPadding(top);
397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*
399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * formatVersion 1.1 (ICU 2.8):
400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * write int32_t indexes[] after root and before the strings
401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * to make it easier to parse resource bundles in icuswap or from Java etc.
402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_memset(indexes, 0, sizeof(indexes));
404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    indexes[URES_INDEX_LENGTH]=             URES_INDEX_TOP;
405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    indexes[URES_INDEX_STRINGS_TOP]=        (int32_t)(usedOffset>>2);
406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    indexes[URES_INDEX_RESOURCES_TOP]=      (int32_t)(top>>2);
407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    indexes[URES_INDEX_BUNDLE_TOP]=         indexes[URES_INDEX_RESOURCES_TOP];
408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    indexes[URES_INDEX_MAX_TABLE_LENGTH]=   bundle->fMaxTableLength;
409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*
411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * formatVersion 1.2 (ICU 3.6):
412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * write indexes[URES_INDEX_ATTRIBUTES] with URES_ATT_NO_FALLBACK set or not set
413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * the memset() above initialized all indexes[] to 0
414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(bundle->noFallback) {
416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        indexes[URES_INDEX_ATTRIBUTES]=URES_ATT_NO_FALLBACK;
417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* write the indexes[] */
420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_writeBlock(mem, indexes, sizeof(indexes));
421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* write the table key strings */
423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_writeBlock(mem, bundle->fKeys+URES_STRINGS_BOTTOM,
424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                          bundle->fKeyPoint-URES_STRINGS_BOTTOM);
425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* write the padding bytes after the table key strings */
427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    udata_writePadding(mem, pad);
428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* write all of the bundle contents: the root item and its children */
430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    usedOffset = res_write(mem, bundle->fRoot, usedOffset, status);
431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    size = udata_finish(mem, status);
433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(top != size) {
434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fprintf(stderr, "genrb error: wrote %u bytes but counted %u\n",
435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                (int)size, (int)top);
436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *status = U_INTERNAL_PROGRAM_ERROR;
437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Opening Functions */
441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct SResource* res_open(const struct UString* comment, UErrorCode* status){
442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *res;
443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res = (struct SResource *) uprv_malloc(sizeof(struct SResource));
449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (res == NULL) {
451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *status = U_MEMORY_ALLOCATION_ERROR;
452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_memset(res, 0, sizeof(struct SResource));
455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
456c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    ustr_init(&res->fComment);
457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(comment != NULL){
458c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        ustr_cpy(&res->fComment, comment, status);
459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return res;
461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
463c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
464c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustruct SResource* res_none() {
465c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return &kNoResource;
466c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
467c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct SResource* table_open(struct SRBRoot *bundle, char *tag,  const struct UString* comment, UErrorCode *status) {
469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *res = res_open(comment, status);
471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fKey  = bundle_addtag(bundle, tag, status);
473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
475c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        res_close(res);
476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fNext = NULL;
480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*
482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * always open a table not a table32 in case it remains empty -
483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * try to use table32 only when necessary
484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fType = URES_TABLE;
486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fSize = sizeof(uint16_t);
487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fTable.fCount        = 0;
489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fTable.fChildrenSize = 0;
490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fTable.fFirst        = NULL;
491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fTable.fRoot         = bundle;
492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return res;
494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct SResource* array_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status) {
497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *res = res_open(comment, status);
499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fType = URES_ARRAY;
505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fKey  = bundle_addtag(bundle, tag, status);
506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(res);
509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fNext = NULL;
513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fSize = sizeof(int32_t);
514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fArray.fCount        = 0;
516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fArray.fChildrenSize = 0;
517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fArray.fFirst        = NULL;
518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fArray.fLast         = NULL;
519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return res;
521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct SResource *string_open(struct SRBRoot *bundle, char *tag, const UChar *value, int32_t len, const struct UString* comment, UErrorCode *status) {
524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *res = res_open(comment, status);
525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fType = URES_STRING;
531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fKey  = bundle_addtag(bundle, tag, status);
532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(res);
535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fNext = NULL;
539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fString.fLength = len;
541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fString.fChars  = (UChar *) uprv_malloc(sizeof(UChar) * (len + 1));
542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (res->u.fString.fChars == NULL) {
544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *status = U_MEMORY_ALLOCATION_ERROR;
545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(res);
546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_memcpy(res->u.fString.fChars, value, sizeof(UChar) * (len + 1));
550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fSize = sizeof(int32_t) + sizeof(UChar) * (len+1);
551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return res;
553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* TODO: make alias_open and string_open use the same code */
556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct SResource *alias_open(struct SRBRoot *bundle, char *tag, UChar *value, int32_t len, const struct UString* comment, UErrorCode *status) {
557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *res = res_open(comment, status);
558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fType = URES_ALIAS;
564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fKey  = bundle_addtag(bundle, tag, status);
565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(res);
568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fNext = NULL;
572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fString.fLength = len;
574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fString.fChars  = (UChar *) uprv_malloc(sizeof(UChar) * (len + 1));
575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (res->u.fString.fChars == NULL) {
577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *status = U_MEMORY_ALLOCATION_ERROR;
578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(res);
579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_memcpy(res->u.fString.fChars, value, sizeof(UChar) * (len + 1));
583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fSize = sizeof(int32_t) + sizeof(UChar) * (len + 1);
584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return res;
586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct SResource* intvector_open(struct SRBRoot *bundle, char *tag, const struct UString* comment, UErrorCode *status) {
590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *res = res_open(comment, status);
591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fType = URES_INT_VECTOR;
597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fKey  = bundle_addtag(bundle, tag, status);
598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(res);
601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fNext = NULL;
605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fSize = sizeof(int32_t);
606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fIntVector.fCount = 0;
608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fIntVector.fArray = (uint32_t *) uprv_malloc(sizeof(uint32_t) * RESLIST_MAX_INT_VECTOR);
609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (res->u.fIntVector.fArray == NULL) {
611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *status = U_MEMORY_ALLOCATION_ERROR;
612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(res);
613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return res;
617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct SResource *int_open(struct SRBRoot *bundle, char *tag, int32_t value, const struct UString* comment, UErrorCode *status) {
620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *res = res_open(comment, status);
621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fType = URES_INT;
627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fKey  = bundle_addtag(bundle, tag, status);
628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(res);
631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fSize              = 0;
635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fNext              = NULL;
636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fIntValue.fValue = value;
637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return res;
639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
641b13da9df870a61b11249bf741347908dbea0edd8Jean-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) {
642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *res = res_open(comment, status);
643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fType = URES_BINARY;
649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fKey  = bundle_addtag(bundle, tag, status);
650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(res);
653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fNext = NULL;
657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fBinaryValue.fLength = length;
659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->u.fBinaryValue.fFileName = NULL;
660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(fileName!=NULL && uprv_strcmp(fileName, "") !=0){
661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        res->u.fBinaryValue.fFileName = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(fileName)+1));
662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_strcpy(res->u.fBinaryValue.fFileName,fileName);
663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (length > 0) {
665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        res->u.fBinaryValue.fData   = (uint8_t *) uprv_malloc(sizeof(uint8_t) * length);
666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (res->u.fBinaryValue.fData == NULL) {
668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *status = U_MEMORY_ALLOCATION_ERROR;
669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            uprv_free(res);
670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return NULL;
671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_memcpy(res->u.fBinaryValue.fData, data, length);
674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else {
676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        res->u.fBinaryValue.fData = NULL;
677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fSize = sizeof(int32_t) + sizeof(uint8_t) * length + BIN_ALIGNMENT;
680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return res;
682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct SRBRoot *bundle_open(const struct UString* comment, UErrorCode *status) {
685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SRBRoot *bundle = NULL;
686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    bundle = (struct SRBRoot *) uprv_malloc(sizeof(struct SRBRoot));
692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (bundle == NULL) {
694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *status = U_MEMORY_ALLOCATION_ERROR;
695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_memset(bundle, 0, sizeof(struct SRBRoot));
698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    bundle->fLocale   = NULL;
700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    bundle->fKeys     = (char *) uprv_malloc(sizeof(char) * KEY_SPACE_SIZE);
702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    bundle->fKeysCapacity = KEY_SPACE_SIZE;
703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(comment != NULL){
705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (bundle->fKeys == NULL) {
709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *status = U_MEMORY_ALLOCATION_ERROR;
710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(bundle);
711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* formatVersion 1.1: start fKeyPoint after the root item and indexes[] */
715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    bundle->fKeyPoint = URES_STRINGS_BOTTOM;
716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_memset(bundle->fKeys, 0, URES_STRINGS_BOTTOM);
717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    bundle->fCount = 0;
719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    bundle->fRoot  = table_open(bundle, NULL, comment, status);
720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (bundle->fRoot == NULL || U_FAILURE(*status)) {
722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_SUCCESS(*status)) {
723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *status = U_MEMORY_ALLOCATION_ERROR;
724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(bundle->fKeys);
727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(bundle);
728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return bundle;
733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Closing Functions */
736c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void table_close(struct SResource *table) {
737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *current = NULL;
738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *prev    = NULL;
739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    current = table->u.fTable.fFirst;
741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (current != NULL) {
743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        prev    = current;
744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        current = current->fNext;
745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
746c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        res_close(prev);
747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    table->u.fTable.fFirst = NULL;
750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
752c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void array_close(struct SResource *array) {
753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *current = NULL;
754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *prev    = NULL;
755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(array==NULL){
757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    current = array->u.fArray.fFirst;
760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (current != NULL) {
762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        prev    = current;
763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        current = current->fNext;
764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
765c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        res_close(prev);
766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    array->u.fArray.fFirst = NULL;
768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
770c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void string_close(struct SResource *string) {
771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (string->u.fString.fChars != NULL) {
772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(string->u.fString.fChars);
773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        string->u.fString.fChars =NULL;
774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
777c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void alias_close(struct SResource *alias) {
778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (alias->u.fString.fChars != NULL) {
779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(alias->u.fString.fChars);
780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        alias->u.fString.fChars =NULL;
781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
784c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void intvector_close(struct SResource *intvector) {
785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (intvector->u.fIntVector.fArray != NULL) {
786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(intvector->u.fIntVector.fArray);
787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        intvector->u.fIntVector.fArray =NULL;
788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
791c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void int_close(struct SResource *intres) {
792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* Intentionally left blank */
793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
795c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic void bin_close(struct SResource *binres) {
796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (binres->u.fBinaryValue.fData != NULL) {
797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(binres->u.fBinaryValue.fData);
798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        binres->u.fBinaryValue.fData = NULL;
799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
802c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruvoid res_close(struct SResource *res) {
803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (res != NULL) {
804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        switch(res->fType) {
805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_STRING:
806c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            string_close(res);
807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_ALIAS:
809c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            alias_close(res);
810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_INT_VECTOR:
812c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            intvector_close(res);
813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_BINARY:
815c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            bin_close(res);
816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_INT:
818c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            int_close(res);
819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_ARRAY:
821c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            array_close(res);
822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_TABLE:
824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case URES_TABLE32:
825c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            table_close(res);
826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        default:
828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* Shouldn't happen */
829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
832c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        ustr_deinit(&res->fComment);
833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(res);
834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid bundle_close(struct SRBRoot *bundle, UErrorCode *status) {
838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (bundle->fRoot != NULL) {
839c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        res_close(bundle->fRoot);
840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (bundle->fLocale != NULL) {
843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(bundle->fLocale);
844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (bundle->fKeys != NULL) {
847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(bundle->fKeys);
848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_free(bundle);
851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Adding Functions */
854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid table_add(struct SResource *table, struct SResource *res, int linenumber, UErrorCode *status) {
855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *current = NULL;
856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResource *prev    = NULL;
857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    struct SResTable *list;
858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
862c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (res == &kNoResource) {
863c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return;
864c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* remember this linenumber to report to the user if there is a duplicate key */
867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->line = linenumber;
868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* here we need to traverse the list */
870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    list = &(table->u.fTable);
871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(table->fType == URES_TABLE && res->fKey > 0xffff) {
873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* this table straddles the 64k strings boundary, update to a table32 */
874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        table->fType = URES_TABLE32;
875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /*
877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * increase the size because count and each string offset
878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         * increase from uint16_t to int32_t
879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru         */
880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        table->fSize += (1 + list->fCount) * 2;
881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ++(list->fCount);
884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(list->fCount > (uint32_t)list->fRoot->fMaxTableLength) {
885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        list->fRoot->fMaxTableLength = list->fCount;
886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*
889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * URES_TABLE:   6 bytes = 1 uint16_t key string offset + 1 uint32_t Resource
890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * URES_TABLE32: 8 bytes = 1 int32_t key string offset + 1 uint32_t Resource
891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    table->fSize += table->fType == URES_TABLE ? 6 : 8;
893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    table->u.fTable.fChildrenSize += res->fSize + calcPadding(res->fSize);
895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (res->fType == URES_TABLE || res->fType == URES_TABLE32) {
897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        table->u.fTable.fChildrenSize += res->u.fTable.fChildrenSize;
898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else if (res->fType == URES_ARRAY) {
899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        table->u.fTable.fChildrenSize += res->u.fArray.fChildrenSize;
900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* is list still empty? */
903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (list->fFirst == NULL) {
904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        list->fFirst = res;
905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        res->fNext   = NULL;
906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    current = list->fFirst;
910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (current != NULL) {
912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (uprv_strcmp(((list->fRoot->fKeys) + (current->fKey)), ((list->fRoot->fKeys) + (res->fKey))) < 0) {
913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            prev    = current;
914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            current = current->fNext;
915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else if (uprv_strcmp(((list->fRoot->fKeys) + (current->fKey)), ((list->fRoot->fKeys) + (res->fKey))) > 0) {
916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* we're either in front of list, or in middle */
917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (prev == NULL) {
918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                /* front of the list */
919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                list->fFirst = res;
920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            } else {
921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                /* middle of the list */
922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                prev->fNext = res;
923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            res->fNext = current;
926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return;
927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        } else {
928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            /* Key already exists! ERROR! */
929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            error(linenumber, "duplicate key '%s' in table, first appeared at line %d", list->fRoot->fKeys + current->fKey, current->line);
930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *status = U_UNSUPPORTED_ERROR;
931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return;
932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /* end of list */
936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    prev->fNext = res;
937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    res->fNext  = NULL;
938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid array_add(struct SResource *array, struct SResource *res, UErrorCode *status) {
941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (array->u.fArray.fFirst == NULL) {
946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        array->u.fArray.fFirst = res;
947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        array->u.fArray.fLast  = res;
948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else {
949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        array->u.fArray.fLast->fNext = res;
950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        array->u.fArray.fLast        = res;
951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    (array->u.fArray.fCount)++;
954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    array->fSize += sizeof(uint32_t);
956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    array->u.fArray.fChildrenSize += res->fSize + calcPadding(res->fSize);
957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (res->fType == URES_TABLE || res->fType == URES_TABLE32) {
959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        array->u.fArray.fChildrenSize += res->u.fTable.fChildrenSize;
960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    } else if (res->fType == URES_ARRAY) {
961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        array->u.fArray.fChildrenSize += res->u.fArray.fChildrenSize;
962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid intvector_add(struct SResource *intvector, int32_t value, UErrorCode *status) {
966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    *(intvector->u.fIntVector.fArray + intvector->u.fIntVector.fCount) = value;
971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    intvector->u.fIntVector.fCount++;
972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    intvector->fSize += sizeof(uint32_t);
974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Misc Functions */
977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid bundle_setlocale(struct SRBRoot *bundle, UChar *locale, UErrorCode *status) {
979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(U_FAILURE(*status)) {
981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (bundle->fLocale!=NULL) {
985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(bundle->fLocale);
986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    bundle->fLocale= (char*) uprv_malloc(sizeof(char) * (u_strlen(locale)+1));
989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if(bundle->fLocale == NULL) {
991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        *status = U_MEMORY_ALLOCATION_ERROR;
992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /*u_strcpy(bundle->fLocale, locale);*/
996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    u_UCharsToChars(locale, bundle->fLocale, u_strlen(locale)+1);
997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t
1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubundle_addtag(struct SRBRoot *bundle, const char *tag, UErrorCode *status) {
1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t keypos, length;
1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(*status)) {
1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return -1;
1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (tag == NULL) {
1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* do not set an error: the root table has a NULL tag */
1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return -1;
1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    keypos = bundle->fKeyPoint;
1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    bundle->fKeyPoint += length = (int32_t) (uprv_strlen(tag) + 1);
1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (bundle->fKeyPoint >= bundle->fKeysCapacity) {
1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        /* overflow - resize the keys buffer */
1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        bundle->fKeysCapacity += KEY_SPACE_SIZE;
1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        bundle->fKeys = uprv_realloc(bundle->fKeys, bundle->fKeysCapacity);
1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(bundle->fKeys == NULL) {
1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            *status = U_MEMORY_ALLOCATION_ERROR;
1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return -1;
1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uprv_memcpy(bundle->fKeys + keypos, tag, length);
1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return keypos;
1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
1032