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

#include "SkData.h"
#include "SkDataTable.h"

SK_DEFINE_INST_COUNT(SkDataTable)

static void malloc_freeproc(void* context) {
    sk_free(context);
}

// Makes empty table
SkDataTable::SkDataTable() {
    fCount = 0;
    fElemSize = 0;   // 0 signals that we use fDir instead of fElems
    fU.fDir = NULL;
    fFreeProc = NULL;
    fFreeProcContext = NULL;
}

SkDataTable::SkDataTable(const void* array, size_t elemSize, int count,
                         FreeProc proc, void* context) {
    SkASSERT(count > 0);

    fCount = count;
    fElemSize = elemSize;   // non-zero signals we use fElems instead of fDir
    fU.fElems = (const char*)array;
    fFreeProc = proc;
    fFreeProcContext = context;
}

SkDataTable::SkDataTable(const Dir* dir, int count, FreeProc proc, void* ctx) {
    SkASSERT(count > 0);

    fCount = count;
    fElemSize = 0;  // 0 signals that we use fDir instead of fElems
    fU.fDir = dir;
    fFreeProc = proc;
    fFreeProcContext = ctx;
}

SkDataTable::~SkDataTable() {
    if (fFreeProc) {
        fFreeProc(fFreeProcContext);
    }
}

size_t SkDataTable::atSize(int index) const {
    SkASSERT((unsigned)index < (unsigned)fCount);

    if (fElemSize) {
        return fElemSize;
    } else {
        return fU.fDir[index].fSize;
    }
}

const void* SkDataTable::at(int index, size_t* size) const {
    SkASSERT((unsigned)index < (unsigned)fCount);

    if (fElemSize) {
        if (size) {
            *size = fElemSize;
        }
        return fU.fElems + index * fElemSize;
    } else {
        if (size) {
            *size = fU.fDir[index].fSize;
        }
        return fU.fDir[index].fPtr;
    }
}

///////////////////////////////////////////////////////////////////////////////

SkDataTable* SkDataTable::NewEmpty() {
    static SkDataTable* gEmpty;
    if (NULL == gEmpty) {
        gEmpty = SkNEW(SkDataTable);
    }
    gEmpty->ref();
    return gEmpty;
}

SkDataTable* SkDataTable::NewCopyArrays(const void * const * ptrs,
                                        const size_t sizes[], int count) {
    if (count <= 0) {
        return SkDataTable::NewEmpty();
    }

    size_t dataSize = 0;
    for (int i = 0; i < count; ++i) {
        dataSize += sizes[i];
    }

    size_t bufferSize = count * sizeof(Dir) + dataSize;
    void* buffer = sk_malloc_throw(bufferSize);

    Dir* dir = (Dir*)buffer;
    char* elem = (char*)(dir + count);
    for (int i = 0; i < count; ++i) {
        dir[i].fPtr = elem;
        dir[i].fSize = sizes[i];
        memcpy(elem, ptrs[i], sizes[i]);
        elem += sizes[i];
    }

    return SkNEW_ARGS(SkDataTable, (dir, count, malloc_freeproc, buffer));
}

SkDataTable* SkDataTable::NewCopyArray(const void* array, size_t elemSize,
                                       int count) {
    if (count <= 0) {
        return SkDataTable::NewEmpty();
    }

    size_t bufferSize = elemSize * count;
    void* buffer = sk_malloc_throw(bufferSize);
    memcpy(buffer, array, bufferSize);

    return SkNEW_ARGS(SkDataTable,
                      (buffer, elemSize, count, malloc_freeproc, buffer));
}

SkDataTable* SkDataTable::NewArrayProc(const void* array, size_t elemSize,
                                       int count, FreeProc proc, void* ctx) {
    if (count <= 0) {
        return SkDataTable::NewEmpty();
    }
    return SkNEW_ARGS(SkDataTable, (array, elemSize, count, proc, ctx));
}

///////////////////////////////////////////////////////////////////////////////

static void chunkalloc_freeproc(void* context) {
    SkDELETE((SkChunkAlloc*)context);
}

SkDataTableBuilder::SkDataTableBuilder(size_t minChunkSize)
    : fHeap(NULL)
    , fMinChunkSize(minChunkSize) {}

SkDataTableBuilder::~SkDataTableBuilder() { this->reset(); }

void SkDataTableBuilder::reset(size_t minChunkSize) {
    fMinChunkSize = minChunkSize;
    fDir.reset();
    if (fHeap) {
        SkDELETE(fHeap);
        fHeap = NULL;
    }
}

void SkDataTableBuilder::append(const void* src, size_t size) {
    if (NULL == fHeap) {
        fHeap = SkNEW_ARGS(SkChunkAlloc, (fMinChunkSize));
    }

    void* dst = fHeap->alloc(size, SkChunkAlloc::kThrow_AllocFailType);
    memcpy(dst, src, size);

    SkDataTable::Dir* dir = fDir.append();
    dir->fPtr = dst;
    dir->fSize = size;
}

SkDataTable* SkDataTableBuilder::detachDataTable() {
    const int count = fDir.count();
    if (0 == count) {
        return SkDataTable::NewEmpty();
    }

    // Copy the dir into the heap;
    void* dir = fHeap->alloc(count * sizeof(SkDataTable::Dir),
                             SkChunkAlloc::kThrow_AllocFailType);
    memcpy(dir, fDir.begin(), count * sizeof(SkDataTable::Dir));

    SkDataTable* table = SkNEW_ARGS(SkDataTable,
                                    ((SkDataTable::Dir*)dir, count,
                                     chunkalloc_freeproc, fHeap));
    // we have to detach our fHeap, since we are giving that to the table
    fHeap = NULL;
    fDir.reset();
    return table;
}
