Line data Source code
1 : /*
2 : * Copyright 2006 The Android Open Source Project
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 :
9 : #include "SkMetaData.h"
10 :
11 : #include "SkMalloc.h"
12 : #include "SkRefCnt.h"
13 :
14 : struct PtrPair {
15 : void* fPtr;
16 : SkMetaData::PtrProc fProc;
17 : };
18 :
19 0 : void* SkMetaData::RefCntProc(void* ptr, bool doRef) {
20 0 : SkASSERT(ptr);
21 0 : SkRefCnt* refcnt = reinterpret_cast<SkRefCnt*>(ptr);
22 :
23 0 : if (doRef) {
24 0 : refcnt->ref();
25 : } else {
26 0 : refcnt->unref();
27 : }
28 0 : return ptr;
29 : }
30 :
31 0 : SkMetaData::SkMetaData() : fRec(nullptr)
32 : {
33 0 : }
34 :
35 0 : SkMetaData::SkMetaData(const SkMetaData& src) : fRec(nullptr)
36 : {
37 0 : *this = src;
38 0 : }
39 :
40 0 : SkMetaData::~SkMetaData()
41 : {
42 0 : this->reset();
43 0 : }
44 :
45 0 : void SkMetaData::reset()
46 : {
47 0 : Rec* rec = fRec;
48 0 : while (rec) {
49 0 : if (kPtr_Type == rec->fType) {
50 0 : PtrPair* pair = (PtrPair*)rec->data();
51 0 : if (pair->fProc && pair->fPtr) {
52 0 : pair->fPtr = pair->fProc(pair->fPtr, false);
53 : }
54 : }
55 0 : Rec* next = rec->fNext;
56 0 : Rec::Free(rec);
57 0 : rec = next;
58 : }
59 0 : fRec = nullptr;
60 0 : }
61 :
62 0 : SkMetaData& SkMetaData::operator=(const SkMetaData& src)
63 : {
64 0 : this->reset();
65 :
66 0 : const Rec* rec = src.fRec;
67 0 : while (rec)
68 : {
69 0 : this->set(rec->name(), rec->data(), rec->fDataLen, (Type)rec->fType, rec->fDataCount);
70 0 : rec = rec->fNext;
71 : }
72 0 : return *this;
73 : }
74 :
75 0 : void SkMetaData::setS32(const char name[], int32_t value)
76 : {
77 0 : (void)this->set(name, &value, sizeof(int32_t), kS32_Type, 1);
78 0 : }
79 :
80 0 : void SkMetaData::setScalar(const char name[], SkScalar value)
81 : {
82 0 : (void)this->set(name, &value, sizeof(SkScalar), kScalar_Type, 1);
83 0 : }
84 :
85 0 : SkScalar* SkMetaData::setScalars(const char name[], int count, const SkScalar values[])
86 : {
87 0 : SkASSERT(count > 0);
88 0 : if (count > 0)
89 0 : return (SkScalar*)this->set(name, values, sizeof(SkScalar), kScalar_Type, count);
90 0 : return nullptr;
91 : }
92 :
93 0 : void SkMetaData::setString(const char name[], const char value[])
94 : {
95 0 : (void)this->set(name, value, sizeof(char), kString_Type, SkToInt(strlen(value) + 1));
96 0 : }
97 :
98 0 : void SkMetaData::setPtr(const char name[], void* ptr, PtrProc proc) {
99 0 : PtrPair pair = { ptr, proc };
100 0 : (void)this->set(name, &pair, sizeof(PtrPair), kPtr_Type, 1);
101 0 : }
102 :
103 0 : void SkMetaData::setBool(const char name[], bool value)
104 : {
105 0 : (void)this->set(name, &value, sizeof(bool), kBool_Type, 1);
106 0 : }
107 :
108 0 : void SkMetaData::setData(const char name[], const void* data, size_t byteCount) {
109 0 : (void)this->set(name, data, sizeof(char), kData_Type, SkToInt(byteCount));
110 0 : }
111 :
112 0 : void* SkMetaData::set(const char name[], const void* data, size_t dataSize, Type type, int count)
113 : {
114 0 : SkASSERT(name);
115 0 : SkASSERT(dataSize);
116 0 : SkASSERT(count > 0);
117 :
118 0 : (void)this->remove(name, type);
119 :
120 0 : size_t len = strlen(name);
121 0 : Rec* rec = Rec::Alloc(sizeof(Rec) + dataSize * count + len + 1);
122 :
123 : #ifndef SK_DEBUG
124 : rec->fType = SkToU8(type);
125 : #else
126 0 : rec->fType = type;
127 : #endif
128 0 : rec->fDataLen = SkToU8(dataSize);
129 0 : rec->fDataCount = SkToU16(count);
130 0 : if (data)
131 0 : memcpy(rec->data(), data, dataSize * count);
132 0 : memcpy(rec->name(), name, len + 1);
133 :
134 0 : if (kPtr_Type == type) {
135 0 : PtrPair* pair = (PtrPair*)rec->data();
136 0 : if (pair->fProc && pair->fPtr) {
137 0 : pair->fPtr = pair->fProc(pair->fPtr, true);
138 : }
139 : }
140 :
141 0 : rec->fNext = fRec;
142 0 : fRec = rec;
143 0 : return rec->data();
144 : }
145 :
146 0 : bool SkMetaData::findS32(const char name[], int32_t* value) const
147 : {
148 0 : const Rec* rec = this->find(name, kS32_Type);
149 0 : if (rec)
150 : {
151 0 : SkASSERT(rec->fDataCount == 1);
152 0 : if (value)
153 0 : *value = *(const int32_t*)rec->data();
154 0 : return true;
155 : }
156 0 : return false;
157 : }
158 :
159 0 : bool SkMetaData::findScalar(const char name[], SkScalar* value) const
160 : {
161 0 : const Rec* rec = this->find(name, kScalar_Type);
162 0 : if (rec)
163 : {
164 0 : SkASSERT(rec->fDataCount == 1);
165 0 : if (value)
166 0 : *value = *(const SkScalar*)rec->data();
167 0 : return true;
168 : }
169 0 : return false;
170 : }
171 :
172 0 : const SkScalar* SkMetaData::findScalars(const char name[], int* count, SkScalar values[]) const
173 : {
174 0 : const Rec* rec = this->find(name, kScalar_Type);
175 0 : if (rec)
176 : {
177 0 : if (count)
178 0 : *count = rec->fDataCount;
179 0 : if (values)
180 0 : memcpy(values, rec->data(), rec->fDataCount * rec->fDataLen);
181 0 : return (const SkScalar*)rec->data();
182 : }
183 0 : return nullptr;
184 : }
185 :
186 0 : bool SkMetaData::findPtr(const char name[], void** ptr, PtrProc* proc) const {
187 0 : const Rec* rec = this->find(name, kPtr_Type);
188 0 : if (rec) {
189 0 : SkASSERT(rec->fDataCount == 1);
190 0 : const PtrPair* pair = (const PtrPair*)rec->data();
191 0 : if (ptr) {
192 0 : *ptr = pair->fPtr;
193 : }
194 0 : if (proc) {
195 0 : *proc = pair->fProc;
196 : }
197 0 : return true;
198 : }
199 0 : return false;
200 : }
201 :
202 0 : const char* SkMetaData::findString(const char name[]) const
203 : {
204 0 : const Rec* rec = this->find(name, kString_Type);
205 0 : SkASSERT(rec == nullptr || rec->fDataLen == sizeof(char));
206 0 : return rec ? (const char*)rec->data() : nullptr;
207 : }
208 :
209 0 : bool SkMetaData::findBool(const char name[], bool* value) const
210 : {
211 0 : const Rec* rec = this->find(name, kBool_Type);
212 0 : if (rec)
213 : {
214 0 : SkASSERT(rec->fDataCount == 1);
215 0 : if (value)
216 0 : *value = *(const bool*)rec->data();
217 0 : return true;
218 : }
219 0 : return false;
220 : }
221 :
222 0 : const void* SkMetaData::findData(const char name[], size_t* length) const {
223 0 : const Rec* rec = this->find(name, kData_Type);
224 0 : if (rec) {
225 0 : SkASSERT(rec->fDataLen == sizeof(char));
226 0 : if (length) {
227 0 : *length = rec->fDataCount;
228 : }
229 0 : return rec->data();
230 : }
231 0 : return nullptr;
232 : }
233 :
234 0 : const SkMetaData::Rec* SkMetaData::find(const char name[], Type type) const
235 : {
236 0 : const Rec* rec = fRec;
237 0 : while (rec)
238 : {
239 0 : if (rec->fType == type && !strcmp(rec->name(), name))
240 0 : return rec;
241 0 : rec = rec->fNext;
242 : }
243 0 : return nullptr;
244 : }
245 :
246 0 : bool SkMetaData::remove(const char name[], Type type) {
247 0 : Rec* rec = fRec;
248 0 : Rec* prev = nullptr;
249 0 : while (rec) {
250 0 : Rec* next = rec->fNext;
251 0 : if (rec->fType == type && !strcmp(rec->name(), name)) {
252 0 : if (prev) {
253 0 : prev->fNext = next;
254 : } else {
255 0 : fRec = next;
256 : }
257 :
258 0 : if (kPtr_Type == type) {
259 0 : PtrPair* pair = (PtrPair*)rec->data();
260 0 : if (pair->fProc && pair->fPtr) {
261 0 : (void)pair->fProc(pair->fPtr, false);
262 : }
263 : }
264 0 : Rec::Free(rec);
265 0 : return true;
266 : }
267 0 : prev = rec;
268 0 : rec = next;
269 : }
270 0 : return false;
271 : }
272 :
273 0 : bool SkMetaData::removeS32(const char name[])
274 : {
275 0 : return this->remove(name, kS32_Type);
276 : }
277 :
278 0 : bool SkMetaData::removeScalar(const char name[])
279 : {
280 0 : return this->remove(name, kScalar_Type);
281 : }
282 :
283 0 : bool SkMetaData::removeString(const char name[])
284 : {
285 0 : return this->remove(name, kString_Type);
286 : }
287 :
288 0 : bool SkMetaData::removePtr(const char name[])
289 : {
290 0 : return this->remove(name, kPtr_Type);
291 : }
292 :
293 0 : bool SkMetaData::removeBool(const char name[])
294 : {
295 0 : return this->remove(name, kBool_Type);
296 : }
297 :
298 0 : bool SkMetaData::removeData(const char name[]) {
299 0 : return this->remove(name, kData_Type);
300 : }
301 :
302 : ///////////////////////////////////////////////////////////////////////////////
303 :
304 0 : SkMetaData::Iter::Iter(const SkMetaData& metadata) {
305 0 : fRec = metadata.fRec;
306 0 : }
307 :
308 0 : void SkMetaData::Iter::reset(const SkMetaData& metadata) {
309 0 : fRec = metadata.fRec;
310 0 : }
311 :
312 0 : const char* SkMetaData::Iter::next(SkMetaData::Type* t, int* count) {
313 0 : const char* name = nullptr;
314 :
315 0 : if (fRec) {
316 0 : if (t) {
317 0 : *t = (SkMetaData::Type)fRec->fType;
318 : }
319 0 : if (count) {
320 0 : *count = fRec->fDataCount;
321 : }
322 0 : name = fRec->name();
323 :
324 0 : fRec = fRec->fNext;
325 : }
326 0 : return name;
327 : }
328 :
329 : ///////////////////////////////////////////////////////////////////////////////
330 :
331 0 : SkMetaData::Rec* SkMetaData::Rec::Alloc(size_t size) {
332 0 : return (Rec*)sk_malloc_throw(size);
333 : }
334 :
335 0 : void SkMetaData::Rec::Free(Rec* rec) {
336 0 : sk_free(rec);
337 0 : }
|