• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *******************************************************************************
3 *
4 *   Copyright (C) 2000-2015, International Business Machines
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 
21 #define KEY_SPACE_SIZE 65536
22 #define RESLIST_MAX_INT_VECTOR 2048
23 
24 #include "unicode/utypes.h"
25 #include "unicode/unistr.h"
26 #include "unicode/ures.h"
27 #include "unicode/ustring.h"
28 #include "cmemory.h"
29 #include "cstring.h"
30 #include "uhash.h"
31 #include "unewdata.h"
32 #include "uresdata.h"
33 #include "ustr.h"
34 
35 U_CDECL_BEGIN
36 
37 class PseudoListResource;
38 
39 struct ResFile {
ResFileResFile40     ResFile()
41             : fBytes(NULL), fIndexes(NULL),
42               fKeys(NULL), fKeysLength(0), fKeysCount(0),
43               fStrings(NULL), fStringIndexLimit(0),
44               fChecksum(0) {}
~ResFileResFile45     ~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 
63 typedef struct KeyMapEntry {
64     int32_t oldpos, newpos;
65 } KeyMapEntry;
66 
67 /* Resource bundle root table */
68 struct SRBRoot {
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.
95   char *fLocale;
96   int32_t fIndexLength;
97   int32_t fMaxTableLength;
98   UBool fNoFallback; /* see URES_ATT_NO_FALLBACK */
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 
109   icu::UnicodeString f16BitUnits;
110   int32_t f16BitStringsLength;
111 
112   const ResFile *fUsePoolBundle;
113   int32_t fPoolStringIndexLimit;
114   int32_t fPoolStringIndex16Limit;
115   int32_t fLocalStringIndexLimit;
116   SRBRoot *fWritePoolBundle;
117 };
118 
119 /* write a java resource file */
120 // TODO: C++ify
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 */
125 // TODO: C++ify
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 
129 /* Various resource types */
130 
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 
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 
isTableSResource164     UBool isTable() const { return fType == URES_TABLE; }
isStringSResource165     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:
ContainerResource(SRBRoot * bundle,const char * tag,int8_t type,const UString * comment,UErrorCode & errorCode)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?
241     uint32_t fCount;
242     SResource *fFirst;
243 };
244 
245 class TableResource : public ContainerResource {
246 public:
TableResource(SRBRoot * bundle,const char * tag,const UString * comment,UErrorCode & errorCode)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();
252 
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;
261 };
262 
263 class ArrayResource : public ContainerResource {
264 public:
ArrayResource(SRBRoot * bundle,const char * tag,const UString * comment,UErrorCode & errorCode)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();
270 
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;
278 };
279 
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:
PseudoListResource(SRBRoot * bundle,UErrorCode & errorCode)286     PseudoListResource(SRBRoot *bundle, UErrorCode &errorCode)
287             : ContainerResource(bundle, NULL, URES_TABLE, NULL, errorCode) {}
288     virtual ~PseudoListResource();
289 
290     void add(SResource *res);
291 
292     virtual void handleWrite16(SRBRoot *bundle);
293 };
294 
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 
getBuffer()305     const UChar *getBuffer() const { return fString.getBuffer(); }
length()306     int32_t length() const { return fString.length(); }
307 
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;
313 };
314 
315 class StringResource : public StringBaseResource {
316 public:
StringResource(SRBRoot * bundle,const char * tag,const UChar * value,int32_t len,const UString * comment,UErrorCode & errorCode)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) {}
StringResource(SRBRoot * bundle,const icu::UnicodeString & value,UErrorCode & errorCode)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) {}
StringResource(int32_t poolStringIndex,int8_t numCharsForLength,const UChar * value,int32_t length,UErrorCode & errorCode)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 
get16BitStringsLength()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 };
353 
354 class AliasResource : public StringBaseResource {
355 public:
AliasResource(SRBRoot * bundle,const char * tag,const UChar * value,int32_t len,const UString * comment,UErrorCode & errorCode)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();
360 };
361 
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();
367 
368     // TODO: private with getter?
369     int32_t fValue;
370 };
371 
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;
386 };
387 
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);
397 
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
406 void res_close(struct SResource *res);
407 
408 void setIncludeCopyright(UBool val);
409 UBool getIncludeCopyright(void);
410 
411 void setFormatVersion(int32_t formatVersion);
412 
413 int32_t getFormatVersion();
414 
415 void setUsePoolBundle(UBool use);
416 
417 /* in wrtxml.cpp */
418 uint32_t computeCRC(const char *ptr, uint32_t len, uint32_t lastcrc);
419 
420 U_CDECL_END
421 #endif /* #ifndef RESLIST_H */
422