/*
 * 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 "../private/SkChunkAlloc.h"
#include "../private/SkTDArray.h"
#include "SkData.h"
#include "SkString.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 SkRefCnt {
public:
    /**
     *  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 sk_sp<SkDataTable> MakeEmpty();

    /**
     *  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 sk_sp<SkDataTable> MakeCopyArrays(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 sk_sp<SkDataTable> MakeCopyArray(const void* array, size_t elemSize, int count);

    static sk_sp<SkDataTable> MakeArrayProc(const void* array, size_t elemSize, int count,
                                            FreeProc proc, void* context);

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 SkRefCnt 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.
     */
    sk_sp<SkDataTable> detachDataTable();

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

#endif
