127a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt/* 227a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt * Copyright 2016 Google Inc. 327a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt * 427a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt * Use of this source code is governed by a BSD-style license that can be 527a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt * found in the LICENSE file. 627a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt */ 727a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt 827a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt#include "GrAuditTrail.h" 927a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt 10adab5a2a4b2ae4d7fa832093fe81a640e848746cjoshualittvoid GrAuditTrail::JsonifyTArray(SkString* json, const char* name, const FrameArray& array, 11adab5a2a4b2ae4d7fa832093fe81a640e848746cjoshualitt bool addComma) { 1287a721b2465c9ccfa191ce9f5012f92be7731fbcjoshualitt if (array.count()) { 13adab5a2a4b2ae4d7fa832093fe81a640e848746cjoshualitt if (addComma) { 14adab5a2a4b2ae4d7fa832093fe81a640e848746cjoshualitt json->appendf(","); 15adab5a2a4b2ae4d7fa832093fe81a640e848746cjoshualitt } 1687a721b2465c9ccfa191ce9f5012f92be7731fbcjoshualitt json->appendf("\"%s\": [", name); 1787a721b2465c9ccfa191ce9f5012f92be7731fbcjoshualitt for (int i = 0; i < array.count(); i++) { 1811fae87d39811882e3e99b4abc72c9713a38da55joshualitt json->append(array[i]->toJson()); 1987a721b2465c9ccfa191ce9f5012f92be7731fbcjoshualitt if (i < array.count() - 1) { 2087a721b2465c9ccfa191ce9f5012f92be7731fbcjoshualitt json->append(","); 2187a721b2465c9ccfa191ce9f5012f92be7731fbcjoshualitt } 2227a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt } 2387a721b2465c9ccfa191ce9f5012f92be7731fbcjoshualitt json->append("]"); 2427a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt } 25086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt} 26086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt 27086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt// This will pretty print a very small subset of json 28086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt// The parsing rules are straightforward, aside from the fact that we do not want an extra newline 29086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt// before ',' and after '}', so we have a comma exception rule. 30086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualittclass PrettyPrintJson { 31086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualittpublic: 32086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt SkString prettify(const SkString& json) { 33086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt fPrettyJson.reset(); 34086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt fTabCount = 0; 35086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt fFreshLine = false; 36086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt fCommaException = false; 37086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt for (size_t i = 0; i < json.size(); i++) { 38086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt if ('[' == json[i] || '{' == json[i]) { 39086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt this->newline(); 40086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt this->appendChar(json[i]); 41086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt fTabCount++; 42086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt this->newline(); 43086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt } else if (']' == json[i] || '}' == json[i]) { 44086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt fTabCount--; 45086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt this->newline(); 46086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt this->appendChar(json[i]); 47086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt fCommaException = true; 48086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt } else if (',' == json[i]) { 49086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt this->appendChar(json[i]); 50086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt this->newline(); 51086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt } else { 52086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt this->appendChar(json[i]); 53086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt } 54086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt } 55086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt return fPrettyJson; 56086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt } 57086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualittprivate: 58086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt void appendChar(char appendee) { 59086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt if (fCommaException && ',' != appendee) { 60086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt this->newline(); 61086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt } 62086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt this->tab(); 63086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt fPrettyJson += appendee; 64086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt fFreshLine = false; 65086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt fCommaException = false; 66086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt } 67086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt 68086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt void tab() { 69086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt if (fFreshLine) { 70086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt for (int i = 0; i < fTabCount; i++) { 71086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt fPrettyJson += '\t'; 72086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt } 73086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt } 74086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt } 75086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt 76086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt void newline() { 77086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt if (!fFreshLine) { 78086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt fFreshLine = true; 79086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt fPrettyJson += '\n'; 80086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt } 81086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt } 82086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt 83086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt SkString fPrettyJson; 84086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt int fTabCount; 85086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt bool fFreshLine; 86086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt bool fCommaException; 87086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt}; 88086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt 89086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualittstatic SkString pretty_print_json(SkString json) { 90086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt class PrettyPrintJson prettyPrintJson; 91086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt return prettyPrintJson.prettify(json); 92086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt} 93086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt 946b3cf73af525fdbf6fd093304db840bb998e3dd6joshualittSkString GrAuditTrail::toJson(bool prettyPrint) const { 95086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt SkString json; 96086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt json.append("{"); 97adab5a2a4b2ae4d7fa832093fe81a640e848746cjoshualitt JsonifyTArray(&json, "Stacks", fFrames, false); 98086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt json.append("}"); 99086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt 1006b3cf73af525fdbf6fd093304db840bb998e3dd6joshualitt if (prettyPrint) { 1016b3cf73af525fdbf6fd093304db840bb998e3dd6joshualitt return pretty_print_json(json); 1026b3cf73af525fdbf6fd093304db840bb998e3dd6joshualitt } else { 1036b3cf73af525fdbf6fd093304db840bb998e3dd6joshualitt return json; 1046b3cf73af525fdbf6fd093304db840bb998e3dd6joshualitt } 10527a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt} 10627a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt 10787a721b2465c9ccfa191ce9f5012f92be7731fbcjoshualittSkString GrAuditTrail::Frame::toJson() const { 10827a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt SkString json; 109086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt json.append("{"); 110adab5a2a4b2ae4d7fa832093fe81a640e848746cjoshualitt json.appendf("\"Name\": \"%s\"", fName); 111adab5a2a4b2ae4d7fa832093fe81a640e848746cjoshualitt JsonifyTArray(&json, "Frames", fChildren, true); 112086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt json.append("}"); 11327a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt return json; 11427a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt} 11527a48dc0cddad7f3531dcf0d39d290e7233e3e76joshualitt 11611fae87d39811882e3e99b4abc72c9713a38da55joshualittSkString GrAuditTrail::Batch::toJson() const { 117086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt SkString json; 118086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt json.append("{"); 11987a721b2465c9ccfa191ce9f5012f92be7731fbcjoshualitt json.appendf("\"Name\": \"%s\",", fName); 120086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt json.append("\"Bounds\": {"); 121086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt json.appendf("\"Left\": %f,", fBounds.fLeft); 122086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt json.appendf("\"Right\": %f,", fBounds.fRight); 123086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt json.appendf("\"Top\": %f,", fBounds.fTop); 124086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt json.appendf("\"Bottom\": %f", fBounds.fBottom); 125086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt json.append("}"); 126086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt json.append("}"); 127086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt return json; 128086cee12deaf9a9f46bbd2e52173e0e4fc4df311joshualitt} 129