2 *******************************************************************************
4 * Copyright (C) 2000-2015, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
11 * Modification History:
13 * Date Name Description
14 * 02/21/00 weiv Creation.
15 *******************************************************************************
21 #define KEY_SPACE_SIZE 65536
22 #define RESLIST_MAX_INT_VECTOR 2048
24 #include "unicode/utypes.h"
25 #include "unicode/unistr.h"
26 #include "unicode/ures.h"
27 #include "unicode/ustring.h"
37 class PseudoListResource
;
41 : fBytes(NULL
), fIndexes(NULL
),
42 fKeys(NULL
), fKeysLength(0), fKeysCount(0),
43 fStrings(NULL
), fStringIndexLimit(0),
45 ~ResFile() { close(); }
50 const int32_t *fIndexes
;
55 PseudoListResource
*fStrings
;
56 int32_t fStringIndexLimit
;
63 typedef struct KeyMapEntry
{
64 int32_t oldpos
, newpos
;
67 /* Resource bundle root table */
69 SRBRoot(const UString
*comment
, UBool isPoolBundle
, UErrorCode
&errorCode
);
72 void write(const char *outputDir
, const char *outputPkg
,
73 char *writtenFilename
, int writtenFilenameLen
, UErrorCode
&errorCode
);
75 void setLocale(UChar
*locale
, UErrorCode
&errorCode
);
76 int32_t addTag(const char *tag
, UErrorCode
&errorCode
);
78 const char *getKeyString(int32_t key
) const;
79 const char *getKeyBytes(int32_t *pLength
) const;
81 int32_t addKeyBytes(const char *keyBytes
, int32_t length
, UErrorCode
&errorCode
);
83 void compactKeys(UErrorCode
&errorCode
);
85 int32_t makeRes16(uint32_t resWord
) const;
86 int32_t mapKey(int32_t oldpos
) const;
89 void compactStringsV2(UHashtable
*stringSet
, UErrorCode
&errorCode
);
94 SResource
*fRoot
; // Normally a TableResource.
97 int32_t fMaxTableLength
;
98 UBool fNoFallback
; /* see URES_ATT_NO_FALLBACK */
99 int8_t fStringsForm
; /* default STRINGS_UTF16_V1 */
103 KeyMapEntry
*fKeyMap
;
104 int32_t fKeysBottom
, fKeysTop
;
105 int32_t fKeysCapacity
;
107 int32_t fLocalKeyLimit
; /* key offset < limit fits into URES_TABLE */
109 icu::UnicodeString f16BitUnits
;
110 int32_t f16BitStringsLength
;
112 const ResFile
*fUsePoolBundle
;
113 int32_t fPoolStringIndexLimit
;
114 int32_t fPoolStringIndex16Limit
;
115 int32_t fLocalStringIndexLimit
;
116 SRBRoot
*fWritePoolBundle
;
119 /* write a java resource file */
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
);
124 /* write a xml resource file */
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
);
129 /* Various resource types */
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.)
136 struct SResource
* res_none(void);
140 class IntVectorResource
;
142 TableResource
*table_open(struct SRBRoot
*bundle
, const char *tag
, const struct UString
* comment
, UErrorCode
*status
);
144 ArrayResource
*array_open(struct SRBRoot
*bundle
, const char *tag
, const struct UString
* comment
, UErrorCode
*status
);
146 struct SResource
*string_open(struct SRBRoot
*bundle
, const char *tag
, const UChar
*value
, int32_t len
, const struct UString
* comment
, UErrorCode
*status
);
148 struct SResource
*alias_open(struct SRBRoot
*bundle
, const char *tag
, UChar
*value
, int32_t len
, const struct UString
* comment
, UErrorCode
*status
);
150 IntVectorResource
*intvector_open(struct SRBRoot
*bundle
, const char *tag
, const struct UString
* comment
, UErrorCode
*status
);
152 struct SResource
*int_open(struct SRBRoot
*bundle
, const char *tag
, int32_t value
, const struct UString
* comment
, UErrorCode
*status
);
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
);
156 /* Resource place holder */
160 SResource(SRBRoot
*bundle
, const char *tag
, int8_t type
, const UString
* comment
,
161 UErrorCode
&errorCode
);
162 virtual ~SResource();
164 UBool
isTable() const { return fType
== URES_TABLE
; }
165 UBool
isString() const { return fType
== URES_STRING
; }
167 const char *getKeyString(const SRBRoot
*bundle
) const;
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.
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).
178 void preflightStrings(SRBRoot
*bundle
, UHashtable
*stringSet
, UErrorCode
&errorCode
);
179 virtual void handlePreflightStrings(SRBRoot
*bundle
, UHashtable
*stringSet
, UErrorCode
&errorCode
);
182 * Writes resource values into f16BitUnits
183 * and determines the resource item word, if possible.
185 void write16(SRBRoot
*bundle
);
186 virtual void handleWrite16(SRBRoot
*bundle
);
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.
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.
197 * The preWrite() and write() functions start and end at the same
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.
203 void preWrite(uint32_t *byteOffset
);
204 virtual void handlePreWrite(uint32_t *byteOffset
);
207 * Writes the resource's data to mem and updates the byteOffset
210 void write(UNewDataMemory
*mem
, uint32_t *byteOffset
);
211 virtual void handleWrite(UNewDataMemory
*mem
, uint32_t *byteOffset
);
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
;
224 class ContainerResource
: public SResource
{
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();
232 virtual void handlePreflightStrings(SRBRoot
*bundle
, UHashtable
*stringSet
, UErrorCode
&errorCode
);
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
);
240 // TODO: private with getter?
245 class TableResource
: public ContainerResource
{
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();
253 void add(SResource
*res
, int linenumber
, UErrorCode
&errorCode
);
255 virtual void handleWrite16(SRBRoot
*bundle
);
256 virtual void handlePreWrite(uint32_t *byteOffset
);
257 virtual void handleWrite(UNewDataMemory
*mem
, uint32_t *byteOffset
);
259 int8_t fTableType
; // determined by table_write16() for table_preWrite() & table_write()
263 class ArrayResource
: public ContainerResource
{
265 ArrayResource(SRBRoot
*bundle
, const char *tag
,
266 const UString
* comment
, UErrorCode
&errorCode
)
267 : ContainerResource(bundle
, tag
, URES_ARRAY
, comment
, errorCode
),
269 virtual ~ArrayResource();
271 void add(SResource
*res
);
273 virtual void handleWrite16(SRBRoot
*bundle
);
274 virtual void handlePreWrite(uint32_t *byteOffset
);
275 virtual void handleWrite(UNewDataMemory
*mem
, uint32_t *byteOffset
);
281 * List of resources for a pool bundle.
282 * Writes an empty table resource, rather than a container structure.
284 class PseudoListResource
: public ContainerResource
{
286 PseudoListResource(SRBRoot
*bundle
, UErrorCode
&errorCode
)
287 : ContainerResource(bundle
, NULL
, URES_TABLE
, NULL
, errorCode
) {}
288 virtual ~PseudoListResource();
290 void add(SResource
*res
);
292 virtual void handleWrite16(SRBRoot
*bundle
);
295 class StringBaseResource
: public SResource
{
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();
305 const UChar
*getBuffer() const { return fString
.getBuffer(); }
306 int32_t length() const { return fString
.length(); }
308 virtual void handlePreWrite(uint32_t *byteOffset
);
309 virtual void handleWrite(UNewDataMemory
*mem
, uint32_t *byteOffset
);
311 // TODO: private with getter?
312 icu::UnicodeString fString
;
315 class StringResource
: public StringBaseResource
{
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
);
336 virtual ~StringResource();
338 int32_t get16BitStringsLength() const {
339 return fNumCharsForLength
+ length() + 1; // +1 for the NUL
342 virtual void handlePreflightStrings(SRBRoot
*bundle
, UHashtable
*stringSet
, UErrorCode
&errorCode
);
343 virtual void handleWrite16(SRBRoot
*bundle
);
345 void writeUTF16v2(int32_t base
, icu::UnicodeString
&dest
);
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
;
354 class AliasResource
: public StringBaseResource
{
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();
362 class IntResource
: public SResource
{
364 IntResource(SRBRoot
*bundle
, const char *tag
, int32_t value
,
365 const UString
* comment
, UErrorCode
&errorCode
);
366 virtual ~IntResource();
368 // TODO: private with getter?
372 class IntVectorResource
: public SResource
{
374 IntVectorResource(SRBRoot
*bundle
, const char *tag
,
375 const UString
* comment
, UErrorCode
&errorCode
);
376 virtual ~IntVectorResource();
378 void add(int32_t value
, UErrorCode
&errorCode
);
380 virtual void handlePreWrite(uint32_t *byteOffset
);
381 virtual void handleWrite(UNewDataMemory
*mem
, uint32_t *byteOffset
);
388 class BinaryResource
: public SResource
{
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();
395 virtual void handlePreWrite(uint32_t *byteOffset
);
396 virtual void handleWrite(UNewDataMemory
*mem
, uint32_t *byteOffset
);
402 char* fFileName
; // file name for binary or import binary tags if any
405 // TODO: use LocalPointer or delete
406 void res_close(struct SResource
*res
);
408 void setIncludeCopyright(UBool val
);
409 UBool
getIncludeCopyright(void);
411 void setFormatVersion(int32_t formatVersion
);
413 int32_t getFormatVersion();
415 void setUsePoolBundle(UBool use
);
418 uint32_t computeCRC(const char *ptr
, uint32_t len
, uint32_t lastcrc
);
421 #endif /* #ifndef RESLIST_H */