//
// Copyright 2006 The Android Open Source Project
//
// Build resource files from raw assets.
//

#ifndef STRING_POOL_H
#define STRING_POOL_H

#include "Main.h"
#include "AaptAssets.h"

#include <androidfw/ResourceTypes.h>
#include <utils/String16.h>
#include <utils/TypeHelpers.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>

using namespace android;

#define PRINT_STRING_METRICS 0

#if __cplusplus >= 201103L
void strcpy16_htod(char16_t* dst, const char16_t* src);
#endif
void strcpy16_htod(uint16_t* dst, const char16_t* src);

void printStringPool(const ResStringPool* pool);

/**
 * The StringPool class is used as an intermediate representation for
 * generating the string pool resource data structure that can be parsed with
 * ResStringPool in include/utils/ResourceTypes.h.
 */
class StringPool
{
public:
    struct entry {
        entry() : offset(0) { }
        entry(const String16& _value) : value(_value), offset(0), hasStyles(false) { }
        entry(const entry& o) : value(o.value), offset(o.offset),
                hasStyles(o.hasStyles), indices(o.indices),
                configTypeName(o.configTypeName), configs(o.configs) { }

        String16 value;
        size_t offset;
        bool hasStyles;
        Vector<size_t> indices;
        String8 configTypeName;
        Vector<ResTable_config> configs;

        String8 makeConfigsString() const;

        int compare(const entry& o) const;

        inline bool operator<(const entry& o) const { return compare(o) < 0; }
        inline bool operator<=(const entry& o) const { return compare(o) <= 0; }
        inline bool operator==(const entry& o) const { return compare(o) == 0; }
        inline bool operator!=(const entry& o) const { return compare(o) != 0; }
        inline bool operator>=(const entry& o) const { return compare(o) >= 0; }
        inline bool operator>(const entry& o) const { return compare(o) > 0; }
    };

    struct entry_style_span {
        String16 name;
        ResStringPool_span span;
    };

    struct entry_style {
        entry_style() : offset(0) { }

        entry_style(const entry_style& o) : offset(o.offset), spans(o.spans) { }

        size_t offset;
        Vector<entry_style_span> spans;
    };

    /**
     * If 'utf8' is true, strings will be encoded with UTF-8 instead of
     * left in Java's native UTF-16.
     */
    explicit StringPool(bool utf8 = false);

    /**
     * Add a new string to the pool.  If mergeDuplicates is true, thenif
     * the string already exists the existing entry for it will be used;
     * otherwise, or if the value doesn't already exist, a new entry is
     * created.
     *
     * Returns the index in the entry array of the new string entry.
     */
    ssize_t add(const String16& value, bool mergeDuplicates = false,
            const String8* configTypeName = NULL, const ResTable_config* config = NULL);

    ssize_t add(const String16& value, const Vector<entry_style_span>& spans,
            const String8* configTypeName = NULL, const ResTable_config* config = NULL);

    status_t addStyleSpan(size_t idx, const String16& name,
                          uint32_t start, uint32_t end);
    status_t addStyleSpans(size_t idx, const Vector<entry_style_span>& spans);
    status_t addStyleSpan(size_t idx, const entry_style_span& span);

    // Sort the contents of the string block by the configuration associated
    // with each item.  After doing this you can use mapOriginalPosToNewPos()
    // to find out the new position given the position originally returned by
    // add().
    void sortByConfig();

    // For use after sortByConfig() to map from the original position of
    // a string to its new sorted position.
    size_t mapOriginalPosToNewPos(size_t originalPos) const {
        return mOriginalPosToNewPos.itemAt(originalPos);
    }

    sp<AaptFile> createStringBlock();

    status_t writeStringBlock(const sp<AaptFile>& pool);

    /**
     * Find out an offset in the pool for a particular string.  If the string
     * pool is sorted, this can not be called until after createStringBlock()
     * or writeStringBlock() has been called
     * (which determines the offsets).  In the case of a string that appears
     * multiple times in the pool, the first offset will be returned.  Returns
     * -1 if the string does not exist.
     */
    ssize_t offsetForString(const String16& val) const;

    /**
     * Find all of the offsets in the pool for a particular string.  If the
     * string pool is sorted, this can not be called until after
     * createStringBlock() or writeStringBlock() has been called
     * (which determines the offsets).  Returns NULL if the string does not exist.
     */
    const Vector<size_t>* offsetsForString(const String16& val) const;

private:
    class ConfigSorter
    {
    public:
        explicit ConfigSorter(const StringPool&);
        bool operator()(size_t l, size_t r);
    private:
        const StringPool& pool;
    };

    const bool                              mUTF8;

    // The following data structures represent the actual structures
    // that will be generated for the final string pool.

    // Raw array of unique strings, in some arbitrary order.  This is the
    // actual strings that appear in the final string pool, in the order
    // that they will be written.
    Vector<entry>                           mEntries;
    // Array of indices into mEntries, in the order they were
    // added to the pool.  This can be different than mEntries
    // if the same string was added multiple times (it will appear
    // once in mEntries, with multiple occurrences in this array).
    // This is the lookup array that will be written for finding
    // the string for each offset/position in the string pool.
    Vector<size_t>                          mEntryArray;
    // Optional style span information associated with each index of
    // mEntryArray.
    Vector<entry_style>                     mEntryStyleArray;

    // The following data structures are used for book-keeping as the
    // string pool is constructed.

    // Unique set of all the strings added to the pool, mapped to
    // the first index of mEntryArray where the value was added.
    DefaultKeyedVector<String16, ssize_t>   mValues;
    // This array maps from the original position a string was placed at
    // in mEntryArray to its new position after being sorted with sortByConfig().
    Vector<size_t>                          mOriginalPosToNewPos;
};

// The entry types are trivially movable because all fields they contain, including
// the vectors and strings, are trivially movable.
namespace android {
    ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry);
    ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry_style_span);
    ANDROID_TRIVIAL_MOVE_TRAIT(StringPool::entry_style);
};

#endif

