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