Line data Source code
1 : /*
2 : * Copyright 2013 Google Inc.
3 : *
4 : * Use of this source code is governed by a BSD-style license that can be
5 : * found in the LICENSE file.
6 : */
7 :
8 : #include "SkData.h"
9 : #include "SkDataTable.h"
10 : #include "SkOnce.h"
11 :
12 0 : static void malloc_freeproc(void* context) {
13 0 : sk_free(context);
14 0 : }
15 :
16 : // Makes empty table
17 0 : SkDataTable::SkDataTable() {
18 0 : fCount = 0;
19 0 : fElemSize = 0; // 0 signals that we use fDir instead of fElems
20 0 : fU.fDir = nullptr;
21 0 : fFreeProc = nullptr;
22 0 : fFreeProcContext = nullptr;
23 0 : }
24 :
25 0 : SkDataTable::SkDataTable(const void* array, size_t elemSize, int count,
26 0 : FreeProc proc, void* context) {
27 0 : SkASSERT(count > 0);
28 :
29 0 : fCount = count;
30 0 : fElemSize = elemSize; // non-zero signals we use fElems instead of fDir
31 0 : fU.fElems = (const char*)array;
32 0 : fFreeProc = proc;
33 0 : fFreeProcContext = context;
34 0 : }
35 :
36 0 : SkDataTable::SkDataTable(const Dir* dir, int count, FreeProc proc, void* ctx) {
37 0 : SkASSERT(count > 0);
38 :
39 0 : fCount = count;
40 0 : fElemSize = 0; // 0 signals that we use fDir instead of fElems
41 0 : fU.fDir = dir;
42 0 : fFreeProc = proc;
43 0 : fFreeProcContext = ctx;
44 0 : }
45 :
46 0 : SkDataTable::~SkDataTable() {
47 0 : if (fFreeProc) {
48 0 : fFreeProc(fFreeProcContext);
49 : }
50 0 : }
51 :
52 0 : size_t SkDataTable::atSize(int index) const {
53 0 : SkASSERT((unsigned)index < (unsigned)fCount);
54 :
55 0 : if (fElemSize) {
56 0 : return fElemSize;
57 : } else {
58 0 : return fU.fDir[index].fSize;
59 : }
60 : }
61 :
62 0 : const void* SkDataTable::at(int index, size_t* size) const {
63 0 : SkASSERT((unsigned)index < (unsigned)fCount);
64 :
65 0 : if (fElemSize) {
66 0 : if (size) {
67 0 : *size = fElemSize;
68 : }
69 0 : return fU.fElems + index * fElemSize;
70 : } else {
71 0 : if (size) {
72 0 : *size = fU.fDir[index].fSize;
73 : }
74 0 : return fU.fDir[index].fPtr;
75 : }
76 : }
77 :
78 : ///////////////////////////////////////////////////////////////////////////////
79 :
80 0 : sk_sp<SkDataTable> SkDataTable::MakeEmpty() {
81 : static SkDataTable* singleton;
82 : static SkOnce once;
83 0 : once([]{ singleton = new SkDataTable(); });
84 0 : return sk_ref_sp(singleton);
85 : }
86 :
87 0 : sk_sp<SkDataTable> SkDataTable::MakeCopyArrays(const void * const * ptrs,
88 : const size_t sizes[], int count) {
89 0 : if (count <= 0) {
90 0 : return SkDataTable::MakeEmpty();
91 : }
92 :
93 0 : size_t dataSize = 0;
94 0 : for (int i = 0; i < count; ++i) {
95 0 : dataSize += sizes[i];
96 : }
97 :
98 0 : size_t bufferSize = count * sizeof(Dir) + dataSize;
99 0 : void* buffer = sk_malloc_throw(bufferSize);
100 :
101 0 : Dir* dir = (Dir*)buffer;
102 0 : char* elem = (char*)(dir + count);
103 0 : for (int i = 0; i < count; ++i) {
104 0 : dir[i].fPtr = elem;
105 0 : dir[i].fSize = sizes[i];
106 0 : memcpy(elem, ptrs[i], sizes[i]);
107 0 : elem += sizes[i];
108 : }
109 :
110 0 : return sk_sp<SkDataTable>(new SkDataTable(dir, count, malloc_freeproc, buffer));
111 : }
112 :
113 0 : sk_sp<SkDataTable> SkDataTable::MakeCopyArray(const void* array, size_t elemSize, int count) {
114 0 : if (count <= 0) {
115 0 : return SkDataTable::MakeEmpty();
116 : }
117 :
118 0 : size_t bufferSize = elemSize * count;
119 0 : void* buffer = sk_malloc_throw(bufferSize);
120 0 : memcpy(buffer, array, bufferSize);
121 :
122 0 : return sk_sp<SkDataTable>(new SkDataTable(buffer, elemSize, count, malloc_freeproc, buffer));
123 : }
124 :
125 0 : sk_sp<SkDataTable> SkDataTable::MakeArrayProc(const void* array, size_t elemSize, int count,
126 : FreeProc proc, void* ctx) {
127 0 : if (count <= 0) {
128 0 : return SkDataTable::MakeEmpty();
129 : }
130 0 : return sk_sp<SkDataTable>(new SkDataTable(array, elemSize, count, proc, ctx));
131 : }
|