X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..HEAD:/icuSources/tools/genrb/reslist.h?ds=inline diff --git a/icuSources/tools/genrb/reslist.h b/icuSources/tools/genrb/reslist.h index 07993723..07874fdb 100644 --- a/icuSources/tools/genrb/reslist.h +++ b/icuSources/tools/genrb/reslist.h @@ -1,7 +1,9 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* * -* Copyright (C) 2000-2003, International Business Machines +* Copyright (C) 2000-2015, International Business Machines * Corporation and others. All Rights Reserved. * ******************************************************************************* @@ -18,129 +20,426 @@ #ifndef RESLIST_H #define RESLIST_H -#define KEY_SPACE_SIZE 65532 +#define KEY_SPACE_SIZE 65536 #define RESLIST_MAX_INT_VECTOR 2048 +#include + #include "unicode/utypes.h" +#include "unicode/unistr.h" #include "unicode/ures.h" #include "unicode/ustring.h" -#include "uresdata.h" #include "cmemory.h" #include "cstring.h" +#include "uhash.h" #include "unewdata.h" +#include "uresdata.h" +#include "ustr.h" U_CDECL_BEGIN +class PathFilter; +class PseudoListResource; +class ResKeyPath; + +struct ResFile { + ResFile() + : fBytes(NULL), fIndexes(NULL), + fKeys(NULL), fKeysLength(0), fKeysCount(0), + fStrings(NULL), fStringIndexLimit(0), + fChecksum(0) {} + ~ResFile() { close(); } + + void close(); + + uint8_t *fBytes; + const int32_t *fIndexes; + const char *fKeys; + int32_t fKeysLength; + int32_t fKeysCount; + + PseudoListResource *fStrings; + int32_t fStringIndexLimit; + + int32_t fChecksum; +}; + +struct SResource; + +typedef struct KeyMapEntry { + int32_t oldpos, newpos; +} KeyMapEntry; + /* Resource bundle root table */ struct SRBRoot { + SRBRoot(const UString *comment, UBool isPoolBundle, UErrorCode &errorCode); + ~SRBRoot(); + + void write(const char *outputDir, const char *outputPkg, + char *writtenFilename, int writtenFilenameLen, UErrorCode &errorCode); + + void setLocale(UChar *locale, UErrorCode &errorCode); + int32_t addTag(const char *tag, UErrorCode &errorCode); + + const char *getKeyString(int32_t key) const; + const char *getKeyBytes(int32_t *pLength) const; + + int32_t addKeyBytes(const char *keyBytes, int32_t length, UErrorCode &errorCode); + + void compactKeys(UErrorCode &errorCode); + + int32_t makeRes16(uint32_t resWord) const; + int32_t mapKey(int32_t oldpos) const; + +private: + void compactStringsV2(UHashtable *stringSet, UErrorCode &errorCode); + +public: + // TODO: private + + SResource *fRoot; // Normally a TableResource. char *fLocale; - uint32_t fKeyPoint; + int32_t fIndexLength; + int32_t fMaxTableLength; + UBool fNoFallback; /* see URES_ATT_NO_FALLBACK */ + int8_t fStringsForm; /* default STRINGS_UTF16_V1 */ + UBool fIsPoolBundle; + char *fKeys; - int32_t fCount; - struct SResource *fRoot; -}; + KeyMapEntry *fKeyMap; + int32_t fKeysBottom, fKeysTop; + int32_t fKeysCapacity; + int32_t fKeysCount; + int32_t fLocalKeyLimit; /* key offset < limit fits into URES_TABLE */ -struct SRBRoot *bundle_open(UErrorCode *status); -void bundle_write(struct SRBRoot *bundle, const char *outputDir, const char *outputPkg, char *writtenFilename, int writtenFilenameLen, UErrorCode *status); + icu::UnicodeString f16BitUnits; + int32_t f16BitStringsLength; + + const ResFile *fUsePoolBundle; + int32_t fPoolStringIndexLimit; + int32_t fPoolStringIndex16Limit; + int32_t fLocalStringIndexLimit; + SRBRoot *fWritePoolBundle; +}; /* write a java resource file */ +// TODO: C++ify void bundle_write_java(struct SRBRoot *bundle, const char *outputDir, const char* outputEnc, char *writtenFilename, int writtenFilenameLen, const char* packageName, const char* bundleName, UErrorCode *status); /* write a xml resource file */ -/* commented by Jing*/ -/* void bundle_write_xml(struct SRBRoot *bundle, const char *outputDir,const char* outputEnc, - char *writtenFilename, int writtenFilenameLen,UErrorCode *status); */ - -/* added by Jing*/ +// TODO: C++ify void bundle_write_xml(struct SRBRoot *bundle, const char *outputDir,const char* outputEnc, const char* rbname, char *writtenFilename, int writtenFilenameLen, const char* language, const char* package, UErrorCode *status); -void bundle_close(struct SRBRoot *bundle, UErrorCode *status); -void bundle_setlocale(struct SRBRoot *bundle, UChar *locale, UErrorCode *status); -uint16_t bundle_addtag(struct SRBRoot *bundle, const char *tag, UErrorCode *status); - /* Various resource types */ -struct SResTable { - uint16_t fCount; - uint32_t fChildrenSize; - struct SResource *fFirst; - struct SRBRoot *fRoot; +/* + * Return a unique pointer to a dummy object, + * for use in non-error cases when no resource is to be added to the bundle. + * (NULL is used in error cases.) + */ +struct SResource* res_none(void); + +class ArrayResource; +class TableResource; +class IntVectorResource; + +TableResource *table_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status); + +ArrayResource *array_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status); + +struct SResource *string_open(struct SRBRoot *bundle, const char *tag, const UChar *value, int32_t len, const struct UString* comment, UErrorCode *status); + +struct SResource *alias_open(struct SRBRoot *bundle, const char *tag, UChar *value, int32_t len, const struct UString* comment, UErrorCode *status); + +IntVectorResource *intvector_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status); + +struct SResource *int_open(struct SRBRoot *bundle, const char *tag, int32_t value, const struct UString* comment, UErrorCode *status); + +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); + +/* Resource place holder */ + +struct SResource { + SResource(); + SResource(SRBRoot *bundle, const char *tag, int8_t type, const UString* comment, + UErrorCode &errorCode); + virtual ~SResource(); + + UBool isTable() const { return fType == URES_TABLE; } + UBool isString() const { return fType == URES_STRING; } + + const char *getKeyString(const SRBRoot *bundle) const; + + /** + * Preflights strings. + * Finds duplicates and counts the total number of string code units + * so that they can be written first to the 16-bit array, + * for minimal string and container storage. + * + * We walk the final parse tree, rather than collecting this information while building it, + * so that we need not deal with changes to the parse tree (especially removing resources). + */ + void preflightStrings(SRBRoot *bundle, UHashtable *stringSet, UErrorCode &errorCode); + virtual void handlePreflightStrings(SRBRoot *bundle, UHashtable *stringSet, UErrorCode &errorCode); + + /** + * Writes resource values into f16BitUnits + * and determines the resource item word, if possible. + */ + void write16(SRBRoot *bundle); + virtual void handleWrite16(SRBRoot *bundle); + + /** + * Calculates ("preflights") and advances the *byteOffset + * by the size of the resource's data in the binary file and + * determines the resource item word. + * + * Most handlePreWrite() functions may add any number of bytes, but preWrite() + * will always pad it to a multiple of 4. + * The resource item type may be a related subtype of the fType. + * + * The preWrite() and write() functions start and end at the same + * byteOffset values. + * Prewriting allows bundle.write() to determine the root resource item word, + * before actually writing the bundle contents to the file, + * which is necessary because the root item is stored at the beginning. + */ + void preWrite(uint32_t *byteOffset); + virtual void handlePreWrite(uint32_t *byteOffset); + + /** + * Writes the resource's data to mem and updates the byteOffset + * in parallel. + */ + void write(UNewDataMemory *mem, uint32_t *byteOffset); + virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset); + + /** + * Applies the given filter with the given base path to this resource. + * Removes child resources rejected by the filter recursively. + * + * @param bundle Needed in order to access the key for this and child resources. + */ + virtual void applyFilter(const PathFilter& filter, ResKeyPath& path, const SRBRoot* bundle); + + /** + * Calls the given function for every key ID present in this tree. + */ + virtual void collectKeys(std::function collector) const; + + int8_t fType; /* nominal type: fRes (when != 0xffffffff) may use subtype */ + UBool fWritten; /* res_write() can exit early */ + uint32_t fRes; /* resource item word; RES_BOGUS=0xffffffff if not known yet */ + int32_t fRes16; /* Res16 version of fRes for Table, Table16, Array16; -1 if it does not fit. */ + int32_t fKey; /* Index into bundle->fKeys; -1 if no key. */ + int32_t fKey16; /* Key16 version of fKey for Table & Table16; -1 if no key or it does not fit. */ + int line; /* used internally to report duplicate keys in tables */ + SResource *fNext; /* This is for internal chaining while building */ + struct UString fComment; }; -struct SResource* table_open(struct SRBRoot *bundle, char *tag, UErrorCode *status); -void table_close(struct SResource *table, UErrorCode *status); -void table_add(struct SResource *table, struct SResource *res, int linenumber, UErrorCode *status); +class ContainerResource : public SResource { +public: + ContainerResource(SRBRoot *bundle, const char *tag, int8_t type, + const UString* comment, UErrorCode &errorCode) + : SResource(bundle, tag, type, comment, errorCode), + fCount(0), fFirst(NULL) {} + virtual ~ContainerResource(); + + void handlePreflightStrings(SRBRoot *bundle, UHashtable *stringSet, UErrorCode &errorCode) override; + + void collectKeys(std::function collector) const override; + +protected: + void writeAllRes16(SRBRoot *bundle); + void preWriteAllRes(uint32_t *byteOffset); + void writeAllRes(UNewDataMemory *mem, uint32_t *byteOffset); + void writeAllRes32(UNewDataMemory *mem, uint32_t *byteOffset); -struct SResArray { +public: + // TODO: private with getter? uint32_t fCount; - uint32_t fChildrenSize; - struct SResource *fFirst; - struct SResource *fLast; + SResource *fFirst; }; -struct SResource* array_open(struct SRBRoot *bundle, char *tag, UErrorCode *status); -void array_close(struct SResource *array, UErrorCode *status); -void array_add(struct SResource *array, struct SResource *res, UErrorCode *status); +class TableResource : public ContainerResource { +public: + TableResource(SRBRoot *bundle, const char *tag, + const UString* comment, UErrorCode &errorCode) + : ContainerResource(bundle, tag, URES_TABLE, comment, errorCode), + fTableType(URES_TABLE), fRoot(bundle) {} + virtual ~TableResource(); -struct SResString { - uint32_t fLength; - UChar *fChars; + void add(SResource *res, int linenumber, UErrorCode &errorCode); + + void handleWrite16(SRBRoot *bundle) override; + void handlePreWrite(uint32_t *byteOffset) override; + void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset) override; + + void applyFilter(const PathFilter& filter, ResKeyPath& path, const SRBRoot* bundle) override; + + int8_t fTableType; // determined by table_write16() for table_preWrite() & table_write() + SRBRoot *fRoot; }; -struct SResource *string_open(struct SRBRoot *bundle, char *tag, const UChar *value, int32_t len, UErrorCode *status); -void string_close(struct SResource *string, UErrorCode *status); +class ArrayResource : public ContainerResource { +public: + ArrayResource(SRBRoot *bundle, const char *tag, + const UString* comment, UErrorCode &errorCode) + : ContainerResource(bundle, tag, URES_ARRAY, comment, errorCode), + fLast(NULL) {} + virtual ~ArrayResource(); -struct SResource *alias_open(struct SRBRoot *bundle, char *tag, UChar *value, int32_t len, UErrorCode *status); -void alias_close(struct SResource *string, UErrorCode *status); + void add(SResource *res); -struct SResIntVector { - uint32_t fCount; - uint32_t *fArray; + virtual void handleWrite16(SRBRoot *bundle); + virtual void handlePreWrite(uint32_t *byteOffset); + virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset); + + SResource *fLast; }; -struct SResource* intvector_open(struct SRBRoot *bundle, char *tag, UErrorCode *status); -void intvector_close(struct SResource *intvector, UErrorCode *status); -void intvector_add(struct SResource *intvector, int32_t value, UErrorCode *status); +/** + * List of resources for a pool bundle. + * Writes an empty table resource, rather than a container structure. + */ +class PseudoListResource : public ContainerResource { +public: + PseudoListResource(SRBRoot *bundle, UErrorCode &errorCode) + : ContainerResource(bundle, NULL, URES_TABLE, NULL, errorCode) {} + virtual ~PseudoListResource(); + + void add(SResource *res); -struct SResInt { - uint32_t fValue; + virtual void handleWrite16(SRBRoot *bundle); }; -struct SResource *int_open(struct SRBRoot *bundle, char *tag, int32_t value, UErrorCode *status); -void int_close(struct SResource *intres, UErrorCode *status); +class StringBaseResource : public SResource { +public: + StringBaseResource(SRBRoot *bundle, const char *tag, int8_t type, + const UChar *value, int32_t len, + const UString* comment, UErrorCode &errorCode); + StringBaseResource(SRBRoot *bundle, int8_t type, + const icu::UnicodeString &value, UErrorCode &errorCode); + StringBaseResource(int8_t type, const UChar *value, int32_t len, UErrorCode &errorCode); + virtual ~StringBaseResource(); -struct SResBinary { - uint32_t fLength; - uint8_t *fData; - char* fFileName; /* file name for binary or import binary tags if any */ + const UChar *getBuffer() const { return icu::toUCharPtr(fString.getBuffer()); } + int32_t length() const { return fString.length(); } + + virtual void handlePreWrite(uint32_t *byteOffset); + virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset); + + // TODO: private with getter? + icu::UnicodeString fString; }; -struct SResource *bin_open(struct SRBRoot *bundle, const char *tag, uint32_t length, uint8_t *data, const char* fileName, UErrorCode *status); -void bin_close(struct SResource *binres, UErrorCode *status); +class StringResource : public StringBaseResource { +public: + StringResource(SRBRoot *bundle, const char *tag, const UChar *value, int32_t len, + const UString* comment, UErrorCode &errorCode) + : StringBaseResource(bundle, tag, URES_STRING, value, len, comment, errorCode), + fSame(NULL), fSuffixOffset(0), + fNumCopies(0), fNumUnitsSaved(0), fNumCharsForLength(0) {} + StringResource(SRBRoot *bundle, const icu::UnicodeString &value, UErrorCode &errorCode) + : StringBaseResource(bundle, URES_STRING, value, errorCode), + fSame(NULL), fSuffixOffset(0), + fNumCopies(0), fNumUnitsSaved(0), fNumCharsForLength(0) {} + StringResource(int32_t poolStringIndex, int8_t numCharsForLength, + const UChar *value, int32_t length, + UErrorCode &errorCode) + : StringBaseResource(URES_STRING, value, length, errorCode), + fSame(NULL), fSuffixOffset(0), + fNumCopies(0), fNumUnitsSaved(0), fNumCharsForLength(numCharsForLength) { + // v3 pool string encoded as string-v2 with low offset + fRes = URES_MAKE_RESOURCE(URES_STRING_V2, poolStringIndex); + fWritten = TRUE; + } + virtual ~StringResource(); -/* Resource place holder */ + int32_t get16BitStringsLength() const { + return fNumCharsForLength + length() + 1; // +1 for the NUL + } -struct SResource { - UResType fType; - uint16_t fKey; - uint32_t fSize; /* Size in bytes outside the header part */ - int line; /* used internally to report duplicate keys in tables */ - struct SResource *fNext; /*This is for internal chaining while building*/ - union { - struct SResTable fTable; - struct SResArray fArray; - struct SResString fString; - struct SResIntVector fIntVector; - struct SResInt fIntValue; - struct SResBinary fBinaryValue; - } u; + virtual void handlePreflightStrings(SRBRoot *bundle, UHashtable *stringSet, UErrorCode &errorCode); + virtual void handleWrite16(SRBRoot *bundle); + + void writeUTF16v2(int32_t base, icu::UnicodeString &dest); + + StringResource *fSame; // used for duplicates + int32_t fSuffixOffset; // this string is a suffix of fSame at this offset + int32_t fNumCopies; // number of equal strings represented by one stringSet element + int32_t fNumUnitsSaved; // from not writing duplicates and suffixes + int8_t fNumCharsForLength; }; -void res_close(struct SResource *res, UErrorCode *status); +class AliasResource : public StringBaseResource { +public: + AliasResource(SRBRoot *bundle, const char *tag, const UChar *value, int32_t len, + const UString* comment, UErrorCode &errorCode) + : StringBaseResource(bundle, tag, URES_ALIAS, value, len, comment, errorCode) {} + virtual ~AliasResource(); +}; + +class IntResource : public SResource { +public: + IntResource(SRBRoot *bundle, const char *tag, int32_t value, + const UString* comment, UErrorCode &errorCode); + virtual ~IntResource(); + + // TODO: private with getter? + int32_t fValue; +}; + +class IntVectorResource : public SResource { +public: + IntVectorResource(SRBRoot *bundle, const char *tag, + const UString* comment, UErrorCode &errorCode); + virtual ~IntVectorResource(); + + void add(int32_t value, UErrorCode &errorCode); + + virtual void handlePreWrite(uint32_t *byteOffset); + virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset); + + // TODO: UVector32 + uint32_t fCount; + uint32_t *fArray; +}; + +class BinaryResource : public SResource { +public: + BinaryResource(SRBRoot *bundle, const char *tag, + uint32_t length, uint8_t *data, const char* fileName, + const UString* comment, UErrorCode &errorCode); + virtual ~BinaryResource(); + + virtual void handlePreWrite(uint32_t *byteOffset); + virtual void handleWrite(UNewDataMemory *mem, uint32_t *byteOffset); + + // TODO: CharString? + uint32_t fLength; + uint8_t *fData; + // TODO: CharString + char* fFileName; // file name for binary or import binary tags if any +}; + +// TODO: use LocalPointer or delete +void res_close(struct SResource *res); + void setIncludeCopyright(UBool val); UBool getIncludeCopyright(void); +void setFormatVersion(int32_t formatVersion); + +int32_t getFormatVersion(); + +void setUsePoolBundle(UBool use); + +/* in wrtxml.cpp */ +uint32_t computeCRC(const char *ptr, uint32_t len, uint32_t lastcrc); + U_CDECL_END #endif /* #ifndef RESLIST_H */