]>
Commit | Line | Data |
---|---|---|
b75a7d8f A |
1 | /* |
2 | ******************************************************************************* | |
3 | * | |
2ca993e8 | 4 | * Copyright (C) 2000-2015, International Business Machines |
b75a7d8f A |
5 | * Corporation and others. All Rights Reserved. |
6 | * | |
7 | ******************************************************************************* | |
8 | * | |
9 | * File reslist.h | |
10 | * | |
11 | * Modification History: | |
12 | * | |
13 | * Date Name Description | |
14 | * 02/21/00 weiv Creation. | |
15 | ******************************************************************************* | |
16 | */ | |
17 | ||
18 | #ifndef RESLIST_H | |
19 | #define RESLIST_H | |
20 | ||
374ca955 | 21 | #define KEY_SPACE_SIZE 65536 |
b75a7d8f A |
22 | #define RESLIST_MAX_INT_VECTOR 2048 |
23 | ||
24 | #include "unicode/utypes.h" | |
2ca993e8 | 25 | #include "unicode/unistr.h" |
b75a7d8f A |
26 | #include "unicode/ures.h" |
27 | #include "unicode/ustring.h" | |
b75a7d8f A |
28 | #include "cmemory.h" |
29 | #include "cstring.h" | |
2ca993e8 | 30 | #include "uhash.h" |
b75a7d8f | 31 | #include "unewdata.h" |
2ca993e8 | 32 | #include "uresdata.h" |
374ca955 | 33 | #include "ustr.h" |
b75a7d8f A |
34 | |
35 | U_CDECL_BEGIN | |
36 | ||
2ca993e8 A |
37 | class PseudoListResource; |
38 | ||
39 | struct ResFile { | |
40 | ResFile() | |
41 | : fBytes(NULL), fIndexes(NULL), | |
42 | fKeys(NULL), fKeysLength(0), fKeysCount(0), | |
43 | fStrings(NULL), fStringIndexLimit(0), | |
44 | fChecksum(0) {} | |
45 | ~ResFile() { close(); } | |
46 | ||
47 | void close(); | |
48 | ||
49 | uint8_t *fBytes; | |
50 | const int32_t *fIndexes; | |
51 | const char *fKeys; | |
52 | int32_t fKeysLength; | |
53 | int32_t fKeysCount; | |
54 | ||
55 | PseudoListResource *fStrings; | |
56 | int32_t fStringIndexLimit; | |
57 | ||
58 | int32_t fChecksum; | |
59 | }; | |
60 | ||
61 | struct SResource; | |
62 | ||
729e4ab9 A |
63 | typedef struct KeyMapEntry { |
64 | int32_t oldpos, newpos; | |
65 | } KeyMapEntry; | |
66 | ||
b75a7d8f A |
67 | /* Resource bundle root table */ |
68 | struct SRBRoot { | |
2ca993e8 A |
69 | SRBRoot(const UString *comment, UBool isPoolBundle, UErrorCode &errorCode); |
70 | ~SRBRoot(); | |
71 | ||
72 | void write(const char *outputDir, const char *outputPkg, | |
73 | char *writtenFilename, int writtenFilenameLen, UErrorCode &errorCode); | |
74 | ||
75 | void setLocale(UChar *locale, UErrorCode &errorCode); | |
76 | int32_t addTag(const char *tag, UErrorCode &errorCode); | |
77 | ||
78 | const char *getKeyString(int32_t key) const; | |
79 | const char *getKeyBytes(int32_t *pLength) const; | |
80 | ||
81 | int32_t addKeyBytes(const char *keyBytes, int32_t length, UErrorCode &errorCode); | |
82 | ||
83 | void compactKeys(UErrorCode &errorCode); | |
84 | ||
85 | int32_t makeRes16(uint32_t resWord) const; | |
86 | int32_t mapKey(int32_t oldpos) const; | |
87 | ||
88 | private: | |
89 | void compactStringsV2(UHashtable *stringSet, UErrorCode &errorCode); | |
90 | ||
91 | public: | |
92 | // TODO: private | |
93 | ||
94 | SResource *fRoot; // Normally a TableResource. | |
729e4ab9 A |
95 | char *fLocale; |
96 | int32_t fIndexLength; | |
374ca955 | 97 | int32_t fMaxTableLength; |
2ca993e8 | 98 | UBool fNoFallback; /* see URES_ATT_NO_FALLBACK */ |
729e4ab9 A |
99 | int8_t fStringsForm; /* default STRINGS_UTF16_V1 */ |
100 | UBool fIsPoolBundle; | |
101 | ||
102 | char *fKeys; | |
103 | KeyMapEntry *fKeyMap; | |
104 | int32_t fKeysBottom, fKeysTop; | |
105 | int32_t fKeysCapacity; | |
106 | int32_t fKeysCount; | |
107 | int32_t fLocalKeyLimit; /* key offset < limit fits into URES_TABLE */ | |
108 | ||
2ca993e8 A |
109 | icu::UnicodeString f16BitUnits; |
110 | int32_t f16BitStringsLength; | |
729e4ab9 | 111 | |
2ca993e8 A |
112 | const ResFile *fUsePoolBundle; |
113 | int32_t fPoolStringIndexLimit; | |
114 | int32_t fPoolStringIndex16Limit; | |
115 | int32_t fLocalStringIndexLimit; | |
116 | SRBRoot *fWritePoolBundle; | |
b75a7d8f A |
117 | }; |
118 | ||
b75a7d8f | 119 | /* write a java resource file */ |
2ca993e8 | 120 | // TODO: C++ify |
b75a7d8f A |
121 | void bundle_write_java(struct SRBRoot *bundle, const char *outputDir, const char* outputEnc, char *writtenFilename, |
122 | int writtenFilenameLen, const char* packageName, const char* bundleName, UErrorCode *status); | |
123 | ||
124 | /* write a xml resource file */ | |
2ca993e8 | 125 | // TODO: C++ify |
b75a7d8f A |
126 | void bundle_write_xml(struct SRBRoot *bundle, const char *outputDir,const char* outputEnc, const char* rbname, |
127 | char *writtenFilename, int writtenFilenameLen, const char* language, const char* package, UErrorCode *status); | |
128 | ||
b75a7d8f A |
129 | /* Various resource types */ |
130 | ||
46f4442e A |
131 | /* |
132 | * Return a unique pointer to a dummy object, | |
133 | * for use in non-error cases when no resource is to be added to the bundle. | |
134 | * (NULL is used in error cases.) | |
135 | */ | |
136 | struct SResource* res_none(void); | |
137 | ||
2ca993e8 A |
138 | class ArrayResource; |
139 | class TableResource; | |
140 | class IntVectorResource; | |
141 | ||
142 | TableResource *table_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status); | |
143 | ||
144 | ArrayResource *array_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status); | |
145 | ||
146 | struct SResource *string_open(struct SRBRoot *bundle, const char *tag, const UChar *value, int32_t len, const struct UString* comment, UErrorCode *status); | |
147 | ||
148 | struct SResource *alias_open(struct SRBRoot *bundle, const char *tag, UChar *value, int32_t len, const struct UString* comment, UErrorCode *status); | |
149 | ||
150 | IntVectorResource *intvector_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status); | |
151 | ||
152 | struct SResource *int_open(struct SRBRoot *bundle, const char *tag, int32_t value, const struct UString* comment, UErrorCode *status); | |
153 | ||
154 | struct SResource *bin_open(struct SRBRoot *bundle, const char *tag, uint32_t length, uint8_t *data, const char* fileName, const struct UString* comment, UErrorCode *status); | |
155 | ||
156 | /* Resource place holder */ | |
157 | ||
158 | struct SResource { | |
159 | SResource(); | |
160 | SResource(SRBRoot *bundle, const char *tag, int8_t type, const UString* comment, | |
161 | UErrorCode &errorCode); | |
162 | virtual ~SResource(); | |
163 | ||
164 | UBool isTable() const { return fType == URES_TABLE; } | |
165 | UBool isString() const { return fType == URES_STRING; } | |
166 | ||
167 | const char *getKeyString(const SRBRoot *bundle) const; | |
168 | ||
169 | /** | |
170 | * Preflights strings. | |
171 | * Finds duplicates and counts the total number of string code units | |
172 | * so that they can be written first to the 16-bit array, | |
173 | * for minimal string and container storage. | |
174 | * | |
175 | * We walk the final parse tree, rather than collecting this information while building it, | |
176 | * so that we need not deal with changes to the parse tree (especially removing resources). | |
177 | */ | |
178 | void preflightStrings(SRBRoot *bundle, UHashtable *stringSet, UErrorCode &errorCode); | |
179 | virtual void handlePreflightStrings(SRBRoot *bundle, UHashtable *stringSet, UErrorCode &errorCode); | |
180 | ||
181 | /** | |
182 | * Writes resource values into f16BitUnits | |
183 | * and determines the resource item word, if possible. | |
184 | */ | |
185 | void write16(SRBRoot *bundle); | |
186 | virtual void handleWrite16(SRBRoot *bundle); | |
187 | ||
188 | /** | |
189 | * Calculates ("preflights") and advances the *byteOffset | |
190 | * by the size of the resource's data in the binary file and | |
191 | * determines the resource item word. | |
192 | * | |
193 | * Most handlePreWrite() functions may add any number of bytes, but preWrite() | |
194 | * will always pad it to a multiple of 4. | |
195 | * The resource item type may be a related subtype of the fType. | |
196 | * | |
197 | * The preWrite() and write() functions start and end at the same | |
198 | * byteOffset values. | |
199 | * Prewriting allows bundle.write() to determine the root resource item word, | |
200 | * before actually writing the bundle contents to the file, | |
201 | * which is necessary because the root item is stored at the beginning. | |
202 | */ | |
203 | void preWrite(uint32_t *byteOffset); | |
204 | virtual void handlePreWrite(uint32_t *byteOffset); | |
205 | ||
206 | /** | |
207 | * Writes the resource's data to mem and updates the byteOffset | |
208 | * in parallel. | |
209 | */ | |
210 | void write(UNewDataMemory *mem, uint32_t *byteOffset); | |
211 | virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset); | |
212 | ||
213 | int8_t fType; /* nominal type: fRes (when != 0xffffffff) may use subtype */ | |
214 | UBool fWritten; /* res_write() can exit early */ | |
215 | uint32_t fRes; /* resource item word; RES_BOGUS=0xffffffff if not known yet */ | |
216 | int32_t fRes16; /* Res16 version of fRes for Table, Table16, Array16; -1 if it does not fit. */ | |
217 | int32_t fKey; /* Index into bundle->fKeys; -1 if no key. */ | |
218 | int32_t fKey16; /* Key16 version of fKey for Table & Table16; -1 if no key or it does not fit. */ | |
219 | int line; /* used internally to report duplicate keys in tables */ | |
220 | SResource *fNext; /* This is for internal chaining while building */ | |
221 | struct UString fComment; | |
222 | }; | |
223 | ||
224 | class ContainerResource : public SResource { | |
225 | public: | |
226 | ContainerResource(SRBRoot *bundle, const char *tag, int8_t type, | |
227 | const UString* comment, UErrorCode &errorCode) | |
228 | : SResource(bundle, tag, type, comment, errorCode), | |
229 | fCount(0), fFirst(NULL) {} | |
230 | virtual ~ContainerResource(); | |
231 | ||
232 | virtual void handlePreflightStrings(SRBRoot *bundle, UHashtable *stringSet, UErrorCode &errorCode); | |
233 | protected: | |
234 | void writeAllRes16(SRBRoot *bundle); | |
235 | void preWriteAllRes(uint32_t *byteOffset); | |
236 | void writeAllRes(UNewDataMemory *mem, uint32_t *byteOffset); | |
237 | void writeAllRes32(UNewDataMemory *mem, uint32_t *byteOffset); | |
238 | ||
239 | public: | |
240 | // TODO: private with getter? | |
374ca955 | 241 | uint32_t fCount; |
2ca993e8 | 242 | SResource *fFirst; |
b75a7d8f A |
243 | }; |
244 | ||
2ca993e8 A |
245 | class TableResource : public ContainerResource { |
246 | public: | |
247 | TableResource(SRBRoot *bundle, const char *tag, | |
248 | const UString* comment, UErrorCode &errorCode) | |
249 | : ContainerResource(bundle, tag, URES_TABLE, comment, errorCode), | |
250 | fTableType(URES_TABLE), fRoot(bundle) {} | |
251 | virtual ~TableResource(); | |
b75a7d8f | 252 | |
2ca993e8 A |
253 | void add(SResource *res, int linenumber, UErrorCode &errorCode); |
254 | ||
255 | virtual void handleWrite16(SRBRoot *bundle); | |
256 | virtual void handlePreWrite(uint32_t *byteOffset); | |
257 | virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset); | |
258 | ||
259 | int8_t fTableType; // determined by table_write16() for table_preWrite() & table_write() | |
260 | SRBRoot *fRoot; | |
b75a7d8f A |
261 | }; |
262 | ||
2ca993e8 A |
263 | class ArrayResource : public ContainerResource { |
264 | public: | |
265 | ArrayResource(SRBRoot *bundle, const char *tag, | |
266 | const UString* comment, UErrorCode &errorCode) | |
267 | : ContainerResource(bundle, tag, URES_ARRAY, comment, errorCode), | |
268 | fLast(NULL) {} | |
269 | virtual ~ArrayResource(); | |
b75a7d8f | 270 | |
2ca993e8 A |
271 | void add(SResource *res); |
272 | ||
273 | virtual void handleWrite16(SRBRoot *bundle); | |
274 | virtual void handlePreWrite(uint32_t *byteOffset); | |
275 | virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset); | |
276 | ||
277 | SResource *fLast; | |
b75a7d8f A |
278 | }; |
279 | ||
2ca993e8 A |
280 | /** |
281 | * List of resources for a pool bundle. | |
282 | * Writes an empty table resource, rather than a container structure. | |
283 | */ | |
284 | class PseudoListResource : public ContainerResource { | |
285 | public: | |
286 | PseudoListResource(SRBRoot *bundle, UErrorCode &errorCode) | |
287 | : ContainerResource(bundle, NULL, URES_TABLE, NULL, errorCode) {} | |
288 | virtual ~PseudoListResource(); | |
b75a7d8f | 289 | |
2ca993e8 | 290 | void add(SResource *res); |
b75a7d8f | 291 | |
2ca993e8 | 292 | virtual void handleWrite16(SRBRoot *bundle); |
b75a7d8f A |
293 | }; |
294 | ||
2ca993e8 A |
295 | class StringBaseResource : public SResource { |
296 | public: | |
297 | StringBaseResource(SRBRoot *bundle, const char *tag, int8_t type, | |
298 | const UChar *value, int32_t len, | |
299 | const UString* comment, UErrorCode &errorCode); | |
300 | StringBaseResource(SRBRoot *bundle, int8_t type, | |
301 | const icu::UnicodeString &value, UErrorCode &errorCode); | |
302 | StringBaseResource(int8_t type, const UChar *value, int32_t len, UErrorCode &errorCode); | |
303 | virtual ~StringBaseResource(); | |
304 | ||
305 | const UChar *getBuffer() const { return fString.getBuffer(); } | |
306 | int32_t length() const { return fString.length(); } | |
b75a7d8f | 307 | |
2ca993e8 A |
308 | virtual void handlePreWrite(uint32_t *byteOffset); |
309 | virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset); | |
310 | ||
311 | // TODO: private with getter? | |
312 | icu::UnicodeString fString; | |
b75a7d8f A |
313 | }; |
314 | ||
2ca993e8 A |
315 | class StringResource : public StringBaseResource { |
316 | public: | |
317 | StringResource(SRBRoot *bundle, const char *tag, const UChar *value, int32_t len, | |
318 | const UString* comment, UErrorCode &errorCode) | |
319 | : StringBaseResource(bundle, tag, URES_STRING, value, len, comment, errorCode), | |
320 | fSame(NULL), fSuffixOffset(0), | |
321 | fNumCopies(0), fNumUnitsSaved(0), fNumCharsForLength(0) {} | |
322 | StringResource(SRBRoot *bundle, const icu::UnicodeString &value, UErrorCode &errorCode) | |
323 | : StringBaseResource(bundle, URES_STRING, value, errorCode), | |
324 | fSame(NULL), fSuffixOffset(0), | |
325 | fNumCopies(0), fNumUnitsSaved(0), fNumCharsForLength(0) {} | |
326 | StringResource(int32_t poolStringIndex, int8_t numCharsForLength, | |
327 | const UChar *value, int32_t length, | |
328 | UErrorCode &errorCode) | |
329 | : StringBaseResource(URES_STRING, value, length, errorCode), | |
330 | fSame(NULL), fSuffixOffset(0), | |
331 | fNumCopies(0), fNumUnitsSaved(0), fNumCharsForLength(numCharsForLength) { | |
332 | // v3 pool string encoded as string-v2 with low offset | |
333 | fRes = URES_MAKE_RESOURCE(URES_STRING_V2, poolStringIndex); | |
334 | fWritten = TRUE; | |
335 | } | |
336 | virtual ~StringResource(); | |
337 | ||
338 | int32_t get16BitStringsLength() const { | |
339 | return fNumCharsForLength + length() + 1; // +1 for the NUL | |
340 | } | |
341 | ||
342 | virtual void handlePreflightStrings(SRBRoot *bundle, UHashtable *stringSet, UErrorCode &errorCode); | |
343 | virtual void handleWrite16(SRBRoot *bundle); | |
344 | ||
345 | void writeUTF16v2(int32_t base, icu::UnicodeString &dest); | |
346 | ||
347 | StringResource *fSame; // used for duplicates | |
348 | int32_t fSuffixOffset; // this string is a suffix of fSame at this offset | |
349 | int32_t fNumCopies; // number of equal strings represented by one stringSet element | |
350 | int32_t fNumUnitsSaved; // from not writing duplicates and suffixes | |
351 | int8_t fNumCharsForLength; | |
352 | }; | |
b75a7d8f | 353 | |
2ca993e8 A |
354 | class AliasResource : public StringBaseResource { |
355 | public: | |
356 | AliasResource(SRBRoot *bundle, const char *tag, const UChar *value, int32_t len, | |
357 | const UString* comment, UErrorCode &errorCode) | |
358 | : StringBaseResource(bundle, tag, URES_ALIAS, value, len, comment, errorCode) {} | |
359 | virtual ~AliasResource(); | |
b75a7d8f A |
360 | }; |
361 | ||
2ca993e8 A |
362 | class IntResource : public SResource { |
363 | public: | |
364 | IntResource(SRBRoot *bundle, const char *tag, int32_t value, | |
365 | const UString* comment, UErrorCode &errorCode); | |
366 | virtual ~IntResource(); | |
b75a7d8f | 367 | |
2ca993e8 A |
368 | // TODO: private with getter? |
369 | int32_t fValue; | |
370 | }; | |
b75a7d8f | 371 | |
2ca993e8 A |
372 | class IntVectorResource : public SResource { |
373 | public: | |
374 | IntVectorResource(SRBRoot *bundle, const char *tag, | |
375 | const UString* comment, UErrorCode &errorCode); | |
376 | virtual ~IntVectorResource(); | |
377 | ||
378 | void add(int32_t value, UErrorCode &errorCode); | |
379 | ||
380 | virtual void handlePreWrite(uint32_t *byteOffset); | |
381 | virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset); | |
382 | ||
383 | // TODO: UVector32 | |
384 | uint32_t fCount; | |
385 | uint32_t *fArray; | |
b75a7d8f A |
386 | }; |
387 | ||
2ca993e8 A |
388 | class BinaryResource : public SResource { |
389 | public: | |
390 | BinaryResource(SRBRoot *bundle, const char *tag, | |
391 | uint32_t length, uint8_t *data, const char* fileName, | |
392 | const UString* comment, UErrorCode &errorCode); | |
393 | virtual ~BinaryResource(); | |
394 | ||
395 | virtual void handlePreWrite(uint32_t *byteOffset); | |
396 | virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset); | |
729e4ab9 | 397 | |
2ca993e8 A |
398 | // TODO: CharString? |
399 | uint32_t fLength; | |
400 | uint8_t *fData; | |
401 | // TODO: CharString | |
402 | char* fFileName; // file name for binary or import binary tags if any | |
403 | }; | |
404 | ||
405 | // TODO: use LocalPointer or delete | |
46f4442e | 406 | void res_close(struct SResource *res); |
729e4ab9 | 407 | |
b75a7d8f A |
408 | void setIncludeCopyright(UBool val); |
409 | UBool getIncludeCopyright(void); | |
410 | ||
729e4ab9 A |
411 | void setFormatVersion(int32_t formatVersion); |
412 | ||
2ca993e8 A |
413 | int32_t getFormatVersion(); |
414 | ||
729e4ab9 A |
415 | void setUsePoolBundle(UBool use); |
416 | ||
417 | /* in wrtxml.cpp */ | |
2ca993e8 | 418 | uint32_t computeCRC(const char *ptr, uint32_t len, uint32_t lastcrc); |
729e4ab9 | 419 | |
b75a7d8f A |
420 | U_CDECL_END |
421 | #endif /* #ifndef RESLIST_H */ |