| Index: src/utils/SkJSON.cpp
|
| diff --git a/src/utils/SkJSON.cpp b/src/utils/SkJSON.cpp
|
| deleted file mode 100644
|
| index 1aedf58d8b6c1dec8369fea8885d2e4be28a80aa..0000000000000000000000000000000000000000
|
| --- a/src/utils/SkJSON.cpp
|
| +++ /dev/null
|
| @@ -1,634 +0,0 @@
|
| -/*
|
| - * Copyright 2011 Google Inc.
|
| - *
|
| - * Use of this source code is governed by a BSD-style license that can be
|
| - * found in the LICENSE file.
|
| - */
|
| -
|
| -#include "SkJSON.h"
|
| -#include "SkString.h"
|
| -
|
| -#ifdef SK_DEBUG
|
| -// #define TRACE_SKJSON_LEAKS
|
| -#endif
|
| -
|
| -#ifdef TRACE_SKJSON_LEAKS
|
| - static int gStringCount;
|
| - static int gSlotCount;
|
| - static int gObjectCount;
|
| - static int gArrayCount;
|
| - #define LEAK_CODE(code) code
|
| -#else
|
| - #define LEAK_CODE(code)
|
| -#endif
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -static char* alloc_string(size_t len) {
|
| - LEAK_CODE(SkDebugf(" string[%d]\n", gStringCount++);)
|
| - char* str = (char*)sk_malloc_throw(len + 1);
|
| - str[len] = 0;
|
| - return str;
|
| -}
|
| -
|
| -static char* dup_string(const char src[]) {
|
| - if (NULL == src) {
|
| - return NULL;
|
| - }
|
| - size_t len = strlen(src);
|
| - char* dst = alloc_string(len);
|
| - memcpy(dst, src, len);
|
| - return dst;
|
| -}
|
| -
|
| -static void free_string(char* str) {
|
| - if (str) {
|
| - sk_free(str);
|
| - LEAK_CODE(SkASSERT(gStringCount > 0); SkDebugf("~string[%d]\n", --gStringCount);)
|
| - }
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -struct SkJSON::Object::Slot {
|
| - Slot(const char name[], Type type) {
|
| - LEAK_CODE(SkDebugf(" slot[%d]\n", gSlotCount++);)
|
| - SkASSERT(name);
|
| -
|
| - fNext = NULL;
|
| -
|
| - size_t len = strlen(name);
|
| - // extra 1 for str[0] which stores the type
|
| - char* str = alloc_string(1 + len);
|
| - str[0] = (char)type;
|
| - // str[1] skips the type, len+1 includes the terminating 0 byte.
|
| - memcpy(&str[1], name, len + 1);
|
| - fName = str;
|
| -
|
| - // fValue is uninitialized
|
| - }
|
| - ~Slot();
|
| -
|
| - Type type() const { return (Type)fName[0]; }
|
| - const char* name() const { return &fName[1]; }
|
| -
|
| - Slot* fNext;
|
| - char* fName; // fName[0] is the type, &fName[1] is the "name"
|
| - union {
|
| - Object* fObject;
|
| - Array* fArray;
|
| - char* fString;
|
| - int32_t fInt;
|
| - float fFloat;
|
| - bool fBool;
|
| - } fValue;
|
| -};
|
| -
|
| -SkJSON::Object::Slot::~Slot() {
|
| - free_string(fName);
|
| - switch (this->type()) {
|
| - case kObject:
|
| - delete fValue.fObject;
|
| - break;
|
| - case kArray:
|
| - delete fValue.fArray;
|
| - break;
|
| - case kString:
|
| - free_string(fValue.fString);
|
| - break;
|
| - default:
|
| - break;
|
| - }
|
| - LEAK_CODE(SkASSERT(gSlotCount > 0); SkDebugf("~slot[%d]\n", --gSlotCount);)
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -SkJSON::Object::Iter::Iter(const Object& obj) : fSlot(obj.fHead) {}
|
| -
|
| -bool SkJSON::Object::Iter::done() const {
|
| - return NULL == fSlot;
|
| -}
|
| -
|
| -void SkJSON::Object::Iter::next() {
|
| - SkASSERT(fSlot);
|
| - fSlot = fSlot->fNext;
|
| -}
|
| -
|
| -SkJSON::Type SkJSON::Object::Iter::type() const {
|
| - SkASSERT(fSlot);
|
| - return fSlot->type();
|
| -}
|
| -
|
| -const char* SkJSON::Object::Iter::name() const {
|
| - SkASSERT(fSlot);
|
| - return fSlot->name();
|
| -}
|
| -
|
| -SkJSON::Object* SkJSON::Object::Iter::objectValue() const {
|
| - SkASSERT(fSlot);
|
| - SkASSERT(kObject == fSlot->type());
|
| - return fSlot->fValue.fObject;
|
| -}
|
| -
|
| -SkJSON::Array* SkJSON::Object::Iter::arrayValue() const {
|
| - SkASSERT(fSlot);
|
| - SkASSERT(kArray == fSlot->type());
|
| - return fSlot->fValue.fArray;
|
| -}
|
| -
|
| -const char* SkJSON::Object::Iter::stringValue() const {
|
| - SkASSERT(fSlot);
|
| - SkASSERT(kString == fSlot->type());
|
| - return fSlot->fValue.fString;
|
| -}
|
| -
|
| -int32_t SkJSON::Object::Iter::intValue() const {
|
| - SkASSERT(fSlot);
|
| - SkASSERT(kInt == fSlot->type());
|
| - return fSlot->fValue.fInt;
|
| -}
|
| -
|
| -float SkJSON::Object::Iter::floatValue() const {
|
| - SkASSERT(fSlot);
|
| - SkASSERT(kFloat == fSlot->type());
|
| - return fSlot->fValue.fFloat;
|
| -}
|
| -
|
| -bool SkJSON::Object::Iter::boolValue() const {
|
| - SkASSERT(fSlot);
|
| - SkASSERT(kBool == fSlot->type());
|
| - return fSlot->fValue.fBool;
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -SkJSON::Object::Object() : fHead(NULL), fTail(NULL) {
|
| - LEAK_CODE(SkDebugf(" object[%d]\n", gObjectCount++);)
|
| -}
|
| -
|
| -SkJSON::Object::Object(const Object& other) : fHead(NULL), fTail(NULL) {
|
| - LEAK_CODE(SkDebugf(" object[%d]\n", gObjectCount++);)
|
| -
|
| - Iter iter(other);
|
| - while (!iter.done()) {
|
| - switch (iter.type()) {
|
| - case kObject:
|
| - this->addObject(iter.name(), new Object(*iter.objectValue()));
|
| - break;
|
| - case kArray:
|
| - this->addArray(iter.name(), new Array(*iter.arrayValue()));
|
| - break;
|
| - case kString:
|
| - this->addString(iter.name(), dup_string(iter.stringValue()));
|
| - break;
|
| - case kInt:
|
| - this->addInt(iter.name(), iter.intValue());
|
| - break;
|
| - case kFloat:
|
| - this->addFloat(iter.name(), iter.floatValue());
|
| - break;
|
| - case kBool:
|
| - this->addBool(iter.name(), iter.boolValue());
|
| - break;
|
| - }
|
| - iter.next();
|
| - }
|
| -}
|
| -
|
| -SkJSON::Object::~Object() {
|
| - Slot* slot = fHead;
|
| - while (slot) {
|
| - Slot* next = slot->fNext;
|
| - delete slot;
|
| - slot = next;
|
| - }
|
| - LEAK_CODE(SkASSERT(gObjectCount > 0); SkDebugf("~object[%d]\n", --gObjectCount);)
|
| -}
|
| -
|
| -int SkJSON::Object::count() const {
|
| - int n = 0;
|
| - for (const Slot* slot = fHead; slot; slot = slot->fNext) {
|
| - n += 1;
|
| - }
|
| - return n;
|
| -}
|
| -
|
| -SkJSON::Object::Slot* SkJSON::Object::addSlot(Slot* slot) {
|
| - SkASSERT(NULL == slot->fNext);
|
| - if (NULL == fHead) {
|
| - SkASSERT(NULL == fTail);
|
| - fHead = fTail = slot;
|
| - } else {
|
| - SkASSERT(fTail);
|
| - SkASSERT(NULL == fTail->fNext);
|
| - fTail->fNext = slot;
|
| - fTail = slot;
|
| - }
|
| - return slot;
|
| -}
|
| -
|
| -void SkJSON::Object::addObject(const char name[], SkJSON::Object* value) {
|
| - this->addSlot(new Slot(name, kObject))->fValue.fObject = value;
|
| -}
|
| -
|
| -void SkJSON::Object::addArray(const char name[], SkJSON::Array* value) {
|
| - this->addSlot(new Slot(name, kArray))->fValue.fArray = value;
|
| -}
|
| -
|
| -void SkJSON::Object::addString(const char name[], const char value[]) {
|
| - this->addSlot(new Slot(name, kString))->fValue.fString = dup_string(value);
|
| -}
|
| -
|
| -void SkJSON::Object::addInt(const char name[], int32_t value) {
|
| - this->addSlot(new Slot(name, kInt))->fValue.fInt = value;
|
| -}
|
| -
|
| -void SkJSON::Object::addFloat(const char name[], float value) {
|
| - this->addSlot(new Slot(name, kFloat))->fValue.fFloat = value;
|
| -}
|
| -
|
| -void SkJSON::Object::addBool(const char name[], bool value) {
|
| - this->addSlot(new Slot(name, kBool))->fValue.fBool = value;
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -const SkJSON::Object::Slot* SkJSON::Object::findSlot(const char name[],
|
| - Type t) const {
|
| - for (const Slot* slot = fHead; slot; slot = slot->fNext) {
|
| - if (t == slot->type() && !strcmp(slot->name(), name)) {
|
| - return slot;
|
| - }
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
| -bool SkJSON::Object::find(const char name[], Type t) const {
|
| - return this->findSlot(name, t) != NULL;
|
| -}
|
| -
|
| -bool SkJSON::Object::findObject(const char name[], SkJSON::Object** value) const {
|
| - const Slot* slot = this->findSlot(name, kObject);
|
| - if (slot) {
|
| - if (value) {
|
| - *value = slot->fValue.fObject;
|
| - }
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool SkJSON::Object::findArray(const char name[], SkJSON::Array** value) const {
|
| - const Slot* slot = this->findSlot(name, kArray);
|
| - if (slot) {
|
| - if (value) {
|
| - *value = slot->fValue.fArray;
|
| - }
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool SkJSON::Object::findString(const char name[], SkString* value) const {
|
| - const Slot* slot = this->findSlot(name, kString);
|
| - if (slot) {
|
| - if (value) {
|
| - value->set(slot->fValue.fString);
|
| - }
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool SkJSON::Object::findInt(const char name[], int32_t* value) const {
|
| - const Slot* slot = this->findSlot(name, kInt);
|
| - if (slot) {
|
| - if (value) {
|
| - *value = slot->fValue.fInt;
|
| - }
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool SkJSON::Object::findFloat(const char name[], float* value) const {
|
| - const Slot* slot = this->findSlot(name, kFloat);
|
| - if (slot) {
|
| - if (value) {
|
| - *value = slot->fValue.fFloat;
|
| - }
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool SkJSON::Object::findBool(const char name[], bool* value) const {
|
| - const Slot* slot = this->findSlot(name, kBool);
|
| - if (slot) {
|
| - if (value) {
|
| - *value = slot->fValue.fBool;
|
| - }
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool SkJSON::Object::remove(const char name[], Type t) {
|
| - SkDEBUGCODE(int count = this->count();)
|
| - Slot* prev = NULL;
|
| - Slot* slot = fHead;
|
| - while (slot) {
|
| - Slot* next = slot->fNext;
|
| - if (t == slot->type() && !strcmp(slot->name(), name)) {
|
| - if (prev) {
|
| - SkASSERT(fHead != slot);
|
| - prev->fNext = next;
|
| - } else {
|
| - SkASSERT(fHead == slot);
|
| - fHead = next;
|
| - }
|
| - if (fTail == slot) {
|
| - fTail = prev;
|
| - }
|
| - delete slot;
|
| - SkASSERT(count - 1 == this->count());
|
| - return true;
|
| - }
|
| - prev = slot;
|
| - slot = next;
|
| - }
|
| - SkASSERT(count == this->count());
|
| - return false;
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -static void tabForLevel(int level) {
|
| - for (int i = 0; i < level; ++i) {
|
| - SkDebugf(" ");
|
| - }
|
| -}
|
| -
|
| -void SkJSON::Object::toDebugf() const {
|
| - SkDebugf("{\n");
|
| - this->dumpLevel(0);
|
| - SkDebugf("}\n");
|
| -}
|
| -
|
| -void SkJSON::Object::dumpLevel(int level) const {
|
| - for (Slot* slot = fHead; slot; slot = slot->fNext) {
|
| - Type t = slot->type();
|
| - tabForLevel(level + 1);
|
| - SkDebugf("\"%s\" : ", slot->name());
|
| - switch (slot->type()) {
|
| - case kObject:
|
| - if (slot->fValue.fObject) {
|
| - SkDebugf("{\n");
|
| - slot->fValue.fObject->dumpLevel(level + 1);
|
| - tabForLevel(level + 1);
|
| - SkDebugf("}");
|
| - } else {
|
| - SkDebugf("null");
|
| - }
|
| - break;
|
| - case kArray:
|
| - if (slot->fValue.fArray) {
|
| - SkDebugf("[");
|
| - slot->fValue.fArray->dumpLevel(level + 1);
|
| - SkDebugf("]");
|
| - } else {
|
| - SkDebugf("null");
|
| - }
|
| - break;
|
| - case kString:
|
| - SkDebugf("\"%s\"", slot->fValue.fString);
|
| - break;
|
| - case kInt:
|
| - SkDebugf("%d", slot->fValue.fInt);
|
| - break;
|
| - case kFloat:
|
| - SkDebugf("%g", slot->fValue.fFloat);
|
| - break;
|
| - case kBool:
|
| - SkDebugf("%s", slot->fValue.fBool ? "true" : "false");
|
| - break;
|
| - default:
|
| - SkDEBUGFAIL("how did I get here");
|
| - break;
|
| - }
|
| - if (slot->fNext) {
|
| - SkDebugf(",");
|
| - }
|
| - SkDebugf("\n");
|
| - }
|
| -}
|
| -
|
| -void SkJSON::Array::dumpLevel(int level) const {
|
| - if (0 == fCount) {
|
| - return;
|
| - }
|
| - int last = fCount - 1;
|
| -
|
| - switch (this->type()) {
|
| - case kObject: {
|
| - SkDebugf("\n");
|
| - for (int i = 0; i <= last; ++i) {
|
| - Object* obj = fArray.fObjects[i];
|
| - tabForLevel(level + 1);
|
| - if (obj) {
|
| - SkDebugf("{\n");
|
| - obj->dumpLevel(level + 1);
|
| - tabForLevel(level + 1);
|
| - SkDebugf(i < last ? "}," : "}");
|
| - } else {
|
| - SkDebugf(i < last ? "null," : "null");
|
| - }
|
| - SkDebugf("\n");
|
| - }
|
| - } break;
|
| - case kArray: {
|
| - SkDebugf("\n");
|
| - for (int i = 0; i <= last; ++i) {
|
| - Array* array = fArray.fArrays[i];
|
| - tabForLevel(level + 1);
|
| - if (array) {
|
| - SkDebugf("[");
|
| - array->dumpLevel(level + 1);
|
| - tabForLevel(level + 1);
|
| - SkDebugf(i < last ? "]," : "]");
|
| - } else {
|
| - SkDebugf(i < last ? "null," : "null");
|
| - }
|
| - SkDebugf("\n");
|
| - }
|
| - } break;
|
| - case kString: {
|
| - for (int i = 0; i < last; ++i) {
|
| - const char* str = fArray.fStrings[i];
|
| - SkDebugf(str ? " \"%s\"," : " null,", str);
|
| - }
|
| - const char* str = fArray.fStrings[last];
|
| - SkDebugf(str ? " \"%s\" " : " null ", str);
|
| - } break;
|
| - case kInt: {
|
| - for (int i = 0; i < last; ++i) {
|
| - SkDebugf(" %d,", fArray.fInts[i]);
|
| - }
|
| - SkDebugf(" %d ", fArray.fInts[last]);
|
| - } break;
|
| - case kFloat: {
|
| - for (int i = 0; i < last; ++i) {
|
| - SkDebugf(" %g,", fArray.fFloats[i]);
|
| - }
|
| - SkDebugf(" %g ", fArray.fFloats[last]);
|
| - } break;
|
| - case kBool: {
|
| - for (int i = 0; i < last; ++i) {
|
| - SkDebugf(" %s,", fArray.fBools[i] ? "true" : "false");
|
| - }
|
| - SkDebugf(" %s ", fArray.fInts[last] ? "true" : "false");
|
| - } break;
|
| - default:
|
| - SkDEBUGFAIL("unsupported array type");
|
| - break;
|
| - }
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////
|
| -
|
| -static const uint8_t gBytesPerType[] = {
|
| - sizeof(SkJSON::Object*),
|
| - sizeof(SkJSON::Array*),
|
| - sizeof(char*),
|
| - sizeof(int32_t),
|
| - sizeof(float),
|
| - sizeof(bool)
|
| -};
|
| -
|
| -typedef void* (*DupProc)(const void*);
|
| -
|
| -static void* dup_object(const void* src) {
|
| - return SkNEW_ARGS(SkJSON::Object, (*(SkJSON::Object*)src));
|
| -}
|
| -
|
| -static void* dup_array(const void* src) {
|
| - return SkNEW_ARGS(SkJSON::Array, (*(SkJSON::Array*)src));
|
| -}
|
| -
|
| -static const DupProc gDupProcs[] = {
|
| - dup_object, // Object
|
| - dup_array, // Array
|
| - (DupProc)dup_string, // String
|
| - NULL, // int
|
| - NULL, // float
|
| - NULL, // bool
|
| -};
|
| -
|
| -void SkJSON::Array::init(Type type, int count, const void* src) {
|
| - LEAK_CODE(SkDebugf(" array[%d]\n", gArrayCount++);)
|
| -
|
| - SkASSERT((unsigned)type < SK_ARRAY_COUNT(gBytesPerType));
|
| -
|
| - if (count < 0) {
|
| - count = 0;
|
| - }
|
| - size_t size = count * gBytesPerType[type];
|
| -
|
| - fCount = count;
|
| - fType = type;
|
| - fArray.fVoids = sk_malloc_throw(size);
|
| - if (src) {
|
| - DupProc proc = gDupProcs[fType];
|
| - if (!proc) {
|
| - memcpy(fArray.fVoids, src, size);
|
| - } else {
|
| - void** srcPtr = (void**)src;
|
| - void** dstPtr = (void**)fArray.fVoids;
|
| - for (int i = 0; i < fCount; ++i) {
|
| - dstPtr[i] = proc(srcPtr[i]);
|
| - }
|
| - }
|
| - } else {
|
| - sk_bzero(fArray.fVoids, size);
|
| - }
|
| -}
|
| -
|
| -SkJSON::Array::Array(Type type, int count) {
|
| - this->init(type, count, NULL);
|
| -}
|
| -
|
| -SkJSON::Array::Array(const int32_t values[], int count) {
|
| - this->init(kInt, count, values);
|
| -}
|
| -
|
| -SkJSON::Array::Array(const float values[], int count) {
|
| - this->init(kFloat, count, values);
|
| -}
|
| -
|
| -SkJSON::Array::Array(const bool values[], int count) {
|
| - this->init(kBool, count, values);
|
| -}
|
| -
|
| -SkJSON::Array::Array(const Array& other) {
|
| - this->init(other.type(), other.count(), other.fArray.fVoids);
|
| -}
|
| -
|
| -typedef void (*FreeProc)(void*);
|
| -
|
| -static void free_object(void* obj) {
|
| - delete (SkJSON::Object*)obj;
|
| -}
|
| -
|
| -static void free_array(void* array) {
|
| - delete (SkJSON::Array*)array;
|
| -}
|
| -
|
| -static const FreeProc gFreeProcs[] = {
|
| - free_object, // Object
|
| - free_array, // Array
|
| - (FreeProc)free_string, // String
|
| - NULL, // int
|
| - NULL, // float
|
| - NULL, // bool
|
| -};
|
| -
|
| -SkJSON::Array::~Array() {
|
| - FreeProc proc = gFreeProcs[fType];
|
| - if (proc) {
|
| - void** ptr = (void**)fArray.fVoids;
|
| - for (int i = 0; i < fCount; ++i) {
|
| - proc(ptr[i]);
|
| - }
|
| - }
|
| - sk_free(fArray.fVoids);
|
| -
|
| - LEAK_CODE(SkASSERT(gArrayCount > 0); SkDebugf("~array[%d]\n", --gArrayCount);)
|
| -}
|
| -
|
| -void SkJSON::Array::setObject(int index, Object* object) {
|
| - SkASSERT((unsigned)index < (unsigned)fCount);
|
| - Object*& prev = fArray.fObjects[index];
|
| - if (prev != object) {
|
| - delete prev;
|
| - prev = object;
|
| - }
|
| -}
|
| -
|
| -void SkJSON::Array::setArray(int index, Array* array) {
|
| - SkASSERT((unsigned)index < (unsigned)fCount);
|
| - Array*& prev = fArray.fArrays[index];
|
| - if (prev != array) {
|
| - delete prev;
|
| - prev = array;
|
| - }
|
| -}
|
| -
|
| -void SkJSON::Array::setString(int index, const char str[]) {
|
| - SkASSERT((unsigned)index < (unsigned)fCount);
|
| - char*& prev = fArray.fStrings[index];
|
| - if (prev != str) {
|
| - free_string(prev);
|
| - prev = dup_string(str);
|
| - }
|
| -}
|
|
|