+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<void(int32_t)> 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;