OLD | NEW |
| (Empty) |
1 /* libs/graphics/views/SkMetaData.cpp | |
2 ** | |
3 ** Copyright 2006, The Android Open Source Project | |
4 ** | |
5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
6 ** you may not use this file except in compliance with the License. | |
7 ** You may obtain a copy of the License at | |
8 ** | |
9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
10 ** | |
11 ** Unless required by applicable law or agreed to in writing, software | |
12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 ** See the License for the specific language governing permissions and | |
15 ** limitations under the License. | |
16 */ | |
17 | |
18 #include "SkMetaData.h" | |
19 | |
20 SkMetaData::SkMetaData() : fRec(NULL) | |
21 { | |
22 } | |
23 | |
24 SkMetaData::SkMetaData(const SkMetaData& src) : fRec(NULL) | |
25 { | |
26 *this = src; | |
27 } | |
28 | |
29 SkMetaData::~SkMetaData() | |
30 { | |
31 this->reset(); | |
32 } | |
33 | |
34 void SkMetaData::reset() | |
35 { | |
36 Rec* rec = fRec; | |
37 while (rec) | |
38 { | |
39 Rec* next = rec->fNext; | |
40 Rec::Free(rec); | |
41 rec = next; | |
42 } | |
43 fRec = NULL; | |
44 } | |
45 | |
46 SkMetaData& SkMetaData::operator=(const SkMetaData& src) | |
47 { | |
48 this->reset(); | |
49 | |
50 const Rec* rec = src.fRec; | |
51 while (rec) | |
52 { | |
53 this->set(rec->name(), rec->data(), rec->fDataLen, (Type)rec->fType, rec
->fDataCount); | |
54 rec = rec->fNext; | |
55 } | |
56 return *this; | |
57 } | |
58 | |
59 void SkMetaData::setS32(const char name[], int32_t value) | |
60 { | |
61 (void)this->set(name, &value, sizeof(int32_t), kS32_Type, 1); | |
62 } | |
63 | |
64 void SkMetaData::setScalar(const char name[], SkScalar value) | |
65 { | |
66 (void)this->set(name, &value, sizeof(SkScalar), kScalar_Type, 1); | |
67 } | |
68 | |
69 SkScalar* SkMetaData::setScalars(const char name[], int count, const SkScalar va
lues[]) | |
70 { | |
71 SkASSERT(count > 0); | |
72 if (count > 0) | |
73 return (SkScalar*)this->set(name, values, sizeof(SkScalar), kScalar_Type
, count); | |
74 return NULL; | |
75 } | |
76 | |
77 void SkMetaData::setString(const char name[], const char value[]) | |
78 { | |
79 (void)this->set(name, value, sizeof(char), kString_Type, strlen(value) + 1); | |
80 } | |
81 | |
82 void SkMetaData::setPtr(const char name[], void* ptr) | |
83 { | |
84 (void)this->set(name, &ptr, sizeof(void*), kPtr_Type, 1); | |
85 } | |
86 | |
87 void SkMetaData::setBool(const char name[], bool value) | |
88 { | |
89 (void)this->set(name, &value, sizeof(bool), kBool_Type, 1); | |
90 } | |
91 | |
92 void* SkMetaData::set(const char name[], const void* data, size_t dataSize, Type
type, int count) | |
93 { | |
94 SkASSERT(name); | |
95 SkASSERT(dataSize); | |
96 SkASSERT(count > 0); | |
97 | |
98 (void)this->remove(name, type); | |
99 | |
100 size_t len = strlen(name); | |
101 Rec* rec = Rec::Alloc(sizeof(Rec) + dataSize * count + len + 1); | |
102 | |
103 #ifndef SK_DEBUG | |
104 rec->fType = SkToU8(type); | |
105 #else | |
106 rec->fType = type; | |
107 #endif | |
108 rec->fDataLen = SkToU8(dataSize); | |
109 rec->fDataCount = SkToU16(count); | |
110 if (data) | |
111 memcpy(rec->data(), data, dataSize * count); | |
112 memcpy(rec->name(), name, len + 1); | |
113 | |
114 #ifdef SK_DEBUG | |
115 rec->fName = rec->name(); | |
116 switch (type) { | |
117 case kS32_Type: | |
118 rec->fData.fS32 = *(const int32_t*)rec->data(); | |
119 break; | |
120 case kScalar_Type: | |
121 rec->fData.fScalar = *(const SkScalar*)rec->data(); | |
122 break; | |
123 case kString_Type: | |
124 rec->fData.fString = (const char*)rec->data(); | |
125 break; | |
126 case kPtr_Type: | |
127 rec->fData.fPtr = *(void**)rec->data(); | |
128 break; | |
129 case kBool_Type: | |
130 rec->fData.fBool = *(const bool*)rec->data(); | |
131 break; | |
132 default: | |
133 SkASSERT(!"bad type"); | |
134 break; | |
135 } | |
136 #endif | |
137 | |
138 rec->fNext = fRec; | |
139 fRec = rec; | |
140 return rec->data(); | |
141 } | |
142 | |
143 bool SkMetaData::findS32(const char name[], int32_t* value) const | |
144 { | |
145 const Rec* rec = this->find(name, kS32_Type); | |
146 if (rec) | |
147 { | |
148 SkASSERT(rec->fDataCount == 1); | |
149 if (value) | |
150 *value = *(const int32_t*)rec->data(); | |
151 return true; | |
152 } | |
153 return false; | |
154 } | |
155 | |
156 bool SkMetaData::findScalar(const char name[], SkScalar* value) const | |
157 { | |
158 const Rec* rec = this->find(name, kScalar_Type); | |
159 if (rec) | |
160 { | |
161 SkASSERT(rec->fDataCount == 1); | |
162 if (value) | |
163 *value = *(const SkScalar*)rec->data(); | |
164 return true; | |
165 } | |
166 return false; | |
167 } | |
168 | |
169 const SkScalar* SkMetaData::findScalars(const char name[], int* count, SkScalar
values[]) const | |
170 { | |
171 const Rec* rec = this->find(name, kScalar_Type); | |
172 if (rec) | |
173 { | |
174 if (count) | |
175 *count = rec->fDataCount; | |
176 if (values) | |
177 memcpy(values, rec->data(), rec->fDataCount * rec->fDataLen); | |
178 return (const SkScalar*)rec->data(); | |
179 } | |
180 return NULL; | |
181 } | |
182 | |
183 bool SkMetaData::findPtr(const char name[], void** value) const | |
184 { | |
185 const Rec* rec = this->find(name, kPtr_Type); | |
186 if (rec) | |
187 { | |
188 SkASSERT(rec->fDataCount == 1); | |
189 if (value) | |
190 *value = *(void**)rec->data(); | |
191 return true; | |
192 } | |
193 return false; | |
194 } | |
195 | |
196 const char* SkMetaData::findString(const char name[]) const | |
197 { | |
198 const Rec* rec = this->find(name, kString_Type); | |
199 SkASSERT(rec == NULL || rec->fDataLen == sizeof(char)); | |
200 return rec ? (const char*)rec->data() : NULL; | |
201 } | |
202 | |
203 bool SkMetaData::findBool(const char name[], bool* value) const | |
204 { | |
205 const Rec* rec = this->find(name, kBool_Type); | |
206 if (rec) | |
207 { | |
208 SkASSERT(rec->fDataCount == 1); | |
209 if (value) | |
210 *value = *(const bool*)rec->data(); | |
211 return true; | |
212 } | |
213 return false; | |
214 } | |
215 | |
216 const SkMetaData::Rec* SkMetaData::find(const char name[], Type type) const | |
217 { | |
218 const Rec* rec = fRec; | |
219 while (rec) | |
220 { | |
221 if (rec->fType == type && !strcmp(rec->name(), name)) | |
222 return rec; | |
223 rec = rec->fNext; | |
224 } | |
225 return NULL; | |
226 } | |
227 | |
228 bool SkMetaData::remove(const char name[], Type type) | |
229 { | |
230 Rec* rec = fRec; | |
231 Rec* prev = NULL; | |
232 while (rec) | |
233 { | |
234 Rec* next = rec->fNext; | |
235 if (rec->fType == type && !strcmp(rec->name(), name)) | |
236 { | |
237 if (prev) | |
238 prev->fNext = next; | |
239 else | |
240 fRec = next; | |
241 Rec::Free(rec); | |
242 return true; | |
243 } | |
244 prev = rec; | |
245 rec = next; | |
246 } | |
247 return false; | |
248 } | |
249 | |
250 bool SkMetaData::removeS32(const char name[]) | |
251 { | |
252 return this->remove(name, kS32_Type); | |
253 } | |
254 | |
255 bool SkMetaData::removeScalar(const char name[]) | |
256 { | |
257 return this->remove(name, kScalar_Type); | |
258 } | |
259 | |
260 bool SkMetaData::removeString(const char name[]) | |
261 { | |
262 return this->remove(name, kString_Type); | |
263 } | |
264 | |
265 bool SkMetaData::removePtr(const char name[]) | |
266 { | |
267 return this->remove(name, kPtr_Type); | |
268 } | |
269 | |
270 bool SkMetaData::removeBool(const char name[]) | |
271 { | |
272 return this->remove(name, kBool_Type); | |
273 } | |
274 | |
275 ////////////////////////////////////////////////////////////////////////////////
/// | |
276 | |
277 SkMetaData::Iter::Iter(const SkMetaData& metadata) | |
278 { | |
279 fRec = metadata.fRec; | |
280 } | |
281 | |
282 void SkMetaData::Iter::reset(const SkMetaData& metadata) | |
283 { | |
284 fRec = metadata.fRec; | |
285 } | |
286 | |
287 const char* SkMetaData::Iter::next(SkMetaData::Type* t, int* count) | |
288 { | |
289 const char* name = NULL; | |
290 | |
291 if (fRec) | |
292 { | |
293 if (t) | |
294 *t = (SkMetaData::Type)fRec->fType; | |
295 if (count) | |
296 *count = fRec->fDataCount; | |
297 name = fRec->name(); | |
298 | |
299 fRec = fRec->fNext; | |
300 } | |
301 return name; | |
302 } | |
303 | |
304 ////////////////////////////////////////////////////////////////////////////////
/// | |
305 | |
306 SkMetaData::Rec* SkMetaData::Rec::Alloc(size_t size) | |
307 { | |
308 return (Rec*)sk_malloc_throw(size); | |
309 } | |
310 | |
311 void SkMetaData::Rec::Free(Rec* rec) | |
312 { | |
313 sk_free(rec); | |
314 } | |
315 | |
316 ////////////////////////////////////////////////////////////////////////////////
/// | |
317 ////////////////////////////////////////////////////////////////////////////////
/// | |
318 | |
319 #ifdef SK_DEBUG | |
320 | |
321 void SkMetaData::UnitTest() | |
322 { | |
323 #ifdef SK_SUPPORT_UNITTEST | |
324 SkMetaData m1; | |
325 | |
326 SkASSERT(!m1.findS32("int")); | |
327 SkASSERT(!m1.findScalar("scalar")); | |
328 SkASSERT(!m1.findString("hello")); | |
329 SkASSERT(!m1.removeS32("int")); | |
330 SkASSERT(!m1.removeScalar("scalar")); | |
331 SkASSERT(!m1.removeString("hello")); | |
332 SkASSERT(!m1.removeString("true")); | |
333 SkASSERT(!m1.removeString("false")); | |
334 | |
335 m1.setS32("int", 12345); | |
336 m1.setScalar("scalar", SK_Scalar1 * 42); | |
337 m1.setString("hello", "world"); | |
338 m1.setPtr("ptr", &m1); | |
339 m1.setBool("true", true); | |
340 m1.setBool("false", false); | |
341 | |
342 int32_t n; | |
343 SkScalar s; | |
344 | |
345 m1.setScalar("scalar", SK_Scalar1/2); | |
346 | |
347 SkASSERT(m1.findS32("int", &n) && n == 12345); | |
348 SkASSERT(m1.findScalar("scalar", &s) && s == SK_Scalar1/2); | |
349 SkASSERT(!strcmp(m1.findString("hello"), "world")); | |
350 SkASSERT(m1.hasBool("true", true)); | |
351 SkASSERT(m1.hasBool("false", false)); | |
352 | |
353 Iter iter(m1); | |
354 const char* name; | |
355 | |
356 static const struct { | |
357 const char* fName; | |
358 SkMetaData::Type fType; | |
359 int fCount; | |
360 } gElems[] = { | |
361 { "int", SkMetaData::kS32_Type, 1 }, | |
362 { "scalar", SkMetaData::kScalar_Type, 1 }, | |
363 { "ptr", SkMetaData::kPtr_Type, 1 }, | |
364 { "hello", SkMetaData::kString_Type, sizeof("world") }, | |
365 { "true", SkMetaData::kBool_Type, 1 }, | |
366 { "false", SkMetaData::kBool_Type, 1 } | |
367 }; | |
368 | |
369 int loop = 0; | |
370 int count; | |
371 SkMetaData::Type t; | |
372 while ((name = iter.next(&t, &count)) != NULL) | |
373 { | |
374 int match = 0; | |
375 for (unsigned i = 0; i < SK_ARRAY_COUNT(gElems); i++) | |
376 { | |
377 if (!strcmp(name, gElems[i].fName)) | |
378 { | |
379 match += 1; | |
380 SkASSERT(gElems[i].fType == t); | |
381 SkASSERT(gElems[i].fCount == count); | |
382 } | |
383 } | |
384 SkASSERT(match == 1); | |
385 loop += 1; | |
386 } | |
387 SkASSERT(loop == SK_ARRAY_COUNT(gElems)); | |
388 | |
389 SkASSERT(m1.removeS32("int")); | |
390 SkASSERT(m1.removeScalar("scalar")); | |
391 SkASSERT(m1.removeString("hello")); | |
392 SkASSERT(m1.removeBool("true")); | |
393 SkASSERT(m1.removeBool("false")); | |
394 | |
395 SkASSERT(!m1.findS32("int")); | |
396 SkASSERT(!m1.findScalar("scalar")); | |
397 SkASSERT(!m1.findString("hello")); | |
398 SkASSERT(!m1.findBool("true")); | |
399 SkASSERT(!m1.findBool("false")); | |
400 #endif | |
401 } | |
402 | |
403 #endif | |
404 | |
405 | |
OLD | NEW |