1 /*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "GrAuditTrail.h"
9
JsonifyTArray(SkString * json,const char * name,const FrameArray & array,bool addComma)10 void GrAuditTrail::JsonifyTArray(SkString* json, const char* name, const FrameArray& array,
11 bool addComma) {
12 if (array.count()) {
13 if (addComma) {
14 json->appendf(",");
15 }
16 json->appendf("\"%s\": [", name);
17 for (int i = 0; i < array.count(); i++) {
18 json->append(array[i]->toJson());
19 if (i < array.count() - 1) {
20 json->append(",");
21 }
22 }
23 json->append("]");
24 }
25 }
26
27 // This will pretty print a very small subset of json
28 // The parsing rules are straightforward, aside from the fact that we do not want an extra newline
29 // before ',' and after '}', so we have a comma exception rule.
30 class PrettyPrintJson {
31 public:
prettify(const SkString & json)32 SkString prettify(const SkString& json) {
33 fPrettyJson.reset();
34 fTabCount = 0;
35 fFreshLine = false;
36 fCommaException = false;
37 for (size_t i = 0; i < json.size(); i++) {
38 if ('[' == json[i] || '{' == json[i]) {
39 this->newline();
40 this->appendChar(json[i]);
41 fTabCount++;
42 this->newline();
43 } else if (']' == json[i] || '}' == json[i]) {
44 fTabCount--;
45 this->newline();
46 this->appendChar(json[i]);
47 fCommaException = true;
48 } else if (',' == json[i]) {
49 this->appendChar(json[i]);
50 this->newline();
51 } else {
52 this->appendChar(json[i]);
53 }
54 }
55 return fPrettyJson;
56 }
57 private:
appendChar(char appendee)58 void appendChar(char appendee) {
59 if (fCommaException && ',' != appendee) {
60 this->newline();
61 }
62 this->tab();
63 fPrettyJson += appendee;
64 fFreshLine = false;
65 fCommaException = false;
66 }
67
tab()68 void tab() {
69 if (fFreshLine) {
70 for (int i = 0; i < fTabCount; i++) {
71 fPrettyJson += '\t';
72 }
73 }
74 }
75
newline()76 void newline() {
77 if (!fFreshLine) {
78 fFreshLine = true;
79 fPrettyJson += '\n';
80 }
81 }
82
83 SkString fPrettyJson;
84 int fTabCount;
85 bool fFreshLine;
86 bool fCommaException;
87 };
88
pretty_print_json(SkString json)89 static SkString pretty_print_json(SkString json) {
90 class PrettyPrintJson prettyPrintJson;
91 return prettyPrintJson.prettify(json);
92 }
93
toJson(bool prettyPrint) const94 SkString GrAuditTrail::toJson(bool prettyPrint) const {
95 SkString json;
96 json.append("{");
97 JsonifyTArray(&json, "Stacks", fFrames, false);
98 json.append("}");
99
100 if (prettyPrint) {
101 return pretty_print_json(json);
102 } else {
103 return json;
104 }
105 }
106
toJson() const107 SkString GrAuditTrail::Frame::toJson() const {
108 SkString json;
109 json.append("{");
110 json.appendf("\"Name\": \"%s\"", fName);
111 JsonifyTArray(&json, "Frames", fChildren, true);
112 json.append("}");
113 return json;
114 }
115
toJson() const116 SkString GrAuditTrail::Batch::toJson() const {
117 SkString json;
118 json.append("{");
119 json.appendf("\"Name\": \"%s\",", fName);
120 json.append("\"Bounds\": {");
121 json.appendf("\"Left\": %f,", fBounds.fLeft);
122 json.appendf("\"Right\": %f,", fBounds.fRight);
123 json.appendf("\"Top\": %f,", fBounds.fTop);
124 json.appendf("\"Bottom\": %f", fBounds.fBottom);
125 json.append("}");
126 json.append("}");
127 return json;
128 }
129