/*
*******************************************************************************
*
*   Copyright (C) 2000-2014, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*
* File reslist.c
*
* Modification History:
*
*   Date        Name        Description
*   02/21/00    weiv        Creation.
*******************************************************************************
*/

#include <assert.h>
#include <stdio.h>
#include "reslist.h"
#include "unewdata.h"
#include "unicode/ures.h"
#include "unicode/putil.h"
#include "errmsg.h"

#include "uarrsort.h"
#include "uelement.h"
#include "uhash.h"
#include "uinvchar.h"
#include "ustr_imp.h"
#include "unicode/utf16.h"
/*
 * Align binary data at a 16-byte offset from the start of the resource bundle,
 * to be safe for any data type it may contain.
 */
#define BIN_ALIGNMENT 16

static UBool gIncludeCopyright = FALSE;
static UBool gUsePoolBundle = FALSE;
static int32_t gFormatVersion = 2;

static UChar gEmptyString = 0;

/* How do we store string values? */
enum {
    STRINGS_UTF16_V1,   /* formatVersion 1: int length + UChars + NUL + padding to 4 bytes */
    STRINGS_UTF16_V2    /* formatVersion 2: optional length in 1..3 UChars + UChars + NUL */
};

enum {
    MAX_IMPLICIT_STRING_LENGTH = 40  /* do not store the length explicitly for such strings */
};

/*
 * res_none() returns the address of kNoResource,
 * for use in non-error cases when no resource is to be added to the bundle.
 * (NULL is used in error cases.)
 */
static const struct SResource kNoResource = { URES_NONE };

static UDataInfo dataInfo= {
    sizeof(UDataInfo),
    0,

    U_IS_BIG_ENDIAN,
    U_CHARSET_FAMILY,
    sizeof(UChar),
    0,

    {0x52, 0x65, 0x73, 0x42},     /* dataFormat="ResB" */
    {1, 3, 0, 0},                 /* formatVersion */
    {1, 4, 0, 0}                  /* dataVersion take a look at version inside parsed resb*/
};

static const UVersionInfo gFormatVersions[3] = {  /* indexed by a major-formatVersion integer */
    { 0, 0, 0, 0 },
    { 1, 3, 0, 0 },
    { 2, 0, 0, 0 }
};

static uint8_t calcPadding(uint32_t size) {
    /* returns space we need to pad */
    return (uint8_t) ((size % sizeof(uint32_t)) ? (sizeof(uint32_t) - (size % sizeof(uint32_t))) : 0);

}

void setIncludeCopyright(UBool val){
    gIncludeCopyright=val;
}

UBool getIncludeCopyright(void){
    return gIncludeCopyright;
}

void setFormatVersion(int32_t formatVersion) {
    gFormatVersion = formatVersion;
}

void setUsePoolBundle(UBool use) {
    gUsePoolBundle = use;
}

static void
bundle_compactStrings(struct SRBRoot *bundle, UErrorCode *status);

/* Writing Functions */

/*
 * Preflight strings.
 * Find duplicates and count 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).
 */
static void
res_preflightStrings(struct SRBRoot *bundle, struct SResource *res, UHashtable *stringSet,
                     UErrorCode *status);

/*
 * type_write16() functions write resource values into f16BitUnits
 * and determine the resource item word, if possible.
 */
static void
res_write16(struct SRBRoot *bundle, struct SResource *res,
            UErrorCode *status);

/*
 * type_preWrite() functions calculate ("preflight") and advance the *byteOffset
 * by the size of their data in the binary file and
 * determine the resource item word.
 * Most type_preWrite() functions may add any number of bytes, but res_preWrite()
 * will always pad it to a multiple of 4.
 * The resource item type may be a related subtype of the fType.
 *
 * The type_preWrite() and type_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.
 */
static void
res_preWrite(uint32_t *byteOffset,
             struct SRBRoot *bundle, struct SResource *res,
             UErrorCode *status);

/*
 * type_write() functions write their data to mem and update the byteOffset
 * in parallel.
 * (A kingdom for C++ and polymorphism...)
 */
static void
res_write(UNewDataMemory *mem, uint32_t *byteOffset,
          struct SRBRoot *bundle, struct SResource *res,
          UErrorCode *status);

static void
string_preflightStrings(struct SRBRoot *bundle, struct SResource *res, UHashtable *stringSet,
                        UErrorCode *status) {
    res->u.fString.fSame = uhash_get(stringSet, res);
    if (res->u.fString.fSame != NULL) {
        return;  /* This is a duplicate of an earlier-visited string. */
    }
    /* Put this string into the set for finding duplicates. */
    uhash_put(stringSet, res, res, status);

    if (bundle->fStringsForm != STRINGS_UTF16_V1) {
        const UChar *s = res->u.fString.fChars;
        int32_t len = res->u.fString.fLength;
        if (len <= MAX_IMPLICIT_STRING_LENGTH && !U16_IS_TRAIL(s[0]) && len == u_strlen(s)) {
            /*
             * This string will be stored without an explicit length.
             * Runtime will detect !U16_IS_TRAIL(s[0]) and call u_strlen().
             */
            res->u.fString.fNumCharsForLength = 0;
        } else if (len <= 0x3ee) {
            res->u.fString.fNumCharsForLength = 1;
        } else if (len <= 0xfffff) {
            res->u.fString.fNumCharsForLength = 2;
        } else {
            res->u.fString.fNumCharsForLength = 3;
        }
        bundle->f16BitUnitsLength += res->u.fString.fNumCharsForLength + len + 1;  /* +1 for the NUL */
    }
}

static void
array_preflightStrings(struct SRBRoot *bundle, struct SResource *res, UHashtable *stringSet,
                       UErrorCode *status) {
    struct SResource *current;

    if (U_FAILURE(*status)) {
        return;
    }
    for (current = res->u.fArray.fFirst; current != NULL; current = current->fNext) {
        res_preflightStrings(bundle, current, stringSet, status);
    }
}

static void
table_preflightStrings(struct SRBRoot *bundle, struct SResource *res, UHashtable *stringSet,
                       UErrorCode *status) {
    struct SResource *current;

    if (U_FAILURE(*status)) {
        return;
    }
    for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) {
        res_preflightStrings(bundle, current, stringSet, status);
    }
}

static void
res_preflightStrings(struct SRBRoot *bundle, struct SResource *res, UHashtable *stringSet,
                     UErrorCode *status) {
    if (U_FAILURE(*status) || res == NULL) {
        return;
    }
    if (res->fRes != RES_BOGUS) {
        /*
         * The resource item word was already precomputed, which means
         * no further data needs to be written.
         * This might be an integer, or an empty string/binary/etc.
         */
        return;
    }
    switch (res->fType) {
    case URES_STRING:
        string_preflightStrings(bundle, res, stringSet, status);
        break;
    case URES_ARRAY:
        array_preflightStrings(bundle, res, stringSet, status);
        break;
    case URES_TABLE:
        table_preflightStrings(bundle, res, stringSet, status);
        break;
    default:
        /* Neither a string nor a container. */
        break;
    }
}

static uint16_t *
reserve16BitUnits(struct SRBRoot *bundle, int32_t length, UErrorCode *status) {
    if (U_FAILURE(*status)) {
        return NULL;
    }
    if ((bundle->f16BitUnitsLength + length) > bundle->f16BitUnitsCapacity) {
        uint16_t *newUnits;
        int32_t capacity = 2 * bundle->f16BitUnitsCapacity + length + 1024;
        capacity &= ~1;  /* ensures padding fits if f16BitUnitsLength needs it */
        newUnits = (uint16_t *)uprv_malloc(capacity * 2);
        if (newUnits == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            return NULL;
        }
        if (bundle->f16BitUnitsLength > 0) {
            uprv_memcpy(newUnits, bundle->f16BitUnits, bundle->f16BitUnitsLength * 2);
        } else {
            newUnits[0] = 0;
            bundle->f16BitUnitsLength = 1;
        }
        uprv_free(bundle->f16BitUnits);
        bundle->f16BitUnits = newUnits;
        bundle->f16BitUnitsCapacity = capacity;
    }
    return bundle->f16BitUnits + bundle->f16BitUnitsLength;
}

static int32_t
makeRes16(uint32_t resWord) {
    uint32_t type, offset;
    if (resWord == 0) {
        return 0;  /* empty string */
    }
    type = RES_GET_TYPE(resWord);
    offset = RES_GET_OFFSET(resWord);
    if (type == URES_STRING_V2 && offset <= 0xffff) {
        return (int32_t)offset;
    }
    return -1;
}

static int32_t
mapKey(struct SRBRoot *bundle, int32_t oldpos) {
    const KeyMapEntry *map = bundle->fKeyMap;
    int32_t i, start, limit;

    /* do a binary search for the old, pre-bundle_compactKeys() key offset */
    start = bundle->fPoolBundleKeysCount;
    limit = start + bundle->fKeysCount;
    while (start < limit - 1) {
        i = (start + limit) / 2;
        if (oldpos < map[i].oldpos) {
            limit = i;
        } else {
            start = i;
        }
    }
    assert(oldpos == map[start].oldpos);
    return map[start].newpos;
}

static uint16_t
makeKey16(struct SRBRoot *bundle, int32_t key) {
    if (key >= 0) {
        return (uint16_t)key;
    } else {
        return (uint16_t)(key + bundle->fLocalKeyLimit);  /* offset in the pool bundle */
    }
}

/*
 * Only called for UTF-16 v1 strings and duplicate UTF-16 v2 strings.
 * For unique UTF-16 v2 strings, res_write16() sees fRes != RES_BOGUS
 * and exits early.
 */
static void
string_write16(struct SRBRoot *bundle, struct SResource *res, UErrorCode *status) {
    struct SResource *same;
    if ((same = res->u.fString.fSame) != NULL) {
        /* This is a duplicate. */
        assert(same->fRes != RES_BOGUS && same->fWritten);
        res->fRes = same->fRes;
        res->fWritten = same->fWritten;
    }
}

static void
array_write16(struct SRBRoot *bundle, struct SResource *res,
              UErrorCode *status) {
    struct SResource *current;
    int32_t res16 = 0;

    if (U_FAILURE(*status)) {
        return;
    }
    if (res->u.fArray.fCount == 0 && gFormatVersion > 1) {
        res->fRes = URES_MAKE_EMPTY_RESOURCE(URES_ARRAY);
        res->fWritten = TRUE;
        return;
    }
    for (current = res->u.fArray.fFirst; current != NULL; current = current->fNext) {
        res_write16(bundle, current, status);
        res16 |= makeRes16(current->fRes);
    }
    if (U_SUCCESS(*status) && res->u.fArray.fCount <= 0xffff && res16 >= 0 && gFormatVersion > 1) {
        uint16_t *p16 = reserve16BitUnits(bundle, 1 + res->u.fArray.fCount, status);
        if (U_SUCCESS(*status)) {
            res->fRes = URES_MAKE_RESOURCE(URES_ARRAY16, bundle->f16BitUnitsLength);
            *p16++ = (uint16_t)res->u.fArray.fCount;
            for (current = res->u.fArray.fFirst; current != NULL; current = current->fNext) {
                *p16++ = (uint16_t)makeRes16(current->fRes);
            }
            bundle->f16BitUnitsLength += 1 + res->u.fArray.fCount;
            res->fWritten = TRUE;
        }
    }
}

static void
table_write16(struct SRBRoot *bundle, struct SResource *res,
              UErrorCode *status) {
    struct SResource *current;
    int32_t maxKey = 0, maxPoolKey = 0x80000000;
    int32_t res16 = 0;
    UBool hasLocalKeys = FALSE, hasPoolKeys = FALSE;

    if (U_FAILURE(*status)) {
        return;
    }
    if (res->u.fTable.fCount == 0 && gFormatVersion > 1) {
        res->fRes = URES_MAKE_EMPTY_RESOURCE(URES_TABLE);
        res->fWritten = TRUE;
        return;
    }
    /* Find the smallest table type that fits the data. */
    for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) {
        int32_t key;
        res_write16(bundle, current, status);
        if (bundle->fKeyMap == NULL) {
            key = current->fKey;
        } else {
            key = current->fKey = mapKey(bundle, current->fKey);
        }
        if (key >= 0) {
            hasLocalKeys = TRUE;
            if (key > maxKey) {
                maxKey = key;
            }
        } else {
            hasPoolKeys = TRUE;
            if (key > maxPoolKey) {
                maxPoolKey = key;
            }
        }
        res16 |= makeRes16(current->fRes);
    }
    if (U_FAILURE(*status)) {
        return;
    }
    if(res->u.fTable.fCount > (uint32_t)bundle->fMaxTableLength) {
        bundle->fMaxTableLength = res->u.fTable.fCount;
    }
    maxPoolKey &= 0x7fffffff;
    if (res->u.fTable.fCount <= 0xffff &&
        (!hasLocalKeys || maxKey < bundle->fLocalKeyLimit) &&
        (!hasPoolKeys || maxPoolKey < (0x10000 - bundle->fLocalKeyLimit))
    ) {
        if (res16 >= 0 && gFormatVersion > 1) {
            uint16_t *p16 = reserve16BitUnits(bundle, 1 + res->u.fTable.fCount * 2, status);
            if (U_SUCCESS(*status)) {
                /* 16-bit count, key offsets and values */
                res->fRes = URES_MAKE_RESOURCE(URES_TABLE16, bundle->f16BitUnitsLength);
                *p16++ = (uint16_t)res->u.fTable.fCount;
                for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) {
                    *p16++ = makeKey16(bundle, current->fKey);
                }
                for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) {
                    *p16++ = (uint16_t)makeRes16(current->fRes);
                }
                bundle->f16BitUnitsLength += 1 + res->u.fTable.fCount * 2;
                res->fWritten = TRUE;
            }
        } else {
            /* 16-bit count, 16-bit key offsets, 32-bit values */
            res->u.fTable.fType = URES_TABLE;
        }
    } else {
        /* 32-bit count, key offsets and values */
        res->u.fTable.fType = URES_TABLE32;
    }
}

static void
res_write16(struct SRBRoot *bundle, struct SResource *res,
            UErrorCode *status) {
    if (U_FAILURE(*status) || res == NULL) {
        return;
    }
    if (res->fRes != RES_BOGUS) {
        /*
         * The resource item word was already precomputed, which means
         * no further data needs to be written.
         * This might be an integer, or an empty or UTF-16 v2 string,
         * an empty binary, etc.
         */
        return;
    }
    switch (res->fType) {
    case URES_STRING:
        string_write16(bundle, res, status);
        break;
    case URES_ARRAY:
        array_write16(bundle, res, status);
        break;
    case URES_TABLE:
        table_write16(bundle, res, status);
        break;
    default:
        /* Only a few resource types write 16-bit units. */
        break;
    }
}

/*
 * Only called for UTF-16 v1 strings.
 * For UTF-16 v2 strings, res_preWrite() sees fRes != RES_BOGUS
 * and exits early.
 */
static void
string_preWrite(uint32_t *byteOffset,
                struct SRBRoot *bundle, struct SResource *res,
                UErrorCode *status) {
    /* Write the UTF-16 v1 string. */
    res->fRes = URES_MAKE_RESOURCE(URES_STRING, *byteOffset >> 2);
    *byteOffset += 4 + (res->u.fString.fLength + 1) * U_SIZEOF_UCHAR;
}

static void
bin_preWrite(uint32_t *byteOffset,
             struct SRBRoot *bundle, struct SResource *res,
             UErrorCode *status) {
    uint32_t pad       = 0;
    uint32_t dataStart = *byteOffset + sizeof(res->u.fBinaryValue.fLength);

    if (dataStart % BIN_ALIGNMENT) {
        pad = (BIN_ALIGNMENT - dataStart % BIN_ALIGNMENT);
        *byteOffset += pad;  /* pad == 4 or 8 or 12 */
    }
    res->fRes = URES_MAKE_RESOURCE(URES_BINARY, *byteOffset >> 2);
    *byteOffset += 4 + res->u.fBinaryValue.fLength;
}

static void
array_preWrite(uint32_t *byteOffset,
               struct SRBRoot *bundle, struct SResource *res,
               UErrorCode *status) {
    struct SResource *current;

    if (U_FAILURE(*status)) {
        return;
    }
    for (current = res->u.fArray.fFirst; current != NULL; current = current->fNext) {
        res_preWrite(byteOffset, bundle, current, status);
    }
    res->fRes = URES_MAKE_RESOURCE(URES_ARRAY, *byteOffset >> 2);
    *byteOffset += (1 + res->u.fArray.fCount) * 4;
}

static void
table_preWrite(uint32_t *byteOffset,
               struct SRBRoot *bundle, struct SResource *res,
               UErrorCode *status) {
    struct SResource *current;

    if (U_FAILURE(*status)) {
        return;
    }
    for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) {
        res_preWrite(byteOffset, bundle, current, status);
    }
    if (res->u.fTable.fType == URES_TABLE) {
        /* 16-bit count, 16-bit key offsets, 32-bit values */
        res->fRes = URES_MAKE_RESOURCE(URES_TABLE, *byteOffset >> 2);
        *byteOffset += 2 + res->u.fTable.fCount * 6;
    } else {
        /* 32-bit count, key offsets and values */
        res->fRes = URES_MAKE_RESOURCE(URES_TABLE32, *byteOffset >> 2);
        *byteOffset += 4 + res->u.fTable.fCount * 8;
    }
}

static void
res_preWrite(uint32_t *byteOffset,
             struct SRBRoot *bundle, struct SResource *res,
             UErrorCode *status) {
    if (U_FAILURE(*status) || res == NULL) {
        return;
    }
    if (res->fRes != RES_BOGUS) {
        /*
         * The resource item word was already precomputed, which means
         * no further data needs to be written.
         * This might be an integer, or an empty or UTF-16 v2 string,
         * an empty binary, etc.
         */
        return;
    }
    switch (res->fType) {
    case URES_STRING:
        string_preWrite(byteOffset, bundle, res, status);
        break;
    case URES_ALIAS:
        res->fRes = URES_MAKE_RESOURCE(URES_ALIAS, *byteOffset >> 2);
        *byteOffset += 4 + (res->u.fString.fLength + 1) * U_SIZEOF_UCHAR;
        break;
    case URES_INT_VECTOR:
        if (res->u.fIntVector.fCount == 0 && gFormatVersion > 1) {
            res->fRes = URES_MAKE_EMPTY_RESOURCE(URES_INT_VECTOR);
            res->fWritten = TRUE;
        } else {
            res->fRes = URES_MAKE_RESOURCE(URES_INT_VECTOR, *byteOffset >> 2);
            *byteOffset += (1 + res->u.fIntVector.fCount) * 4;
        }
        break;
    case URES_BINARY:
        bin_preWrite(byteOffset, bundle, res, status);
        break;
    case URES_INT:
        break;
    case URES_ARRAY:
        array_preWrite(byteOffset, bundle, res, status);
        break;
    case URES_TABLE:
        table_preWrite(byteOffset, bundle, res, status);
        break;
    default:
        *status = U_INTERNAL_PROGRAM_ERROR;
        break;
    }
    *byteOffset += calcPadding(*byteOffset);
}

/*
 * Only called for UTF-16 v1 strings. For UTF-16 v2 strings,
 * res_write() sees fWritten and exits early.
 */
static void string_write(UNewDataMemory *mem, uint32_t *byteOffset,
                         struct SRBRoot *bundle, struct SResource *res,
                         UErrorCode *status) {
    /* Write the UTF-16 v1 string. */
    int32_t length = res->u.fString.fLength;
    udata_write32(mem, length);
    udata_writeUString(mem, res->u.fString.fChars, length + 1);
    *byteOffset += 4 + (length + 1) * U_SIZEOF_UCHAR;
    res->fWritten = TRUE;
}

static void alias_write(UNewDataMemory *mem, uint32_t *byteOffset,
                        struct SRBRoot *bundle, struct SResource *res,
                        UErrorCode *status) {
    int32_t length = res->u.fString.fLength;
    udata_write32(mem, length);
    udata_writeUString(mem, res->u.fString.fChars, length + 1);
    *byteOffset += 4 + (length + 1) * U_SIZEOF_UCHAR;
}

static void array_write(UNewDataMemory *mem, uint32_t *byteOffset,
                        struct SRBRoot *bundle, struct SResource *res,
                        UErrorCode *status) {
    uint32_t  i;

    struct SResource *current = NULL;

    if (U_FAILURE(*status)) {
        return;
    }
    for (i = 0, current = res->u.fArray.fFirst; current != NULL; ++i, current = current->fNext) {
        res_write(mem, byteOffset, bundle, current, status);
    }
    assert(i == res->u.fArray.fCount);

    udata_write32(mem, res->u.fArray.fCount);
    for (current = res->u.fArray.fFirst; current != NULL; current = current->fNext) {
        udata_write32(mem, current->fRes);
    }
    *byteOffset += (1 + res->u.fArray.fCount) * 4;
}

static void intvector_write(UNewDataMemory *mem, uint32_t *byteOffset,
                            struct SRBRoot *bundle, struct SResource *res,
                            UErrorCode *status) {
    uint32_t i = 0;
    udata_write32(mem, res->u.fIntVector.fCount);
    for(i = 0; i<res->u.fIntVector.fCount; i++) {
      udata_write32(mem, res->u.fIntVector.fArray[i]);
    }
    *byteOffset += (1 + res->u.fIntVector.fCount) * 4;
}

static void bin_write(UNewDataMemory *mem, uint32_t *byteOffset,
                      struct SRBRoot *bundle, struct SResource *res,
                      UErrorCode *status) {
    uint32_t pad       = 0;
    uint32_t dataStart = *byteOffset + sizeof(res->u.fBinaryValue.fLength);

    if (dataStart % BIN_ALIGNMENT) {
        pad = (BIN_ALIGNMENT - dataStart % BIN_ALIGNMENT);
        udata_writePadding(mem, pad);  /* pad == 4 or 8 or 12 */
        *byteOffset += pad;
    }

    udata_write32(mem, res->u.fBinaryValue.fLength);
    if (res->u.fBinaryValue.fLength > 0) {
        udata_writeBlock(mem, res->u.fBinaryValue.fData, res->u.fBinaryValue.fLength);
    }
    *byteOffset += 4 + res->u.fBinaryValue.fLength;
}

static void table_write(UNewDataMemory *mem, uint32_t *byteOffset,
                        struct SRBRoot *bundle, struct SResource *res,
                        UErrorCode *status) {
    struct SResource *current;
    uint32_t i;

    if (U_FAILURE(*status)) {
        return;
    }
    for (i = 0, current = res->u.fTable.fFirst; current != NULL; ++i, current = current->fNext) {
        assert(i < res->u.fTable.fCount);
        res_write(mem, byteOffset, bundle, current, status);
    }
    assert(i == res->u.fTable.fCount);

    if(res->u.fTable.fType == URES_TABLE) {
        udata_write16(mem, (uint16_t)res->u.fTable.fCount);
        for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) {
            udata_write16(mem, makeKey16(bundle, current->fKey));
        }
        *byteOffset += (1 + res->u.fTable.fCount)* 2;
        if ((res->u.fTable.fCount & 1) == 0) {
            /* 16-bit count and even number of 16-bit key offsets need padding before 32-bit resource items */
            udata_writePadding(mem, 2);
            *byteOffset += 2;
        }
    } else /* URES_TABLE32 */ {
        udata_write32(mem, res->u.fTable.fCount);
        for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) {
            udata_write32(mem, (uint32_t)current->fKey);
        }
        *byteOffset += (1 + res->u.fTable.fCount)* 4;
    }
    for (current = res->u.fTable.fFirst; current != NULL; current = current->fNext) {
        udata_write32(mem, current->fRes);
    }
    *byteOffset += res->u.fTable.fCount * 4;
}

void res_write(UNewDataMemory *mem, uint32_t *byteOffset,
               struct SRBRoot *bundle, struct SResource *res,
               UErrorCode *status) {
    uint8_t paddingSize;

    if (U_FAILURE(*status) || res == NULL) {
        return;
    }
    if (res->fWritten) {
        assert(res->fRes != RES_BOGUS);
        return;
    }
    switch (res->fType) {
    case URES_STRING:
        string_write    (mem, byteOffset, bundle, res, status);
        break;
    case URES_ALIAS:
        alias_write     (mem, byteOffset, bundle, res, status);
        break;
    case URES_INT_VECTOR:
        intvector_write (mem, byteOffset, bundle, res, status);
        break;
    case URES_BINARY:
        bin_write       (mem, byteOffset, bundle, res, status);
        break;
    case URES_INT:
        break;  /* fRes was set by int_open() */
    case URES_ARRAY:
        array_write     (mem, byteOffset, bundle, res, status);
        break;
    case URES_TABLE:
        table_write     (mem, byteOffset, bundle, res, status);
        break;
    default:
        *status = U_INTERNAL_PROGRAM_ERROR;
        break;
    }
    paddingSize = calcPadding(*byteOffset);
    if (paddingSize > 0) {
        udata_writePadding(mem, paddingSize);
        *byteOffset += paddingSize;
    }
    res->fWritten = TRUE;
}

void bundle_write(struct SRBRoot *bundle,
                  const char *outputDir, const char *outputPkg,
                  char *writtenFilename, int writtenFilenameLen,
                  UErrorCode *status) {
    UNewDataMemory *mem        = NULL;
    uint32_t        byteOffset = 0;
    uint32_t        top, size;
    char            dataName[1024];
    int32_t         indexes[URES_INDEX_TOP];

    bundle_compactKeys(bundle, status);
    /*
     * Add padding bytes to fKeys so that fKeysTop is 4-aligned.
     * Safe because the capacity is a multiple of 4.
     */
    while (bundle->fKeysTop & 3) {
        bundle->fKeys[bundle->fKeysTop++] = (char)0xaa;
    }
    /*
     * In URES_TABLE, use all local key offsets that fit into 16 bits,
     * and use the remaining 16-bit offsets for pool key offsets
     * if there are any.
     * If there are no local keys, then use the whole 16-bit space
     * for pool key offsets.
     * Note: This cannot be changed without changing the major formatVersion.
     */
    if (bundle->fKeysBottom < bundle->fKeysTop) {
        if (bundle->fKeysTop <= 0x10000) {
            bundle->fLocalKeyLimit = bundle->fKeysTop;
        } else {
            bundle->fLocalKeyLimit = 0x10000;
        }
    } else {
        bundle->fLocalKeyLimit = 0;
    }

    bundle_compactStrings(bundle, status);
    res_write16(bundle, bundle->fRoot, status);
    if (bundle->f16BitUnitsLength & 1) {
        bundle->f16BitUnits[bundle->f16BitUnitsLength++] = 0xaaaa;  /* pad to multiple of 4 bytes */
    }
    /* all keys have been mapped */
    uprv_free(bundle->fKeyMap);
    bundle->fKeyMap = NULL;

    byteOffset = bundle->fKeysTop + bundle->f16BitUnitsLength * 2;
    res_preWrite(&byteOffset, bundle, bundle->fRoot, status);

    /* total size including the root item */
    top = byteOffset;

    if (U_FAILURE(*status)) {
        return;
    }

    if (writtenFilename && writtenFilenameLen) {
        *writtenFilename = 0;
    }

    if (writtenFilename) {
       int32_t off = 0, len = 0;
       if (outputDir) {
           len = (int32_t)uprv_strlen(outputDir);
           if (len > writtenFilenameLen) {
               len = writtenFilenameLen;
           }
           uprv_strncpy(writtenFilename, outputDir, len);
       }
       if (writtenFilenameLen -= len) {
           off += len;
           writtenFilename[off] = U_FILE_SEP_CHAR;
           if (--writtenFilenameLen) {
               ++off;
               if(outputPkg != NULL)
               {
                   uprv_strcpy(writtenFilename+off, outputPkg);
                   off += (int32_t)uprv_strlen(outputPkg);
                   writtenFilename[off] = '_';
                   ++off;
               }

               len = (int32_t)uprv_strlen(bundle->fLocale);
               if (len > writtenFilenameLen) {
                   len = writtenFilenameLen;
               }
               uprv_strncpy(writtenFilename + off, bundle->fLocale, len);
               if (writtenFilenameLen -= len) {
                   off += len;
                   len = 5;
                   if (len > writtenFilenameLen) {
                       len = writtenFilenameLen;
                   }
                   uprv_strncpy(writtenFilename +  off, ".res", len);
               }
           }
       }
    }

    if(outputPkg)
    {
        uprv_strcpy(dataName, outputPkg);
        uprv_strcat(dataName, "_");
        uprv_strcat(dataName, bundle->fLocale);
    }
    else
    {
        uprv_strcpy(dataName, bundle->fLocale);
    }

    uprv_memcpy(dataInfo.formatVersion, gFormatVersions + gFormatVersion, sizeof(UVersionInfo));

    mem = udata_create(outputDir, "res", dataName, &dataInfo, (gIncludeCopyright==TRUE)? U_COPYRIGHT_STRING:NULL, status);
    if(U_FAILURE(*status)){
        return;
    }

    /* write the root item */
    udata_write32(mem, bundle->fRoot->fRes);

    /*
     * formatVersion 1.1 (ICU 2.8):
     * write int32_t indexes[] after root and before the strings
     * to make it easier to parse resource bundles in icuswap or from Java etc.
     */
    uprv_memset(indexes, 0, sizeof(indexes));
    indexes[URES_INDEX_LENGTH]=             bundle->fIndexLength;
    indexes[URES_INDEX_KEYS_TOP]=           bundle->fKeysTop>>2;
    indexes[URES_INDEX_RESOURCES_TOP]=      (int32_t)(top>>2);
    indexes[URES_INDEX_BUNDLE_TOP]=         indexes[URES_INDEX_RESOURCES_TOP];
    indexes[URES_INDEX_MAX_TABLE_LENGTH]=   bundle->fMaxTableLength;

    /*
     * formatVersion 1.2 (ICU 3.6):
     * write indexes[URES_INDEX_ATTRIBUTES] with URES_ATT_NO_FALLBACK set or not set
     * the memset() above initialized all indexes[] to 0
     */
    if (bundle->noFallback) {
        indexes[URES_INDEX_ATTRIBUTES]=URES_ATT_NO_FALLBACK;
    }
    /*
     * formatVersion 2.0 (ICU 4.4):
     * more compact string value storage, optional pool bundle
     */
    if (URES_INDEX_16BIT_TOP < bundle->fIndexLength) {
        indexes[URES_INDEX_16BIT_TOP] = (bundle->fKeysTop>>2) + (bundle->f16BitUnitsLength>>1);
    }
    if (URES_INDEX_POOL_CHECKSUM < bundle->fIndexLength) {
        if (bundle->fIsPoolBundle) {
            indexes[URES_INDEX_ATTRIBUTES] |= URES_ATT_IS_POOL_BUNDLE | URES_ATT_NO_FALLBACK;
            indexes[URES_INDEX_POOL_CHECKSUM] =
                (int32_t)computeCRC((char *)(bundle->fKeys + bundle->fKeysBottom),
                                    (uint32_t)(bundle->fKeysTop - bundle->fKeysBottom),
                                    0);
        } else if (gUsePoolBundle) {
            indexes[URES_INDEX_ATTRIBUTES] |= URES_ATT_USES_POOL_BUNDLE;
            indexes[URES_INDEX_POOL_CHECKSUM] = bundle->fPoolChecksum;
        }
    }

    /* write the indexes[] */
    udata_writeBlock(mem, indexes, bundle->fIndexLength*4);

    /* write the table key strings */
    udata_writeBlock(mem, bundle->fKeys+bundle->fKeysBottom,
                          bundle->fKeysTop-bundle->fKeysBottom);

    /* write the v2 UTF-16 strings, URES_TABLE16 and URES_ARRAY16 */
    udata_writeBlock(mem, bundle->f16BitUnits, bundle->f16BitUnitsLength*2);

    /* write all of the bundle contents: the root item and its children */
    byteOffset = bundle->fKeysTop + bundle->f16BitUnitsLength * 2;
    res_write(mem, &byteOffset, bundle, bundle->fRoot, status);
    assert(byteOffset == top);

    size = udata_finish(mem, status);
    if(top != size) {
        fprintf(stderr, "genrb error: wrote %u bytes but counted %u\n",
                (int)size, (int)top);
        *status = U_INTERNAL_PROGRAM_ERROR;
    }
}

/* Opening Functions */

/* gcc 4.2 complained "no previous prototype for res_open" without this prototype... */
struct SResource* res_open(struct SRBRoot *bundle, const char *tag,
                           const struct UString* comment, UErrorCode* status);

struct SResource* res_open(struct SRBRoot *bundle, const char *tag,
                           const struct UString* comment, UErrorCode* status){
    struct SResource *res;
    int32_t key = bundle_addtag(bundle, tag, status);
    if (U_FAILURE(*status)) {
        return NULL;
    }

    res = (struct SResource *) uprv_malloc(sizeof(struct SResource));
    if (res == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return NULL;
    }
    uprv_memset(res, 0, sizeof(struct SResource));
    res->fKey = key;
    res->fRes = RES_BOGUS;

    ustr_init(&res->fComment);
    if(comment != NULL){
        ustr_cpy(&res->fComment, comment, status);
        if (U_FAILURE(*status)) {
            res_close(res);
            return NULL;
        }
    }
    return res;
}

struct SResource* res_none() {
    return (struct SResource*)&kNoResource;
}

struct SResource* table_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status) {
    struct SResource *res = res_open(bundle, tag, comment, status);
    if (U_FAILURE(*status)) {
        return NULL;
    }
    res->fType = URES_TABLE;
    res->u.fTable.fRoot = bundle;
    return res;
}

struct SResource* array_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status) {
    struct SResource *res = res_open(bundle, tag, comment, status);
    if (U_FAILURE(*status)) {
        return NULL;
    }
    res->fType = URES_ARRAY;
    return res;
}

static int32_t U_CALLCONV
string_hash(const UElement key) {
    const struct SResource *res = (struct SResource *)key.pointer;
    return ustr_hashUCharsN(res->u.fString.fChars, res->u.fString.fLength);
}

static UBool U_CALLCONV
string_comp(const UElement key1, const UElement key2) {
    const struct SResource *res1 = (struct SResource *)key1.pointer;
    const struct SResource *res2 = (struct SResource *)key2.pointer;
    return 0 == u_strCompare(res1->u.fString.fChars, res1->u.fString.fLength,
                             res2->u.fString.fChars, res2->u.fString.fLength,
                             FALSE);
}

static struct SResource *
stringbase_open(struct SRBRoot *bundle, const char *tag, int8_t type,
                const UChar *value, int32_t len, const struct UString* comment,
                UErrorCode *status) {
    struct SResource *res = res_open(bundle, tag, comment, status);
    if (U_FAILURE(*status)) {
        return NULL;
    }
    res->fType = type;

    if (len == 0 && gFormatVersion > 1) {
        res->u.fString.fChars = &gEmptyString;
        res->fRes = URES_MAKE_EMPTY_RESOURCE(type);
        res->fWritten = TRUE;
        return res;
    }

    res->u.fString.fLength = len;
    res->u.fString.fChars = (UChar *) uprv_malloc(sizeof(UChar) * (len + 1));
    if (res->u.fString.fChars == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        uprv_free(res);
        return NULL;
    }
    uprv_memcpy(res->u.fString.fChars, value, sizeof(UChar) * len);
    res->u.fString.fChars[len] = 0;
    return res;
}

struct SResource *string_open(struct SRBRoot *bundle, const char *tag, const UChar *value, int32_t len, const struct UString* comment, UErrorCode *status) {
    return stringbase_open(bundle, tag, URES_STRING, value, len, comment, status);
}

struct SResource *alias_open(struct SRBRoot *bundle, const char *tag, UChar *value, int32_t len, const struct UString* comment, UErrorCode *status) {
    return stringbase_open(bundle, tag, URES_ALIAS, value, len, comment, status);
}


struct SResource* intvector_open(struct SRBRoot *bundle, const char *tag, const struct UString* comment, UErrorCode *status) {
    struct SResource *res = res_open(bundle, tag, comment, status);
    if (U_FAILURE(*status)) {
        return NULL;
    }
    res->fType = URES_INT_VECTOR;

    res->u.fIntVector.fCount = 0;
    res->u.fIntVector.fArray = (uint32_t *) uprv_malloc(sizeof(uint32_t) * RESLIST_MAX_INT_VECTOR);
    if (res->u.fIntVector.fArray == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        uprv_free(res);
        return NULL;
    }
    return res;
}

struct SResource *int_open(struct SRBRoot *bundle, const char *tag, int32_t value, const struct UString* comment, UErrorCode *status) {
    struct SResource *res = res_open(bundle, tag, comment, status);
    if (U_FAILURE(*status)) {
        return NULL;
    }
    res->fType = URES_INT;
    res->u.fIntValue.fValue = value;
    res->fRes = URES_MAKE_RESOURCE(URES_INT, value & 0x0FFFFFFF);
    res->fWritten = TRUE;
    return res;
}

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) {
    struct SResource *res = res_open(bundle, tag, comment, status);
    if (U_FAILURE(*status)) {
        return NULL;
    }
    res->fType = URES_BINARY;

    res->u.fBinaryValue.fLength = length;
    res->u.fBinaryValue.fFileName = NULL;
    if(fileName!=NULL && uprv_strcmp(fileName, "") !=0){
        res->u.fBinaryValue.fFileName = (char*) uprv_malloc(sizeof(char) * (uprv_strlen(fileName)+1));
        uprv_strcpy(res->u.fBinaryValue.fFileName,fileName);
    }
    if (length > 0) {
        res->u.fBinaryValue.fData   = (uint8_t *) uprv_malloc(sizeof(uint8_t) * length);

        if (res->u.fBinaryValue.fData == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            uprv_free(res);
            return NULL;
        }

        uprv_memcpy(res->u.fBinaryValue.fData, data, length);
    }
    else {
        res->u.fBinaryValue.fData = NULL;
        if (gFormatVersion > 1) {
            res->fRes = URES_MAKE_EMPTY_RESOURCE(URES_BINARY);
            res->fWritten = TRUE;
        }
    }

    return res;
}

struct SRBRoot *bundle_open(const struct UString* comment, UBool isPoolBundle, UErrorCode *status) {
    struct SRBRoot *bundle;

    if (U_FAILURE(*status)) {
        return NULL;
    }

    bundle = (struct SRBRoot *) uprv_malloc(sizeof(struct SRBRoot));
    if (bundle == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return 0;
    }
    uprv_memset(bundle, 0, sizeof(struct SRBRoot));

    bundle->fKeys = (char *) uprv_malloc(sizeof(char) * KEY_SPACE_SIZE);
    bundle->fRoot = table_open(bundle, NULL, comment, status);
    if (bundle->fKeys == NULL || bundle->fRoot == NULL || U_FAILURE(*status)) {
        if (U_SUCCESS(*status)) {
            *status = U_MEMORY_ALLOCATION_ERROR;
        }
        bundle_close(bundle, status);
        return NULL;
    }

    bundle->fLocale   = NULL;
    bundle->fKeysCapacity = KEY_SPACE_SIZE;
    /* formatVersion 1.1: start fKeysTop after the root item and indexes[] */
    bundle->fIsPoolBundle = isPoolBundle;
    if (gUsePoolBundle || isPoolBundle) {
        bundle->fIndexLength = URES_INDEX_POOL_CHECKSUM + 1;
    } else if (gFormatVersion >= 2) {
        bundle->fIndexLength = URES_INDEX_16BIT_TOP + 1;
    } else /* formatVersion 1 */ {
        bundle->fIndexLength = URES_INDEX_ATTRIBUTES + 1;
    }
    bundle->fKeysBottom = (1 /* root */ + bundle->fIndexLength) * 4;
    uprv_memset(bundle->fKeys, 0, bundle->fKeysBottom);
    bundle->fKeysTop = bundle->fKeysBottom;

    if (gFormatVersion == 1) {
        bundle->fStringsForm = STRINGS_UTF16_V1;
    } else {
        bundle->fStringsForm = STRINGS_UTF16_V2;
    }

    return bundle;
}

/* Closing Functions */
static void table_close(struct SResource *table) {
    struct SResource *current = NULL;
    struct SResource *prev    = NULL;

    current = table->u.fTable.fFirst;

    while (current != NULL) {
        prev    = current;
        current = current->fNext;

        res_close(prev);
    }

    table->u.fTable.fFirst = NULL;
}

static void array_close(struct SResource *array) {
    struct SResource *current = NULL;
    struct SResource *prev    = NULL;
    
    if(array==NULL){
        return;
    }
    current = array->u.fArray.fFirst;
    
    while (current != NULL) {
        prev    = current;
        current = current->fNext;

        res_close(prev);
    }
    array->u.fArray.fFirst = NULL;
}

static void string_close(struct SResource *string) {
    if (string->u.fString.fChars != NULL &&
            string->u.fString.fChars != &gEmptyString) {
        uprv_free(string->u.fString.fChars);
        string->u.fString.fChars =NULL;
    }
}

static void alias_close(struct SResource *alias) {
    if (alias->u.fString.fChars != NULL) {
        uprv_free(alias->u.fString.fChars);
        alias->u.fString.fChars =NULL;
    }
}

static void intvector_close(struct SResource *intvector) {
    if (intvector->u.fIntVector.fArray != NULL) {
        uprv_free(intvector->u.fIntVector.fArray);
        intvector->u.fIntVector.fArray =NULL;
    }
}

static void int_close(struct SResource *intres) {
    /* Intentionally left blank */
}

static void bin_close(struct SResource *binres) {
    if (binres->u.fBinaryValue.fData != NULL) {
        uprv_free(binres->u.fBinaryValue.fData);
        binres->u.fBinaryValue.fData = NULL;
    }
    if (binres->u.fBinaryValue.fFileName != NULL) {
        uprv_free(binres->u.fBinaryValue.fFileName);
        binres->u.fBinaryValue.fFileName = NULL;
    }
}

void res_close(struct SResource *res) {
    if (res != NULL) {
        switch(res->fType) {
        case URES_STRING:
            string_close(res);
            break;
        case URES_ALIAS:
            alias_close(res);
            break;
        case URES_INT_VECTOR:
            intvector_close(res);
            break;
        case URES_BINARY:
            bin_close(res);
            break;
        case URES_INT:
            int_close(res);
            break;
        case URES_ARRAY:
            array_close(res);
            break;
        case URES_TABLE:
            table_close(res);
            break;
        default:
            /* Shouldn't happen */
            break;
        }

        ustr_deinit(&res->fComment);
        uprv_free(res);
    }
}

void bundle_close(struct SRBRoot *bundle, UErrorCode *status) {
    res_close(bundle->fRoot);
    uprv_free(bundle->fLocale);
    uprv_free(bundle->fKeys);
    uprv_free(bundle->fKeyMap);
    uprv_free(bundle->f16BitUnits);
    uprv_free(bundle);
}

/* Adding Functions */
void table_add(struct SResource *table, struct SResource *res, int linenumber, UErrorCode *status) {
    struct SResource *current = NULL;
    struct SResource *prev    = NULL;
    struct SResTable *list;
    const char *resKeyString;

    if (U_FAILURE(*status)) {
        return;
    }
    if (res == &kNoResource) {
        return;
    }

    /* remember this linenumber to report to the user if there is a duplicate key */
    res->line = linenumber;

    /* here we need to traverse the list */
    list = &(table->u.fTable);
    ++(list->fCount);

    /* is list still empty? */
    if (list->fFirst == NULL) {
        list->fFirst = res;
        res->fNext   = NULL;
        return;
    }

    resKeyString = list->fRoot->fKeys + res->fKey;

    current = list->fFirst;

    while (current != NULL) {
        const char *currentKeyString = list->fRoot->fKeys + current->fKey;
        int diff;
        /*
         * formatVersion 1: compare key strings in native-charset order
         * formatVersion 2 and up: compare key strings in ASCII order
         */
        if (gFormatVersion == 1 || U_CHARSET_FAMILY == U_ASCII_FAMILY) {
            diff = uprv_strcmp(currentKeyString, resKeyString);
        } else {
            diff = uprv_compareInvCharsAsAscii(currentKeyString, resKeyString);
        }
        if (diff < 0) {
            prev    = current;
            current = current->fNext;
        } else if (diff > 0) {
            /* we're either in front of list, or in middle */
            if (prev == NULL) {
                /* front of the list */
                list->fFirst = res;
            } else {
                /* middle of the list */
                prev->fNext = res;
            }

            res->fNext = current;
            return;
        } else {
            /* Key already exists! ERROR! */
            error(linenumber, "duplicate key '%s' in table, first appeared at line %d", currentKeyString, current->line);
            *status = U_UNSUPPORTED_ERROR;
            return;
        }
    }

    /* end of list */
    prev->fNext = res;
    res->fNext  = NULL;
}

void array_add(struct SResource *array, struct SResource *res, UErrorCode *status) {
    if (U_FAILURE(*status)) {
        return;
    }

    if (array->u.fArray.fFirst == NULL) {
        array->u.fArray.fFirst = res;
        array->u.fArray.fLast  = res;
    } else {
        array->u.fArray.fLast->fNext = res;
        array->u.fArray.fLast        = res;
    }

    (array->u.fArray.fCount)++;
}

void intvector_add(struct SResource *intvector, int32_t value, UErrorCode *status) {
    if (U_FAILURE(*status)) {
        return;
    }

    *(intvector->u.fIntVector.fArray + intvector->u.fIntVector.fCount) = value;
    intvector->u.fIntVector.fCount++;
}

/* Misc Functions */

void bundle_setlocale(struct SRBRoot *bundle, UChar *locale, UErrorCode *status) {

    if(U_FAILURE(*status)) {
        return;
    }

    if (bundle->fLocale!=NULL) {
        uprv_free(bundle->fLocale);
    }

    bundle->fLocale= (char*) uprv_malloc(sizeof(char) * (u_strlen(locale)+1));

    if(bundle->fLocale == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }

    /*u_strcpy(bundle->fLocale, locale);*/
    u_UCharsToChars(locale, bundle->fLocale, u_strlen(locale)+1);

}

static const char *
getKeyString(const struct SRBRoot *bundle, int32_t key) {
    if (key < 0) {
        return bundle->fPoolBundleKeys + (key & 0x7fffffff);
    } else {
        return bundle->fKeys + key;
    }
}

const char *
res_getKeyString(const struct SRBRoot *bundle, const struct SResource *res, char temp[8]) {
    if (res->fKey == -1) {
        return NULL;
    }
    return getKeyString(bundle, res->fKey);
}

const char *
bundle_getKeyBytes(struct SRBRoot *bundle, int32_t *pLength) {
    *pLength = bundle->fKeysTop - bundle->fKeysBottom;
    return bundle->fKeys + bundle->fKeysBottom;
}

int32_t
bundle_addKeyBytes(struct SRBRoot *bundle, const char *keyBytes, int32_t length, UErrorCode *status) {
    int32_t keypos;

    if (U_FAILURE(*status)) {
        return -1;
    }
    if (length < 0 || (keyBytes == NULL && length != 0)) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return -1;
    }
    if (length == 0) {
        return bundle->fKeysTop;
    }

    keypos = bundle->fKeysTop;
    bundle->fKeysTop += length;
    if (bundle->fKeysTop >= bundle->fKeysCapacity) {
        /* overflow - resize the keys buffer */
        bundle->fKeysCapacity += KEY_SPACE_SIZE;
        bundle->fKeys = uprv_realloc(bundle->fKeys, bundle->fKeysCapacity);
        if(bundle->fKeys == NULL) {
            *status = U_MEMORY_ALLOCATION_ERROR;
            return -1;
        }
    }

    uprv_memcpy(bundle->fKeys + keypos, keyBytes, length);

    return keypos;
}

int32_t
bundle_addtag(struct SRBRoot *bundle, const char *tag, UErrorCode *status) {
    int32_t keypos;

    if (U_FAILURE(*status)) {
        return -1;
    }

    if (tag == NULL) {
        /* no error: the root table and array items have no keys */
        return -1;
    }

    keypos = bundle_addKeyBytes(bundle, tag, (int32_t)(uprv_strlen(tag) + 1), status);
    if (U_SUCCESS(*status)) {
        ++bundle->fKeysCount;
    }
    return keypos;
}

static int32_t
compareInt32(int32_t lPos, int32_t rPos) {
    /*
     * Compare possibly-negative key offsets. Don't just return lPos - rPos
     * because that is prone to negative-integer underflows.
     */
    if (lPos < rPos) {
        return -1;
    } else if (lPos > rPos) {
        return 1;
    } else {
        return 0;
    }
}

static int32_t U_CALLCONV
compareKeySuffixes(const void *context, const void *l, const void *r) {
    const struct SRBRoot *bundle=(const struct SRBRoot *)context;
    int32_t lPos = ((const KeyMapEntry *)l)->oldpos;
    int32_t rPos = ((const KeyMapEntry *)r)->oldpos;
    const char *lStart = getKeyString(bundle, lPos);
    const char *lLimit = lStart;
    const char *rStart = getKeyString(bundle, rPos);
    const char *rLimit = rStart;
    int32_t diff;
    while (*lLimit != 0) { ++lLimit; }
    while (*rLimit != 0) { ++rLimit; }
    /* compare keys in reverse character order */
    while (lStart < lLimit && rStart < rLimit) {
        diff = (int32_t)(uint8_t)*--lLimit - (int32_t)(uint8_t)*--rLimit;
        if (diff != 0) {
            return diff;
        }
    }
    /* sort equal suffixes by descending key length */
    diff = (int32_t)(rLimit - rStart) - (int32_t)(lLimit - lStart);
    if (diff != 0) {
        return diff;
    }
    /* Sort pool bundle keys first (negative oldpos), and otherwise keys in parsing order. */
    return compareInt32(lPos, rPos);
}

static int32_t U_CALLCONV
compareKeyNewpos(const void *context, const void *l, const void *r) {
    return compareInt32(((const KeyMapEntry *)l)->newpos, ((const KeyMapEntry *)r)->newpos);
}

static int32_t U_CALLCONV
compareKeyOldpos(const void *context, const void *l, const void *r) {
    return compareInt32(((const KeyMapEntry *)l)->oldpos, ((const KeyMapEntry *)r)->oldpos);
}

void
bundle_compactKeys(struct SRBRoot *bundle, UErrorCode *status) {
    KeyMapEntry *map;
    char *keys;
    int32_t i;
    int32_t keysCount = bundle->fPoolBundleKeysCount + bundle->fKeysCount;
    if (U_FAILURE(*status) || bundle->fKeysCount == 0 || bundle->fKeyMap != NULL) {
        return;
    }
    map = (KeyMapEntry *)uprv_malloc(keysCount * sizeof(KeyMapEntry));
    if (map == NULL) {
        *status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    keys = (char *)bundle->fPoolBundleKeys;
    for (i = 0; i < bundle->fPoolBundleKeysCount; ++i) {
        map[i].oldpos =
            (int32_t)(keys - bundle->fPoolBundleKeys) | 0x80000000;  /* negative oldpos */
        map[i].newpos = 0;
        while (*keys != 0) { ++keys; }  /* skip the key */
        ++keys;  /* skip the NUL */
    }
    keys = bundle->fKeys + bundle->fKeysBottom;
    for (; i < keysCount; ++i) {
        map[i].oldpos = (int32_t)(keys - bundle->fKeys);
        map[i].newpos = 0;
        while (*keys != 0) { ++keys; }  /* skip the key */
        ++keys;  /* skip the NUL */
    }
    /* Sort the keys so that each one is immediately followed by all of its suffixes. */
    uprv_sortArray(map, keysCount, (int32_t)sizeof(KeyMapEntry),
                   compareKeySuffixes, bundle, FALSE, status);
    /*
     * Make suffixes point into earlier, longer strings that contain them
     * and mark the old, now unused suffix bytes as deleted.
     */
    if (U_SUCCESS(*status)) {
        keys = bundle->fKeys;
        for (i = 0; i < keysCount;) {
            /*
             * This key is not a suffix of the previous one;
             * keep this one and delete the following ones that are
             * suffixes of this one.
             */
            const char *key;
            const char *keyLimit;
            int32_t j = i + 1;
            map[i].newpos = map[i].oldpos;
            if (j < keysCount && map[j].oldpos < 0) {
                /* Key string from the pool bundle, do not delete. */
                i = j;
                continue;
            }
            key = getKeyString(bundle, map[i].oldpos);
            for (keyLimit = key; *keyLimit != 0; ++keyLimit) {}
            for (; j < keysCount && map[j].oldpos >= 0; ++j) {
                const char *k;
                char *suffix;
                const char *suffixLimit;
                int32_t offset;
                suffix = keys + map[j].oldpos;
                for (suffixLimit = suffix; *suffixLimit != 0; ++suffixLimit) {}
                offset = (int32_t)(keyLimit - key) - (suffixLimit - suffix);
                if (offset < 0) {
                    break;  /* suffix cannot be longer than the original */
                }
                /* Is it a suffix of the earlier, longer key? */
                for (k = keyLimit; suffix < suffixLimit && *--k == *--suffixLimit;) {}
                if (suffix == suffixLimit && *k == *suffixLimit) {
                    map[j].newpos = map[i].oldpos + offset;  /* yes, point to the earlier key */
                    /* mark the suffix as deleted */
                    while (*suffix != 0) { *suffix++ = 1; }
                    *suffix = 1;
                } else {
                    break;  /* not a suffix, restart from here */
                }
            }
            i = j;
        }
        /*
         * Re-sort by newpos, then modify the key characters array in-place
         * to squeeze out unused bytes, and readjust the newpos offsets.
         */
        uprv_sortArray(map, keysCount, (int32_t)sizeof(KeyMapEntry),
                       compareKeyNewpos, NULL, FALSE, status);
        if (U_SUCCESS(*status)) {
            int32_t oldpos, newpos, limit;
            oldpos = newpos = bundle->fKeysBottom;
            limit = bundle->fKeysTop;
            /* skip key offsets that point into the pool bundle rather than this new bundle */
            for (i = 0; i < keysCount && map[i].newpos < 0; ++i) {}
            if (i < keysCount) {
                while (oldpos < limit) {
                    if (keys[oldpos] == 1) {
                        ++oldpos;  /* skip unused bytes */
                    } else {
                        /* adjust the new offsets for keys starting here */
                        while (i < keysCount && map[i].newpos == oldpos) {
                            map[i++].newpos = newpos;
                        }
                        /* move the key characters to their new position */
                        keys[newpos++] = keys[oldpos++];
                    }
                }
                assert(i == keysCount);
            }
            bundle->fKeysTop = newpos;
            /* Re-sort once more, by old offsets for binary searching. */
            uprv_sortArray(map, keysCount, (int32_t)sizeof(KeyMapEntry),
                           compareKeyOldpos, NULL, FALSE, status);
            if (U_SUCCESS(*status)) {
                /* key size reduction by limit - newpos */
                bundle->fKeyMap = map;
                map = NULL;
            }
        }
    }
    uprv_free(map);
}

static int32_t U_CALLCONV
compareStringSuffixes(const void *context, const void *l, const void *r) {
    struct SResource *left = *((struct SResource **)l);
    struct SResource *right = *((struct SResource **)r);
    const UChar *lStart = left->u.fString.fChars;
    const UChar *lLimit = lStart + left->u.fString.fLength;
    const UChar *rStart = right->u.fString.fChars;
    const UChar *rLimit = rStart + right->u.fString.fLength;
    int32_t diff;
    /* compare keys in reverse character order */
    while (lStart < lLimit && rStart < rLimit) {
        diff = (int32_t)*--lLimit - (int32_t)*--rLimit;
        if (diff != 0) {
            return diff;
        }
    }
    /* sort equal suffixes by descending string length */
    return right->u.fString.fLength - left->u.fString.fLength;
}

static int32_t U_CALLCONV
compareStringLengths(const void *context, const void *l, const void *r) {
    struct SResource *left = *((struct SResource **)l);
    struct SResource *right = *((struct SResource **)r);
    int32_t diff;
    /* Make "is suffix of another string" compare greater than a non-suffix. */
    diff = (int)(left->u.fString.fSame != NULL) - (int)(right->u.fString.fSame != NULL);
    if (diff != 0) {
        return diff;
    }
    /* sort by ascending string length */
    return left->u.fString.fLength - right->u.fString.fLength;
}

static int32_t
string_writeUTF16v2(struct SRBRoot *bundle, struct SResource *res, int32_t utf16Length) {
    int32_t length = res->u.fString.fLength;
    res->fRes = URES_MAKE_RESOURCE(URES_STRING_V2, utf16Length);
    res->fWritten = TRUE;
    switch(res->u.fString.fNumCharsForLength) {
    case 0:
        break;
    case 1:
        bundle->f16BitUnits[utf16Length++] = (uint16_t)(0xdc00 + length);
        break;
    case 2:
        bundle->f16BitUnits[utf16Length] = (uint16_t)(0xdfef + (length >> 16));
        bundle->f16BitUnits[utf16Length + 1] = (uint16_t)length;
        utf16Length += 2;
        break;
    case 3:
        bundle->f16BitUnits[utf16Length] = 0xdfff;
        bundle->f16BitUnits[utf16Length + 1] = (uint16_t)(length >> 16);
        bundle->f16BitUnits[utf16Length + 2] = (uint16_t)length;
        utf16Length += 3;
        break;
    default:
        break;  /* will not occur */
    }
    u_memcpy(bundle->f16BitUnits + utf16Length, res->u.fString.fChars, length + 1);
    return utf16Length + length + 1;
}

static void
bundle_compactStrings(struct SRBRoot *bundle, UErrorCode *status) {
    UHashtable *stringSet;
    if (gFormatVersion > 1) {
        stringSet = uhash_open(string_hash, string_comp, string_comp, status);
        res_preflightStrings(bundle, bundle->fRoot, stringSet, status);
    } else {
        stringSet = NULL;
    }
    if (U_FAILURE(*status)) {
        uhash_close(stringSet);
        return;
    }
    switch(bundle->fStringsForm) {
    case STRINGS_UTF16_V2:
        if (bundle->f16BitUnitsLength > 0) {
            struct SResource **array;
            int32_t count = uhash_count(stringSet);
            int32_t i, pos;
            /*
             * Allocate enough space for the initial NUL and the UTF-16 v2 strings,
             * and some extra for URES_TABLE16 and URES_ARRAY16 values.
             * Round down to an even number.
             */
            int32_t utf16Length = (bundle->f16BitUnitsLength + 20000) & ~1;
            bundle->f16BitUnits = (UChar *)uprv_malloc(utf16Length * U_SIZEOF_UCHAR);
            array = (struct SResource **)uprv_malloc(count * sizeof(struct SResource **));
            if (bundle->f16BitUnits == NULL || array == NULL) {
                uprv_free(bundle->f16BitUnits);
                bundle->f16BitUnits = NULL;
                uprv_free(array);
                uhash_close(stringSet);
                *status = U_MEMORY_ALLOCATION_ERROR;
                return;
            }
            bundle->f16BitUnitsCapacity = utf16Length;
            /* insert the initial NUL */
            bundle->f16BitUnits[0] = 0;
            utf16Length = 1;
            ++bundle->f16BitUnitsLength;
            for (pos = -1, i = 0; i < count; ++i) {
                array[i] = (struct SResource *)uhash_nextElement(stringSet, &pos)->key.pointer;
            }
            /* Sort the strings so that each one is immediately followed by all of its suffixes. */
            uprv_sortArray(array, count, (int32_t)sizeof(struct SResource **),
                           compareStringSuffixes, NULL, FALSE, status);
            /*
             * Make suffixes point into earlier, longer strings that contain them.
             * Temporarily use fSame and fSuffixOffset for suffix strings to
             * refer to the remaining ones.
             */
            if (U_SUCCESS(*status)) {
                for (i = 0; i < count;) {
                    /*
                     * This string is not a suffix of the previous one;
                     * write this one and subsume the following ones that are
                     * suffixes of this one.
                     */
                    struct SResource *res = array[i];
                    const UChar *strLimit = res->u.fString.fChars + res->u.fString.fLength;
                    int32_t j;
                    for (j = i + 1; j < count; ++j) {
                        struct SResource *suffixRes = array[j];
                        const UChar *s;
                        const UChar *suffix = suffixRes->u.fString.fChars;
                        const UChar *suffixLimit = suffix + suffixRes->u.fString.fLength;
                        int32_t offset = res->u.fString.fLength - suffixRes->u.fString.fLength;
                        if (offset < 0) {
                            break;  /* suffix cannot be longer than the original */
                        }
                        /* Is it a suffix of the earlier, longer key? */
                        for (s = strLimit; suffix < suffixLimit && *--s == *--suffixLimit;) {}
                        if (suffix == suffixLimit && *s == *suffixLimit) {
                            if (suffixRes->u.fString.fNumCharsForLength == 0) {
                                /* yes, point to the earlier string */
                                suffixRes->u.fString.fSame = res;
                                suffixRes->u.fString.fSuffixOffset = offset;
                            } else {
                                /* write the suffix by itself if we need explicit length */
                            }
                        } else {
                            break;  /* not a suffix, restart from here */
                        }
                    }
                    i = j;
                }
            }
            /*
             * Re-sort the strings by ascending length (except suffixes last)
             * to optimize for URES_TABLE16 and URES_ARRAY16:
             * Keep as many as possible within reach of 16-bit offsets.
             */
            uprv_sortArray(array, count, (int32_t)sizeof(struct SResource **),
                           compareStringLengths, NULL, FALSE, status);
            if (U_SUCCESS(*status)) {
                /* Write the non-suffix strings. */
                for (i = 0; i < count && array[i]->u.fString.fSame == NULL; ++i) {
                    utf16Length = string_writeUTF16v2(bundle, array[i], utf16Length);
                }
                /* Write the suffix strings. Make each point to the real string. */
                for (; i < count; ++i) {
                    struct SResource *res = array[i];
                    struct SResource *same = res->u.fString.fSame;
                    res->fRes = same->fRes + same->u.fString.fNumCharsForLength + res->u.fString.fSuffixOffset;
                    res->u.fString.fSame = NULL;
                    res->fWritten = TRUE;
                }
            }
            assert(utf16Length <= bundle->f16BitUnitsLength);
            bundle->f16BitUnitsLength = utf16Length;
            uprv_free(array);
        }
        break;
    default:
        break;
    }
    uhash_close(stringSet);
}
