/*
 * 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"

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;
}
