1 /*
2  * Copyright (c) 2023 The Khronos Group Inc.
3  * Copyright (c) 2023 Valve Corporation
4  * Copyright (c) 2023 LunarG, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and/or associated documentation files (the "Materials"), to
8  * deal in the Materials without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Materials, and to permit persons to whom the Materials are
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice(s) and this permission notice shall be included in
14  * all copies or substantial portions of the Materials.
15  *
16  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  *
20  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
23  * USE OR OTHER DEALINGS IN THE MATERIALS.
24  *
25  * Author: Charles Giessen <charles@lunarg.com>
26  */
27 
28 #pragma once
29 
30 #include <stack>
31 #include <string>
32 #include <utility>
33 
34 // Utility class to simplify the writing of JSON manifest files
35 
36 struct JsonWriter {
37     std::string output;
38 
39     // the bool represents whether an object has been written & a comma is needed
40     std::stack<bool> stack;
41 
StartObjectJsonWriter42     void StartObject() {
43         CommaAndNewLine();
44         Indent();
45         output += "{";
46         stack.push(false);
47     }
StartKeyedObjectJsonWriter48     void StartKeyedObject(std::string const& key) {
49         CommaAndNewLine();
50         Indent();
51         output += "\"" + key + "\": {";
52         stack.push(false);
53     }
EndObjectJsonWriter54     void EndObject() {
55         stack.pop();
56         output += "\n";
57         Indent();
58         output += "}";
59     }
StartKeyedArrayJsonWriter60     void StartKeyedArray(std::string const& key) {
61         CommaAndNewLine();
62         Indent();
63         output += "\"" + key + "\": [";
64         stack.push(false);
65     }
StartArrayJsonWriter66     void StartArray() {
67         CommaAndNewLine();
68         Indent();
69         output += "[";
70         stack.push(false);
71     }
EndArrayJsonWriter72     void EndArray() {
73         stack.pop();
74         output += "\n";
75         Indent();
76         output += "]";
77     }
78 
AddKeyedStringJsonWriter79     void AddKeyedString(std::string const& key, std::string const& value) {
80         CommaAndNewLine();
81         Indent();
82         output += "\"" + key + "\": \"" + value + "\"";
83     }
AddStringJsonWriter84     void AddString(std::string const& value) {
85         CommaAndNewLine();
86         Indent();
87         output += "\"" + value + "\"";
88     }
89 
AddKeyedBoolJsonWriter90     void AddKeyedBool(std::string const& key, bool value) {
91         CommaAndNewLine();
92         Indent();
93         output += "\"" + key + "\": " + (value ? "true" : "false");
94     }
AddBoolJsonWriter95     void AddBool(bool value) {
96         CommaAndNewLine();
97         Indent();
98         output += std::string(value ? "true" : "false");
99     }
100 
101    private:
CommaAndNewLineJsonWriter102     void CommaAndNewLine() {
103         if (stack.size() > 0) {
104             if (stack.top() == false) {
105                 stack.top() = true;
106             } else {
107                 output += ",";
108             }
109             output += "\n";
110         }
111     }
IndentJsonWriter112     void Indent() {
113         for (uint32_t i = 0; i < stack.size(); i++) {
114             output += '\t';
115         }
116     }
117 };
118