| 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 |