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); |
- } |
-} |