Convert bookmaker to SkJSON
Verified that running bookmaker produces an identical fiddle.json
before and after this change.
Bug: skia:
Change-Id: I1aa7477348a5f8c362201199b130508c2818116f
Reviewed-on: https://skia-review.googlesource.com/c/188303
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 7e98378..497587b 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1698,7 +1698,6 @@
":flags",
":skia",
":tool_utils",
- "//third_party/jsoncpp",
]
}
diff --git a/tools/bookmaker/cataloger.cpp b/tools/bookmaker/cataloger.cpp
index cad7505..6156fcb 100644
--- a/tools/bookmaker/cataloger.cpp
+++ b/tools/bookmaker/cataloger.cpp
@@ -105,7 +105,7 @@
fTextOut = false;
fPngOut = true;
JsonStatus* status = &fStack.back();
- status->fIter = status->fObject.begin();
+ status->reset();
fContinuation = false;
return parseFiddles();
}
diff --git a/tools/bookmaker/fiddleParser.cpp b/tools/bookmaker/fiddleParser.cpp
index 79c4a70..8e8eb0f5 100644
--- a/tools/bookmaker/fiddleParser.cpp
+++ b/tools/bookmaker/fiddleParser.cpp
@@ -24,52 +24,55 @@
return false;
}
JsonStatus* status = &fStack.back();
- while (status->fIter != status->fObject.end()) {
- const char* blockName = status->fIter.memberName();
+ while (!status->atEnd()) {
+ const char* blockName = status->fObjectIter->fKey.begin();
Definition* example = nullptr;
string textString;
- if (!status->fObject.isObject()) {
+ if (!status->fObject) {
return report_error(blockName, "expected object");
}
- for (auto iter = status->fIter->begin(); status->fIter->end() != iter; ++iter) {
- const char* memberName = iter.memberName();
+ const skjson::ObjectValue* obj = status->fObjectIter->fValue;
+ for (auto iter = obj->begin(); obj->end() != iter; ++iter) {
+ const char* memberName = iter->fKey.begin();
if (!strcmp("compile_errors", memberName)) {
- if (!iter->isArray()) {
+ if (!iter->fValue.is<skjson::ArrayValue>()) {
return report_error(blockName, "expected array");
}
- if (iter->size()) {
+ if (iter->fValue.as<skjson::ArrayValue>().size()) {
return report_error(blockName, "fiddle compiler error");
}
continue;
}
if (!strcmp("runtime_error", memberName)) {
- if (!iter->isString()) {
+ if (!iter->fValue.is<skjson::StringValue>()) {
return report_error(blockName, "expected string 1");
}
- if (iter->asString().length()) {
+ if (iter->fValue.as<skjson::StringValue>().size()) {
return report_error(blockName, "fiddle runtime error");
}
continue;
}
if (!strcmp("fiddleHash", memberName)) {
- if (!iter->isString()) {
+ const skjson::StringValue* sv = iter->fValue;
+ if (!sv) {
return report_error(blockName, "expected string 2");
}
example = this->findExample(blockName);
if (!example) {
return report_error(blockName, "missing example");
}
- if (example->fHash.length() && example->fHash != iter->asString()) {
+ if (example->fHash.length() && example->fHash != sv->begin()) {
return example->reportError<bool>("mismatched hash");
}
- example->fHash = iter->asString();
+ example->fHash = sv->begin();
continue;
}
if (!strcmp("text", memberName)) {
- if (!iter->isString()) {
+ const skjson::StringValue* sv = iter->fValue;
+ if (!sv) {
return report_error(blockName, "expected string 3");
}
- textString = iter->asString();
+ textString = sv->begin();
continue;
}
return report_error(blockName, "unexpected key");
@@ -86,7 +89,7 @@
} else if (fPngOut && !this->pngOut(example)) {
return false;
}
- status->fIter++;
+ status->advance();
}
return true;
}
diff --git a/tools/bookmaker/includeParser.cpp b/tools/bookmaker/includeParser.cpp
index 73a8015..48e7c5f 100644
--- a/tools/bookmaker/includeParser.cpp
+++ b/tools/bookmaker/includeParser.cpp
@@ -10,6 +10,7 @@
#include "bmhParser.h"
#include "includeParser.h"
+#include <map>
const IncludeKey kKeyWords[] = {
{ "", KeyWord::kNone, KeyProperty::kNone },
diff --git a/tools/bookmaker/mdOut.cpp b/tools/bookmaker/mdOut.cpp
index 3e16b06..366135f 100644
--- a/tools/bookmaker/mdOut.cpp
+++ b/tools/bookmaker/mdOut.cpp
@@ -11,6 +11,7 @@
#include "SkOSFile.h"
#include "SkOSPath.h"
+#include <map>
class SubtopicKeys {
public:
diff --git a/tools/bookmaker/parserCommon.cpp b/tools/bookmaker/parserCommon.cpp
index 271551b..5a8867a 100644
--- a/tools/bookmaker/parserCommon.cpp
+++ b/tools/bookmaker/parserCommon.cpp
@@ -414,7 +414,7 @@
};
string StatusIter::baseDir() {
- SkASSERT(fStack.back().fObject.isArray());
+ SkASSERT(fStack.back().fArray);
SkASSERT(fStack.size() > 2);
string dir;
for (unsigned index = 2; index < fStack.size(); ++index) {
@@ -438,7 +438,7 @@
return false;
}
status = &fStack.back();
- if (status->fIter != status->fObject.end()) {
+ if (!status->atEnd()) {
break;
}
fStack.pop_back();
@@ -446,8 +446,9 @@
if (1 == fStack.size()) {
do {
blockType = StatusFilter::kUnknown;
+ SkASSERT(status->fObject);
for (unsigned index = 0; index < SK_ARRAY_COUNT(block_names); ++index) {
- if (status->fIter.key().asString() == block_names[index]) {
+ if (!strcmp(status->fObjectIter->fKey.begin(), block_names[index])) {
blockType = (StatusFilter) index;
break;
}
@@ -455,34 +456,35 @@
if (blockType <= fFilter) {
break;
}
- status->fIter++;
- } while (status->fIter != status->fObject.end());
- if (status->fIter == status->fObject.end()) {
+ status->advance();
+ } while (!status->atEnd());
+ if (status->atEnd()) {
continue;
}
}
- if (!status->fObject.isArray()) {
- SkASSERT(status->fIter != status->fObject.end());
- JsonStatus block = {
- *status->fIter,
- status->fIter->begin(),
- status->fIter.key().asString(),
- blockType
- };
+ if (!status->fArray) {
+ SkASSERT(status->fObjectIter != status->fObject->end());
+ JsonStatus block = JsonStatus::Make(status->current(),
+ status->fObjectIter->fKey.begin(),
+ blockType);
fStack.emplace_back(block);
status = &(&fStack.back())[-1];
- status->fIter++;
+ status->advance();
status = &fStack.back();
continue;
}
- str = status->fIter->asString();
+ if (const skjson::StringValue* sv = status->current()) {
+ str = sv->begin();
+ } else {
+ str = status->current().toString().c_str();
+ }
if (strPtr) {
*strPtr = str;
}
if (filter) {
*filter = status->fStatusFilter;
}
- status->fIter++;
+ status->advance();
if (str.length() - strlen(fSuffix) == str.find(fSuffix)) {
return true;
}
@@ -496,14 +498,12 @@
SkDebugf("file %s:\n", path);
return this->reportError<bool>("file not readable");
}
- Json::Reader reader;
- const char* data = (const char*)json->data();
- if (!reader.parse(data, data + json->size(), fRoot)) {
+ fDom.reset(new skjson::DOM((const char*)json->data(), json->size()));
+ if (!fDom->root().is<skjson::ObjectValue>()) {
SkDebugf("file %s:\n", path);
return this->reportError<bool>("file not parsable");
}
- JsonStatus block = { fRoot, fRoot.begin(), "", StatusFilter::kUnknown };
+ JsonStatus block = JsonStatus::Make(fDom->root(), "", StatusFilter::kUnknown);
fStack.emplace_back(block);
return true;
}
-
diff --git a/tools/bookmaker/parserCommon.h b/tools/bookmaker/parserCommon.h
index f31cbd6..ecf5c2f 100644
--- a/tools/bookmaker/parserCommon.h
+++ b/tools/bookmaker/parserCommon.h
@@ -9,11 +9,13 @@
#define parserCommon_DEFINED
#include "SkData.h"
-#include "SkJSONCPP.h"
+#include "SkJSON.h"
#include "definition.h"
#include "textParser.h"
+#include <memory>
+
enum class StatusFilter {
kCompleted,
kInProgress,
@@ -255,10 +257,50 @@
};
struct JsonStatus {
- const Json::Value& fObject;
- Json::Value::iterator fIter;
+ const skjson::ArrayValue* fArray;
+ const skjson::Value* fArrayIter;
+ const skjson::ObjectValue* fObject;
+ const skjson::Member* fObjectIter;
string fName;
StatusFilter fStatusFilter;
+
+ static JsonStatus Make(const skjson::Value& value, string name, StatusFilter filter) {
+ JsonStatus status = { value, nullptr, value, nullptr, name, filter };
+ status.reset();
+ return status;
+ }
+
+ void reset() {
+ fArrayIter = fArray ? fArray->begin() : nullptr;
+ fObjectIter = fObject ? fObject->begin() : nullptr;
+ }
+
+ bool atEnd() const {
+ if (fArray) {
+ return fArrayIter == fArray->end();
+ } else if (fObject) {
+ return fObjectIter == fObject->end();
+ } else {
+ return true;
+ }
+ }
+
+ void advance() {
+ if (fArrayIter) {
+ fArrayIter++;
+ } else if (fObjectIter) {
+ fObjectIter++;
+ }
+ }
+
+ const skjson::Value& current() const {
+ if (fArrayIter) {
+ return *fArrayIter;
+ } else {
+ SkASSERT(fObjectIter);
+ return fObjectIter->fValue;
+ }
+ }
};
class JsonCommon : public ParserCommon {
@@ -272,7 +314,7 @@
}
vector<JsonStatus> fStack;
- Json::Value fRoot;
+ std::unique_ptr<skjson::DOM> fDom;
private:
typedef ParserCommon INHERITED;
};