/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkDataTable_DEFINED
#define SkDataTable_DEFINED

#include "SkChunkAlloc.h"
#include "SkData.h"
#include "SkFlattenable.h"
#include "SkString.h"
#include "SkTDArray.h"

/**
 *  Like SkData, SkDataTable holds an immutable data buffer. The data buffer is
 *  organized into a table of entries, each with a length, so the entries are
 *  not required to all be the same size.
 */
class SK_API SkDataTable : public SkFlattenable {
public:
    SK_DECLARE_INST_COUNT(SkDataTable)

    /**
     *  Returns true if the table is empty (i.e. has no entries).
     */
    bool isEmpty() const { return 0 == fCount; }

    /**
     *  Return the number of entries in the table. 0 for an empty table
     */
    int count() const { return fCount; }

    /**
     *  Return the size of the index'th entry in the table. The caller must
     *  ensure that index is valid for this table.
     */
    size_t atSize(int index) const;

    /**
     *  Return a pointer to the data of the index'th entry in the table.
     *  The caller must ensure that index is valid for this table.
     *
     *  @param size If non-null, this returns the byte size of this entry. This
     *              will be the same value that atSize(index) would return.
     */
    const void* at(int index, size_t* size = NULL) const;

    template <typename T>
    const T* atT(int index, size_t* size = NULL) const {
        return reinterpret_cast<const T*>(this->at(index, size));
    }

    /**
     *  Returns the index'th entry as a c-string, and assumes that the trailing
     *  null byte had been copied into the table as well.
     */
    const char* atStr(int index) const {
        size_t size;
        const char* str = this->atT<const char>(index, &size);
        SkASSERT(strlen(str) + 1 == size);
        return str;
    }

    typedef void (*FreeProc)(void* context);

    static SkDataTable* NewEmpty();

    /**
     *  Return a new DataTable that contains a copy of the data stored in each
     *  "array".
     *
     *  @param ptrs array of points to each element to be copied into the table.
     *  @param sizes array of byte-lengths for each entry in the corresponding
     *               ptrs[] array.
     *  @param count the number of array elements in ptrs[] and sizes[] to copy.
     */
    static SkDataTable* NewCopyArrays(const void * const * ptrs,
                                      const size_t sizes[], int count);

    /**
     *  Return a new table that contains a copy of the data in array.
     *
     *  @param array contiguous array of data for all elements to be copied.
     *  @param elemSize byte-length for a given element.
     *  @param count the number of entries to be copied out of array. The number
     *               of bytes that will be copied is count * elemSize.
     */
    static SkDataTable* NewCopyArray(const void* array, size_t elemSize,
                                     int count);

    static SkDataTable* NewArrayProc(const void* array, size_t elemSize,
                                     int count, FreeProc proc, void* context);

    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDataTable)

protected:
    SkDataTable(SkFlattenableReadBuffer&);
    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;

private:
    struct Dir {
        const void* fPtr;
        uintptr_t   fSize;
    };

    int         fCount;
    size_t      fElemSize;
    union {
        const Dir*  fDir;
        const char* fElems;
    } fU;

    FreeProc    fFreeProc;
    void*       fFreeProcContext;

    SkDataTable();
    SkDataTable(const void* array, size_t elemSize, int count,
                FreeProc, void* context);
    SkDataTable(const Dir*, int count, FreeProc, void* context);
    virtual ~SkDataTable();

    friend class SkDataTableBuilder;    // access to Dir

    typedef SkFlattenable INHERITED;
};

/**
 *  Helper class that allows for incrementally building up the data needed to
 *  create a SkDataTable.
 */
class SK_API SkDataTableBuilder : SkNoncopyable {
public:
    SkDataTableBuilder(size_t minChunkSize);
    ~SkDataTableBuilder();

    int  count() const { return fDir.count(); }
    size_t minChunkSize() const { return fMinChunkSize; }

    /**
     *  Forget any previously appended entries, setting count() back to 0.
     */
    void reset(size_t minChunkSize);
    void reset() {
        this->reset(fMinChunkSize);
    }

    /**
     *  Copy size-bytes from data, and append it to the growing SkDataTable.
     */
    void append(const void* data, size_t size);

    /**
     *  Helper version of append() passes strlen() + 1 for the size,
     *  so the trailing-zero will be copied as well.
     */
    void appendStr(const char str[]) {
        this->append(str, strlen(str) + 1);
    }

    /**
     *  Helper version of append() passes string.size() + 1 for the size,
     *  so the trailing-zero will be copied as well.
     */
    void appendString(const SkString& string) {
        this->append(string.c_str(), string.size() + 1);
    }

    /**
     *  Return an SkDataTable from the accumulated entries that were added by
     *  calls to append(). This call also clears any accumluated entries from
     *  this builder, so its count() will be 0 after this call.
     */
    SkDataTable* detachDataTable();

private:
    SkTDArray<SkDataTable::Dir> fDir;
    SkChunkAlloc*               fHeap;
    size_t                      fMinChunkSize;
};

#endif
