180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkJSON.h" 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkString.h" 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// #define TRACE_SKJSON_LEAKS 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef TRACE_SKJSON_LEAKS 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int gStringCount; 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int gSlotCount; 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int gObjectCount; 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static int gArrayCount; 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define LEAK_CODE(code) code 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define LEAK_CODE(code) 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic char* alloc_string(size_t len) { 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru LEAK_CODE(SkDebugf(" string[%d]\n", gStringCount++);) 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* str = (char*)sk_malloc_throw(len + 1); 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str[len] = 0; 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return str; 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic char* dup_string(const char src[]) { 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == src) { 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t len = strlen(src); 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* dst = alloc_string(len); 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(dst, src, len); 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return dst; 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void free_string(char* str) { 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (str) { 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sk_free(str); 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru LEAK_CODE(SkASSERT(gStringCount > 0); SkDebugf("~string[%d]\n", --gStringCount);) 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustruct SkJSON::Object::Slot { 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Slot(const char name[], Type type) { 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru LEAK_CODE(SkDebugf(" slot[%d]\n", gSlotCount++);) 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(name); 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fNext = NULL; 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t len = strlen(name); 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // extra 1 for str[0] which stores the type 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* str = alloc_string(1 + len); 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru str[0] = (char)type; 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // str[1] skips the type, len+1 includes the terminating 0 byte. 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(&str[1], name, len + 1); 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fName = str; 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // fValue is uninitialized 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ~Slot(); 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Type type() const { return (Type)fName[0]; } 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* name() const { return &fName[1]; } 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Slot* fNext; 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* fName; // fName[0] is the type, &fName[1] is the "name" 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru union { 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Object* fObject; 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Array* fArray; 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char* fString; 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int32_t fInt; 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float fFloat; 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool fBool; 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } fValue; 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Object::Slot::~Slot() { 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru free_string(fName); 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (this->type()) { 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kObject: 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fValue.fObject; 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kArray: 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete fValue.fArray; 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kString: 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru free_string(fValue.fString); 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru LEAK_CODE(SkASSERT(gSlotCount > 0); SkDebugf("~slot[%d]\n", --gSlotCount);) 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Object::Iter::Iter(const Object& obj) : fSlot(obj.fHead) {} 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkJSON::Object::Iter::done() const { 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL == fSlot; 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkJSON::Object::Iter::next() { 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fSlot); 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSlot = fSlot->fNext; 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Type SkJSON::Object::Iter::type() const { 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fSlot); 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fSlot->type(); 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* SkJSON::Object::Iter::name() const { 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fSlot); 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fSlot->name(); 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Object* SkJSON::Object::Iter::objectValue() const { 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fSlot); 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(kObject == fSlot->type()); 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fSlot->fValue.fObject; 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Array* SkJSON::Object::Iter::arrayValue() const { 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fSlot); 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(kArray == fSlot->type()); 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fSlot->fValue.fArray; 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst char* SkJSON::Object::Iter::stringValue() const { 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fSlot); 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(kString == fSlot->type()); 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fSlot->fValue.fString; 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint32_t SkJSON::Object::Iter::intValue() const { 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fSlot); 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(kInt == fSlot->type()); 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fSlot->fValue.fInt; 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querufloat SkJSON::Object::Iter::floatValue() const { 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fSlot); 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(kFloat == fSlot->type()); 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fSlot->fValue.fFloat; 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkJSON::Object::Iter::boolValue() const { 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fSlot); 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(kBool == fSlot->type()); 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fSlot->fValue.fBool; 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Object::Object() : fHead(NULL), fTail(NULL) { 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru LEAK_CODE(SkDebugf(" object[%d]\n", gObjectCount++);) 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Object::Object(const Object& other) : fHead(NULL), fTail(NULL) { 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru LEAK_CODE(SkDebugf(" object[%d]\n", gObjectCount++);) 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Iter iter(other); 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (!iter.done()) { 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (iter.type()) { 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kObject: 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->addObject(iter.name(), new Object(*iter.objectValue())); 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kArray: 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->addArray(iter.name(), new Array(*iter.arrayValue())); 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kString: 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->addString(iter.name(), dup_string(iter.stringValue())); 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kInt: 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->addInt(iter.name(), iter.intValue()); 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kFloat: 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->addFloat(iter.name(), iter.floatValue()); 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kBool: 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->addBool(iter.name(), iter.boolValue()); 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru iter.next(); 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Object::~Object() { 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Slot* slot = fHead; 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (slot) { 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Slot* next = slot->fNext; 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete slot; 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru slot = next; 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru LEAK_CODE(SkASSERT(gObjectCount > 0); SkDebugf("~object[%d]\n", --gObjectCount);) 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkJSON::Object::count() const { 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int n = 0; 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (const Slot* slot = fHead; slot; slot = slot->fNext) { 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n += 1; 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return n; 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Object::Slot* SkJSON::Object::addSlot(Slot* slot) { 21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(NULL == slot->fNext); 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == fHead) { 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(NULL == fTail); 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fHead = fTail = slot; 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fTail); 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(NULL == fTail->fNext); 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTail->fNext = slot; 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTail = slot; 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return slot; 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkJSON::Object::addObject(const char name[], SkJSON::Object* value) { 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->addSlot(new Slot(name, kObject))->fValue.fObject = value; 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkJSON::Object::addArray(const char name[], SkJSON::Array* value) { 23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->addSlot(new Slot(name, kArray))->fValue.fArray = value; 23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkJSON::Object::addString(const char name[], const char value[]) { 24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->addSlot(new Slot(name, kString))->fValue.fString = dup_string(value); 24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkJSON::Object::addInt(const char name[], int32_t value) { 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->addSlot(new Slot(name, kInt))->fValue.fInt = value; 24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkJSON::Object::addFloat(const char name[], float value) { 24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->addSlot(new Slot(name, kFloat))->fValue.fFloat = value; 24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkJSON::Object::addBool(const char name[], bool value) { 25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->addSlot(new Slot(name, kBool))->fValue.fBool = value; 25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst SkJSON::Object::Slot* SkJSON::Object::findSlot(const char name[], 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Type t) const { 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (const Slot* slot = fHead; slot; slot = slot->fNext) { 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (t == slot->type() && !strcmp(slot->name(), name)) { 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return slot; 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkJSON::Object::find(const char name[], Type t) const { 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->findSlot(name, t) != NULL; 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkJSON::Object::findObject(const char name[], SkJSON::Object** value) const { 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const Slot* slot = this->findSlot(name, kObject); 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (slot) { 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) { 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *value = slot->fValue.fObject; 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkJSON::Object::findArray(const char name[], SkJSON::Array** value) const { 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const Slot* slot = this->findSlot(name, kArray); 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (slot) { 28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) { 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *value = slot->fValue.fArray; 28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkJSON::Object::findString(const char name[], SkString* value) const { 29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const Slot* slot = this->findSlot(name, kString); 29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (slot) { 29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) { 29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru value->set(slot->fValue.fString); 29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkJSON::Object::findInt(const char name[], int32_t* value) const { 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const Slot* slot = this->findSlot(name, kInt); 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (slot) { 30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) { 30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *value = slot->fValue.fInt; 30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkJSON::Object::findFloat(const char name[], float* value) const { 31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const Slot* slot = this->findSlot(name, kFloat); 31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (slot) { 31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) { 31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *value = slot->fValue.fFloat; 32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkJSON::Object::findBool(const char name[], bool* value) const { 32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const Slot* slot = this->findSlot(name, kBool); 32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (slot) { 32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (value) { 33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *value = slot->fValue.fBool; 33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkJSON::Object::remove(const char name[], Type t) { 33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDEBUGCODE(int count = this->count();) 33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Slot* prev = NULL; 34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Slot* slot = fHead; 34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (slot) { 34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Slot* next = slot->fNext; 34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (t == slot->type() && !strcmp(slot->name(), name)) { 34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (prev) { 34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fHead != slot); 34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru prev->fNext = next; 34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(fHead == slot); 34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fHead = next; 35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fTail == slot) { 35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fTail = prev; 35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete slot; 35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(count - 1 == this->count()); 35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru prev = slot; 35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru slot = next; 36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(count == this->count()); 36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void tabForLevel(int level) { 36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < level; ++i) { 36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(" "); 37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkJSON::Object::toDebugf() const { 37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("{\n"); 37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->dumpLevel(0); 37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("}\n"); 37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkJSON::Object::dumpLevel(int level) const { 38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (Slot* slot = fHead; slot; slot = slot->fNext) { 38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Type t = slot->type(); 38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tabForLevel(level + 1); 38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("\"%s\" : ", slot->name()); 38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (slot->type()) { 38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kObject: 38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (slot->fValue.fObject) { 38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("{\n"); 38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru slot->fValue.fObject->dumpLevel(level + 1); 38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tabForLevel(level + 1); 39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("}"); 39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("null"); 39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kArray: 39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (slot->fValue.fArray) { 39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("["); 39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru slot->fValue.fArray->dumpLevel(level + 1); 39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("]"); 40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("null"); 40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kString: 40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("\"%s\"", slot->fValue.fString); 40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kInt: 40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("%d", slot->fValue.fInt); 40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kFloat: 41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("%g", slot->fValue.fFloat); 41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kBool: 41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("%s", slot->fValue.fBool ? "true" : "false"); 41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(!"how did I get here"); 41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 41980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (slot->fNext) { 42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(","); 42280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("\n"); 42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkJSON::Array::dumpLevel(int level) const { 42880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == fCount) { 42980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 43180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int last = fCount - 1; 43280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 43380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (this->type()) { 43480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kObject: { 43580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("\n"); 43680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i <= last; ++i) { 43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Object* obj = fArray.fObjects[i]; 43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tabForLevel(level + 1); 43980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (obj) { 44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("{\n"); 44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru obj->dumpLevel(level + 1); 44280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tabForLevel(level + 1); 44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(i < last ? "}," : "}"); 44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(i < last ? "null," : "null"); 44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 44780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("\n"); 44880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 44980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } break; 45080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kArray: { 45180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("\n"); 45280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i <= last; ++i) { 45380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Array* array = fArray.fArrays[i]; 45480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tabForLevel(level + 1); 45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (array) { 45680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("["); 45780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru array->dumpLevel(level + 1); 45880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tabForLevel(level + 1); 45980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(i < last ? "]," : "]"); 46080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 46180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(i < last ? "null," : "null"); 46280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 46380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("\n"); 46480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } break; 46680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kString: { 46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < last; ++i) { 46880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* str = fArray.fStrings[i]; 46980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(str ? " \"%s\"," : " null,", str); 47080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 47180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const char* str = fArray.fStrings[last]; 47280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(str ? " \"%s\" " : " null ", str); 47380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } break; 47480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kInt: { 47580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < last; ++i) { 47680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(" %d,", fArray.fInts[i]); 47780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 47880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(" %d ", fArray.fInts[last]); 47980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } break; 48080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kFloat: { 48180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < last; ++i) { 48280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(" %g,", fArray.fFloats[i]); 48380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 48480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(" %g ", fArray.fFloats[last]); 48580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } break; 48680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case kBool: { 48780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < last; ++i) { 48880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(" %s,", fArray.fBools[i] ? "true" : "false"); 48980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 49080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf(" %s ", fArray.fInts[last] ? "true" : "false"); 49180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } break; 49280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 49380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(!"unsupported array type"); 49480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 49580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 49680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 49780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 49880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 49980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 50080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const uint8_t gBytesPerType[] = { 50180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sizeof(SkJSON::Object*), 50280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sizeof(SkJSON::Array*), 50380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sizeof(char*), 50480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sizeof(int32_t), 50580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sizeof(float), 50680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sizeof(bool) 50780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 50880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 50980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutypedef void* (*DupProc)(const void*); 51080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 51180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void* dup_object(const void* src) { 51280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkNEW_ARGS(SkJSON::Object, (*(SkJSON::Object*)src)); 51380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 51480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 51580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void* dup_array(const void* src) { 51680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkNEW_ARGS(SkJSON::Array, (*(SkJSON::Array*)src)); 51780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 51880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 51980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const DupProc gDupProcs[] = { 52080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dup_object, // Object 52180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dup_array, // Array 52280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (DupProc)dup_string, // String 52380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NULL, // int 52480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NULL, // float 52580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NULL, // bool 52680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 52780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkJSON::Array::init(Type type, int count, const void* src) { 52980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru LEAK_CODE(SkDebugf(" array[%d]\n", gArrayCount++);) 53080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 53180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((unsigned)type < SK_ARRAY_COUNT(gBytesPerType)); 53280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 53380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (count < 0) { 53480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru count = 0; 53580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 53680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t size = count * gBytesPerType[type]; 53780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 53880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCount = count; 53980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fType = type; 54080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fArray.fVoids = sk_malloc_throw(size); 54180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (src) { 54280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru DupProc proc = gDupProcs[fType]; 54380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!proc) { 54480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(fArray.fVoids, src, size); 54580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 54680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void** srcPtr = (void**)src; 54780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void** dstPtr = (void**)fArray.fVoids; 54880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < fCount; ++i) { 54980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dstPtr[i] = proc(srcPtr[i]); 55080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 55180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 55280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 55380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sk_bzero(fArray.fVoids, size); 55480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 55580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 55680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 55780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Array::Array(Type type, int count) { 55880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->init(type, count, NULL); 55980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 56080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 56180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Array::Array(const int32_t values[], int count) { 56280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->init(kInt, count, values); 56380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 56480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 56580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Array::Array(const float values[], int count) { 56680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->init(kFloat, count, values); 56780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 56880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 56980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Array::Array(const bool values[], int count) { 57080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->init(kBool, count, values); 57180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 57280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 57380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Array::Array(const Array& other) { 57480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->init(other.type(), other.count(), other.fArray.fVoids); 57580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 57680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 57780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutypedef void (*FreeProc)(void*); 57880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 57980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void free_object(void* obj) { 58080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete (SkJSON::Object*)obj; 58180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 58280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 58380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void free_array(void* array) { 58480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete (SkJSON::Array*)array; 58580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 58680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 58780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const FreeProc gFreeProcs[] = { 58880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru free_object, // Object 58980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru free_array, // Array 59080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (FreeProc)free_string, // String 59180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NULL, // int 59280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NULL, // float 59380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru NULL, // bool 59480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 59580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 59680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkJSON::Array::~Array() { 59780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru FreeProc proc = gFreeProcs[fType]; 59880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (proc) { 59980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void** ptr = (void**)fArray.fVoids; 60080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < fCount; ++i) { 60180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru proc(ptr[i]); 60280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 60380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 60480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sk_free(fArray.fVoids); 60580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 60680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru LEAK_CODE(SkASSERT(gArrayCount > 0); SkDebugf("~array[%d]\n", --gArrayCount);) 60780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 60880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 60980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkJSON::Array::setObject(int index, Object* object) { 61080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((unsigned)index < (unsigned)fCount); 61180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Object*& prev = fArray.fObjects[index]; 61280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (prev != object) { 61380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete prev; 61480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru prev = object; 61580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 61680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 61780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 61880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkJSON::Array::setArray(int index, Array* array) { 61980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((unsigned)index < (unsigned)fCount); 62080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Array*& prev = fArray.fArrays[index]; 62180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (prev != array) { 62280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete prev; 62380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru prev = array; 62480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 62580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 62680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 62780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkJSON::Array::setString(int index, const char str[]) { 62880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((unsigned)index < (unsigned)fCount); 62980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru char*& prev = fArray.fStrings[index]; 63080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (prev != str) { 63180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru free_string(prev); 63280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru prev = dup_string(str); 63380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 63480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 635