1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/utils/SkJSON.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,634 @@ 1.4 +/* 1.5 + * Copyright 2011 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#include "SkJSON.h" 1.12 +#include "SkString.h" 1.13 + 1.14 +#ifdef SK_DEBUG 1.15 +// #define TRACE_SKJSON_LEAKS 1.16 +#endif 1.17 + 1.18 +#ifdef TRACE_SKJSON_LEAKS 1.19 + static int gStringCount; 1.20 + static int gSlotCount; 1.21 + static int gObjectCount; 1.22 + static int gArrayCount; 1.23 + #define LEAK_CODE(code) code 1.24 +#else 1.25 + #define LEAK_CODE(code) 1.26 +#endif 1.27 + 1.28 +/////////////////////////////////////////////////////////////////////////////// 1.29 + 1.30 +static char* alloc_string(size_t len) { 1.31 + LEAK_CODE(SkDebugf(" string[%d]\n", gStringCount++);) 1.32 + char* str = (char*)sk_malloc_throw(len + 1); 1.33 + str[len] = 0; 1.34 + return str; 1.35 +} 1.36 + 1.37 +static char* dup_string(const char src[]) { 1.38 + if (NULL == src) { 1.39 + return NULL; 1.40 + } 1.41 + size_t len = strlen(src); 1.42 + char* dst = alloc_string(len); 1.43 + memcpy(dst, src, len); 1.44 + return dst; 1.45 +} 1.46 + 1.47 +static void free_string(char* str) { 1.48 + if (str) { 1.49 + sk_free(str); 1.50 + LEAK_CODE(SkASSERT(gStringCount > 0); SkDebugf("~string[%d]\n", --gStringCount);) 1.51 + } 1.52 +} 1.53 + 1.54 +/////////////////////////////////////////////////////////////////////////////// 1.55 + 1.56 +struct SkJSON::Object::Slot { 1.57 + Slot(const char name[], Type type) { 1.58 + LEAK_CODE(SkDebugf(" slot[%d]\n", gSlotCount++);) 1.59 + SkASSERT(name); 1.60 + 1.61 + fNext = NULL; 1.62 + 1.63 + size_t len = strlen(name); 1.64 + // extra 1 for str[0] which stores the type 1.65 + char* str = alloc_string(1 + len); 1.66 + str[0] = (char)type; 1.67 + // str[1] skips the type, len+1 includes the terminating 0 byte. 1.68 + memcpy(&str[1], name, len + 1); 1.69 + fName = str; 1.70 + 1.71 + // fValue is uninitialized 1.72 + } 1.73 + ~Slot(); 1.74 + 1.75 + Type type() const { return (Type)fName[0]; } 1.76 + const char* name() const { return &fName[1]; } 1.77 + 1.78 + Slot* fNext; 1.79 + char* fName; // fName[0] is the type, &fName[1] is the "name" 1.80 + union { 1.81 + Object* fObject; 1.82 + Array* fArray; 1.83 + char* fString; 1.84 + int32_t fInt; 1.85 + float fFloat; 1.86 + bool fBool; 1.87 + } fValue; 1.88 +}; 1.89 + 1.90 +SkJSON::Object::Slot::~Slot() { 1.91 + free_string(fName); 1.92 + switch (this->type()) { 1.93 + case kObject: 1.94 + delete fValue.fObject; 1.95 + break; 1.96 + case kArray: 1.97 + delete fValue.fArray; 1.98 + break; 1.99 + case kString: 1.100 + free_string(fValue.fString); 1.101 + break; 1.102 + default: 1.103 + break; 1.104 + } 1.105 + LEAK_CODE(SkASSERT(gSlotCount > 0); SkDebugf("~slot[%d]\n", --gSlotCount);) 1.106 +} 1.107 + 1.108 +/////////////////////////////////////////////////////////////////////////////// 1.109 + 1.110 +SkJSON::Object::Iter::Iter(const Object& obj) : fSlot(obj.fHead) {} 1.111 + 1.112 +bool SkJSON::Object::Iter::done() const { 1.113 + return NULL == fSlot; 1.114 +} 1.115 + 1.116 +void SkJSON::Object::Iter::next() { 1.117 + SkASSERT(fSlot); 1.118 + fSlot = fSlot->fNext; 1.119 +} 1.120 + 1.121 +SkJSON::Type SkJSON::Object::Iter::type() const { 1.122 + SkASSERT(fSlot); 1.123 + return fSlot->type(); 1.124 +} 1.125 + 1.126 +const char* SkJSON::Object::Iter::name() const { 1.127 + SkASSERT(fSlot); 1.128 + return fSlot->name(); 1.129 +} 1.130 + 1.131 +SkJSON::Object* SkJSON::Object::Iter::objectValue() const { 1.132 + SkASSERT(fSlot); 1.133 + SkASSERT(kObject == fSlot->type()); 1.134 + return fSlot->fValue.fObject; 1.135 +} 1.136 + 1.137 +SkJSON::Array* SkJSON::Object::Iter::arrayValue() const { 1.138 + SkASSERT(fSlot); 1.139 + SkASSERT(kArray == fSlot->type()); 1.140 + return fSlot->fValue.fArray; 1.141 +} 1.142 + 1.143 +const char* SkJSON::Object::Iter::stringValue() const { 1.144 + SkASSERT(fSlot); 1.145 + SkASSERT(kString == fSlot->type()); 1.146 + return fSlot->fValue.fString; 1.147 +} 1.148 + 1.149 +int32_t SkJSON::Object::Iter::intValue() const { 1.150 + SkASSERT(fSlot); 1.151 + SkASSERT(kInt == fSlot->type()); 1.152 + return fSlot->fValue.fInt; 1.153 +} 1.154 + 1.155 +float SkJSON::Object::Iter::floatValue() const { 1.156 + SkASSERT(fSlot); 1.157 + SkASSERT(kFloat == fSlot->type()); 1.158 + return fSlot->fValue.fFloat; 1.159 +} 1.160 + 1.161 +bool SkJSON::Object::Iter::boolValue() const { 1.162 + SkASSERT(fSlot); 1.163 + SkASSERT(kBool == fSlot->type()); 1.164 + return fSlot->fValue.fBool; 1.165 +} 1.166 + 1.167 +/////////////////////////////////////////////////////////////////////////////// 1.168 + 1.169 +SkJSON::Object::Object() : fHead(NULL), fTail(NULL) { 1.170 + LEAK_CODE(SkDebugf(" object[%d]\n", gObjectCount++);) 1.171 +} 1.172 + 1.173 +SkJSON::Object::Object(const Object& other) : fHead(NULL), fTail(NULL) { 1.174 + LEAK_CODE(SkDebugf(" object[%d]\n", gObjectCount++);) 1.175 + 1.176 + Iter iter(other); 1.177 + while (!iter.done()) { 1.178 + switch (iter.type()) { 1.179 + case kObject: 1.180 + this->addObject(iter.name(), new Object(*iter.objectValue())); 1.181 + break; 1.182 + case kArray: 1.183 + this->addArray(iter.name(), new Array(*iter.arrayValue())); 1.184 + break; 1.185 + case kString: 1.186 + this->addString(iter.name(), dup_string(iter.stringValue())); 1.187 + break; 1.188 + case kInt: 1.189 + this->addInt(iter.name(), iter.intValue()); 1.190 + break; 1.191 + case kFloat: 1.192 + this->addFloat(iter.name(), iter.floatValue()); 1.193 + break; 1.194 + case kBool: 1.195 + this->addBool(iter.name(), iter.boolValue()); 1.196 + break; 1.197 + } 1.198 + iter.next(); 1.199 + } 1.200 +} 1.201 + 1.202 +SkJSON::Object::~Object() { 1.203 + Slot* slot = fHead; 1.204 + while (slot) { 1.205 + Slot* next = slot->fNext; 1.206 + delete slot; 1.207 + slot = next; 1.208 + } 1.209 + LEAK_CODE(SkASSERT(gObjectCount > 0); SkDebugf("~object[%d]\n", --gObjectCount);) 1.210 +} 1.211 + 1.212 +int SkJSON::Object::count() const { 1.213 + int n = 0; 1.214 + for (const Slot* slot = fHead; slot; slot = slot->fNext) { 1.215 + n += 1; 1.216 + } 1.217 + return n; 1.218 +} 1.219 + 1.220 +SkJSON::Object::Slot* SkJSON::Object::addSlot(Slot* slot) { 1.221 + SkASSERT(NULL == slot->fNext); 1.222 + if (NULL == fHead) { 1.223 + SkASSERT(NULL == fTail); 1.224 + fHead = fTail = slot; 1.225 + } else { 1.226 + SkASSERT(fTail); 1.227 + SkASSERT(NULL == fTail->fNext); 1.228 + fTail->fNext = slot; 1.229 + fTail = slot; 1.230 + } 1.231 + return slot; 1.232 +} 1.233 + 1.234 +void SkJSON::Object::addObject(const char name[], SkJSON::Object* value) { 1.235 + this->addSlot(new Slot(name, kObject))->fValue.fObject = value; 1.236 +} 1.237 + 1.238 +void SkJSON::Object::addArray(const char name[], SkJSON::Array* value) { 1.239 + this->addSlot(new Slot(name, kArray))->fValue.fArray = value; 1.240 +} 1.241 + 1.242 +void SkJSON::Object::addString(const char name[], const char value[]) { 1.243 + this->addSlot(new Slot(name, kString))->fValue.fString = dup_string(value); 1.244 +} 1.245 + 1.246 +void SkJSON::Object::addInt(const char name[], int32_t value) { 1.247 + this->addSlot(new Slot(name, kInt))->fValue.fInt = value; 1.248 +} 1.249 + 1.250 +void SkJSON::Object::addFloat(const char name[], float value) { 1.251 + this->addSlot(new Slot(name, kFloat))->fValue.fFloat = value; 1.252 +} 1.253 + 1.254 +void SkJSON::Object::addBool(const char name[], bool value) { 1.255 + this->addSlot(new Slot(name, kBool))->fValue.fBool = value; 1.256 +} 1.257 + 1.258 +/////////////////////////////////////////////////////////////////////////////// 1.259 + 1.260 +const SkJSON::Object::Slot* SkJSON::Object::findSlot(const char name[], 1.261 + Type t) const { 1.262 + for (const Slot* slot = fHead; slot; slot = slot->fNext) { 1.263 + if (t == slot->type() && !strcmp(slot->name(), name)) { 1.264 + return slot; 1.265 + } 1.266 + } 1.267 + return NULL; 1.268 +} 1.269 + 1.270 +bool SkJSON::Object::find(const char name[], Type t) const { 1.271 + return this->findSlot(name, t) != NULL; 1.272 +} 1.273 + 1.274 +bool SkJSON::Object::findObject(const char name[], SkJSON::Object** value) const { 1.275 + const Slot* slot = this->findSlot(name, kObject); 1.276 + if (slot) { 1.277 + if (value) { 1.278 + *value = slot->fValue.fObject; 1.279 + } 1.280 + return true; 1.281 + } 1.282 + return false; 1.283 +} 1.284 + 1.285 +bool SkJSON::Object::findArray(const char name[], SkJSON::Array** value) const { 1.286 + const Slot* slot = this->findSlot(name, kArray); 1.287 + if (slot) { 1.288 + if (value) { 1.289 + *value = slot->fValue.fArray; 1.290 + } 1.291 + return true; 1.292 + } 1.293 + return false; 1.294 +} 1.295 + 1.296 +bool SkJSON::Object::findString(const char name[], SkString* value) const { 1.297 + const Slot* slot = this->findSlot(name, kString); 1.298 + if (slot) { 1.299 + if (value) { 1.300 + value->set(slot->fValue.fString); 1.301 + } 1.302 + return true; 1.303 + } 1.304 + return false; 1.305 +} 1.306 + 1.307 +bool SkJSON::Object::findInt(const char name[], int32_t* value) const { 1.308 + const Slot* slot = this->findSlot(name, kInt); 1.309 + if (slot) { 1.310 + if (value) { 1.311 + *value = slot->fValue.fInt; 1.312 + } 1.313 + return true; 1.314 + } 1.315 + return false; 1.316 +} 1.317 + 1.318 +bool SkJSON::Object::findFloat(const char name[], float* value) const { 1.319 + const Slot* slot = this->findSlot(name, kFloat); 1.320 + if (slot) { 1.321 + if (value) { 1.322 + *value = slot->fValue.fFloat; 1.323 + } 1.324 + return true; 1.325 + } 1.326 + return false; 1.327 +} 1.328 + 1.329 +bool SkJSON::Object::findBool(const char name[], bool* value) const { 1.330 + const Slot* slot = this->findSlot(name, kBool); 1.331 + if (slot) { 1.332 + if (value) { 1.333 + *value = slot->fValue.fBool; 1.334 + } 1.335 + return true; 1.336 + } 1.337 + return false; 1.338 +} 1.339 + 1.340 +bool SkJSON::Object::remove(const char name[], Type t) { 1.341 + SkDEBUGCODE(int count = this->count();) 1.342 + Slot* prev = NULL; 1.343 + Slot* slot = fHead; 1.344 + while (slot) { 1.345 + Slot* next = slot->fNext; 1.346 + if (t == slot->type() && !strcmp(slot->name(), name)) { 1.347 + if (prev) { 1.348 + SkASSERT(fHead != slot); 1.349 + prev->fNext = next; 1.350 + } else { 1.351 + SkASSERT(fHead == slot); 1.352 + fHead = next; 1.353 + } 1.354 + if (fTail == slot) { 1.355 + fTail = prev; 1.356 + } 1.357 + delete slot; 1.358 + SkASSERT(count - 1 == this->count()); 1.359 + return true; 1.360 + } 1.361 + prev = slot; 1.362 + slot = next; 1.363 + } 1.364 + SkASSERT(count == this->count()); 1.365 + return false; 1.366 +} 1.367 + 1.368 +/////////////////////////////////////////////////////////////////////////////// 1.369 + 1.370 +static void tabForLevel(int level) { 1.371 + for (int i = 0; i < level; ++i) { 1.372 + SkDebugf(" "); 1.373 + } 1.374 +} 1.375 + 1.376 +void SkJSON::Object::toDebugf() const { 1.377 + SkDebugf("{\n"); 1.378 + this->dumpLevel(0); 1.379 + SkDebugf("}\n"); 1.380 +} 1.381 + 1.382 +void SkJSON::Object::dumpLevel(int level) const { 1.383 + for (Slot* slot = fHead; slot; slot = slot->fNext) { 1.384 + Type t = slot->type(); 1.385 + tabForLevel(level + 1); 1.386 + SkDebugf("\"%s\" : ", slot->name()); 1.387 + switch (slot->type()) { 1.388 + case kObject: 1.389 + if (slot->fValue.fObject) { 1.390 + SkDebugf("{\n"); 1.391 + slot->fValue.fObject->dumpLevel(level + 1); 1.392 + tabForLevel(level + 1); 1.393 + SkDebugf("}"); 1.394 + } else { 1.395 + SkDebugf("null"); 1.396 + } 1.397 + break; 1.398 + case kArray: 1.399 + if (slot->fValue.fArray) { 1.400 + SkDebugf("["); 1.401 + slot->fValue.fArray->dumpLevel(level + 1); 1.402 + SkDebugf("]"); 1.403 + } else { 1.404 + SkDebugf("null"); 1.405 + } 1.406 + break; 1.407 + case kString: 1.408 + SkDebugf("\"%s\"", slot->fValue.fString); 1.409 + break; 1.410 + case kInt: 1.411 + SkDebugf("%d", slot->fValue.fInt); 1.412 + break; 1.413 + case kFloat: 1.414 + SkDebugf("%g", slot->fValue.fFloat); 1.415 + break; 1.416 + case kBool: 1.417 + SkDebugf("%s", slot->fValue.fBool ? "true" : "false"); 1.418 + break; 1.419 + default: 1.420 + SkDEBUGFAIL("how did I get here"); 1.421 + break; 1.422 + } 1.423 + if (slot->fNext) { 1.424 + SkDebugf(","); 1.425 + } 1.426 + SkDebugf("\n"); 1.427 + } 1.428 +} 1.429 + 1.430 +void SkJSON::Array::dumpLevel(int level) const { 1.431 + if (0 == fCount) { 1.432 + return; 1.433 + } 1.434 + int last = fCount - 1; 1.435 + 1.436 + switch (this->type()) { 1.437 + case kObject: { 1.438 + SkDebugf("\n"); 1.439 + for (int i = 0; i <= last; ++i) { 1.440 + Object* obj = fArray.fObjects[i]; 1.441 + tabForLevel(level + 1); 1.442 + if (obj) { 1.443 + SkDebugf("{\n"); 1.444 + obj->dumpLevel(level + 1); 1.445 + tabForLevel(level + 1); 1.446 + SkDebugf(i < last ? "}," : "}"); 1.447 + } else { 1.448 + SkDebugf(i < last ? "null," : "null"); 1.449 + } 1.450 + SkDebugf("\n"); 1.451 + } 1.452 + } break; 1.453 + case kArray: { 1.454 + SkDebugf("\n"); 1.455 + for (int i = 0; i <= last; ++i) { 1.456 + Array* array = fArray.fArrays[i]; 1.457 + tabForLevel(level + 1); 1.458 + if (array) { 1.459 + SkDebugf("["); 1.460 + array->dumpLevel(level + 1); 1.461 + tabForLevel(level + 1); 1.462 + SkDebugf(i < last ? "]," : "]"); 1.463 + } else { 1.464 + SkDebugf(i < last ? "null," : "null"); 1.465 + } 1.466 + SkDebugf("\n"); 1.467 + } 1.468 + } break; 1.469 + case kString: { 1.470 + for (int i = 0; i < last; ++i) { 1.471 + const char* str = fArray.fStrings[i]; 1.472 + SkDebugf(str ? " \"%s\"," : " null,", str); 1.473 + } 1.474 + const char* str = fArray.fStrings[last]; 1.475 + SkDebugf(str ? " \"%s\" " : " null ", str); 1.476 + } break; 1.477 + case kInt: { 1.478 + for (int i = 0; i < last; ++i) { 1.479 + SkDebugf(" %d,", fArray.fInts[i]); 1.480 + } 1.481 + SkDebugf(" %d ", fArray.fInts[last]); 1.482 + } break; 1.483 + case kFloat: { 1.484 + for (int i = 0; i < last; ++i) { 1.485 + SkDebugf(" %g,", fArray.fFloats[i]); 1.486 + } 1.487 + SkDebugf(" %g ", fArray.fFloats[last]); 1.488 + } break; 1.489 + case kBool: { 1.490 + for (int i = 0; i < last; ++i) { 1.491 + SkDebugf(" %s,", fArray.fBools[i] ? "true" : "false"); 1.492 + } 1.493 + SkDebugf(" %s ", fArray.fInts[last] ? "true" : "false"); 1.494 + } break; 1.495 + default: 1.496 + SkDEBUGFAIL("unsupported array type"); 1.497 + break; 1.498 + } 1.499 +} 1.500 + 1.501 +/////////////////////////////////////////////////////////////////////////////// 1.502 + 1.503 +static const uint8_t gBytesPerType[] = { 1.504 + sizeof(SkJSON::Object*), 1.505 + sizeof(SkJSON::Array*), 1.506 + sizeof(char*), 1.507 + sizeof(int32_t), 1.508 + sizeof(float), 1.509 + sizeof(bool) 1.510 +}; 1.511 + 1.512 +typedef void* (*DupProc)(const void*); 1.513 + 1.514 +static void* dup_object(const void* src) { 1.515 + return SkNEW_ARGS(SkJSON::Object, (*(SkJSON::Object*)src)); 1.516 +} 1.517 + 1.518 +static void* dup_array(const void* src) { 1.519 + return SkNEW_ARGS(SkJSON::Array, (*(SkJSON::Array*)src)); 1.520 +} 1.521 + 1.522 +static const DupProc gDupProcs[] = { 1.523 + dup_object, // Object 1.524 + dup_array, // Array 1.525 + (DupProc)dup_string, // String 1.526 + NULL, // int 1.527 + NULL, // float 1.528 + NULL, // bool 1.529 +}; 1.530 + 1.531 +void SkJSON::Array::init(Type type, int count, const void* src) { 1.532 + LEAK_CODE(SkDebugf(" array[%d]\n", gArrayCount++);) 1.533 + 1.534 + SkASSERT((unsigned)type < SK_ARRAY_COUNT(gBytesPerType)); 1.535 + 1.536 + if (count < 0) { 1.537 + count = 0; 1.538 + } 1.539 + size_t size = count * gBytesPerType[type]; 1.540 + 1.541 + fCount = count; 1.542 + fType = type; 1.543 + fArray.fVoids = sk_malloc_throw(size); 1.544 + if (src) { 1.545 + DupProc proc = gDupProcs[fType]; 1.546 + if (!proc) { 1.547 + memcpy(fArray.fVoids, src, size); 1.548 + } else { 1.549 + void** srcPtr = (void**)src; 1.550 + void** dstPtr = (void**)fArray.fVoids; 1.551 + for (int i = 0; i < fCount; ++i) { 1.552 + dstPtr[i] = proc(srcPtr[i]); 1.553 + } 1.554 + } 1.555 + } else { 1.556 + sk_bzero(fArray.fVoids, size); 1.557 + } 1.558 +} 1.559 + 1.560 +SkJSON::Array::Array(Type type, int count) { 1.561 + this->init(type, count, NULL); 1.562 +} 1.563 + 1.564 +SkJSON::Array::Array(const int32_t values[], int count) { 1.565 + this->init(kInt, count, values); 1.566 +} 1.567 + 1.568 +SkJSON::Array::Array(const float values[], int count) { 1.569 + this->init(kFloat, count, values); 1.570 +} 1.571 + 1.572 +SkJSON::Array::Array(const bool values[], int count) { 1.573 + this->init(kBool, count, values); 1.574 +} 1.575 + 1.576 +SkJSON::Array::Array(const Array& other) { 1.577 + this->init(other.type(), other.count(), other.fArray.fVoids); 1.578 +} 1.579 + 1.580 +typedef void (*FreeProc)(void*); 1.581 + 1.582 +static void free_object(void* obj) { 1.583 + delete (SkJSON::Object*)obj; 1.584 +} 1.585 + 1.586 +static void free_array(void* array) { 1.587 + delete (SkJSON::Array*)array; 1.588 +} 1.589 + 1.590 +static const FreeProc gFreeProcs[] = { 1.591 + free_object, // Object 1.592 + free_array, // Array 1.593 + (FreeProc)free_string, // String 1.594 + NULL, // int 1.595 + NULL, // float 1.596 + NULL, // bool 1.597 +}; 1.598 + 1.599 +SkJSON::Array::~Array() { 1.600 + FreeProc proc = gFreeProcs[fType]; 1.601 + if (proc) { 1.602 + void** ptr = (void**)fArray.fVoids; 1.603 + for (int i = 0; i < fCount; ++i) { 1.604 + proc(ptr[i]); 1.605 + } 1.606 + } 1.607 + sk_free(fArray.fVoids); 1.608 + 1.609 + LEAK_CODE(SkASSERT(gArrayCount > 0); SkDebugf("~array[%d]\n", --gArrayCount);) 1.610 +} 1.611 + 1.612 +void SkJSON::Array::setObject(int index, Object* object) { 1.613 + SkASSERT((unsigned)index < (unsigned)fCount); 1.614 + Object*& prev = fArray.fObjects[index]; 1.615 + if (prev != object) { 1.616 + delete prev; 1.617 + prev = object; 1.618 + } 1.619 +} 1.620 + 1.621 +void SkJSON::Array::setArray(int index, Array* array) { 1.622 + SkASSERT((unsigned)index < (unsigned)fCount); 1.623 + Array*& prev = fArray.fArrays[index]; 1.624 + if (prev != array) { 1.625 + delete prev; 1.626 + prev = array; 1.627 + } 1.628 +} 1.629 + 1.630 +void SkJSON::Array::setString(int index, const char str[]) { 1.631 + SkASSERT((unsigned)index < (unsigned)fCount); 1.632 + char*& prev = fArray.fStrings[index]; 1.633 + if (prev != str) { 1.634 + free_string(prev); 1.635 + prev = dup_string(str); 1.636 + } 1.637 +}