/*
* 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 "include/core/SkDataTable.h"
#include "include/core/SkRefCnt.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkMalloc.h"
#include "include/private/base/SkOnce.h"
#include <cstring>
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 = nullptr;
fFreeProc = nullptr;
fFreeProcContext = nullptr;
}
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;
}
}
///////////////////////////////////////////////////////////////////////////////
sk_sp<SkDataTable> SkDataTable::MakeEmpty() {
static SkDataTable* singleton;
static SkOnce once;
once([]{ singleton = new SkDataTable(); });
return sk_ref_sp(singleton);
}
sk_sp<SkDataTable> SkDataTable::MakeCopyArrays(const void * const * ptrs,
const size_t sizes[], int count) {
if (count <= 0) {
return SkDataTable::MakeEmpty();
}
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 sk_sp<SkDataTable>(new SkDataTable(dir, count, malloc_freeproc, buffer));
}
sk_sp<SkDataTable> SkDataTable::MakeCopyArray(const void * array, size_t elemSize, int count) {
if (count <= 0) {
return SkDataTable::MakeEmpty();
}
size_t bufferSize = elemSize * count;
void * buffer = sk_malloc_throw(bufferSize);
memcpy(buffer, array, bufferSize);
return sk_sp<SkDataTable>(new SkDataTable(buffer, elemSize, count, malloc_freeproc, buffer));
}
sk_sp<SkDataTable> SkDataTable::MakeArrayProc(const void * array, size_t elemSize, int count,
FreeProc proc, void * ctx) {
if (count <= 0) {
return SkDataTable::MakeEmpty();
}
return sk_sp<SkDataTable>(new SkDataTable(array, elemSize, count, proc, ctx));
}
Messung V0.5 C=91 H=95 G=92
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland