• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <cstdint>
31 #include <stack>
32 #include <string>
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 + "\": \"" + escape(value) + "\"";
83     }
AddStringJsonWriter84     void AddString(std::string const& value) {
85         CommaAndNewLine();
86         Indent();
87         output += "\"" + escape(value) + "\"";
88     }
89 #if defined(WIN32)
AddKeyedStringJsonWriter90     void AddKeyedString(std::string const& key, std::wstring const& value) {
91         CommaAndNewLine();
92         Indent();
93         output += "\"" + key + "\": \"" + escape(narrow(value)) + "\"";
94     }
AddStringJsonWriter95     void AddString(std::wstring const& value) {
96         CommaAndNewLine();
97         Indent();
98         output += "\"" + escape(narrow(value)) + "\"";
99     }
100 #endif
101 
AddKeyedBoolJsonWriter102     void AddKeyedBool(std::string const& key, bool value) {
103         CommaAndNewLine();
104         Indent();
105         output += "\"" + key + "\": " + (value ? "true" : "false");
106     }
AddBoolJsonWriter107     void AddBool(bool value) {
108         CommaAndNewLine();
109         Indent();
110         output += std::string(value ? "true" : "false");
111     }
112 
113     // Json doesn't allow `\` in strings, it must be escaped. Thus we have to convert '\\' to '\\\\' in strings
escapeJsonWriter114     static std::string escape(std::string const& in_path) {
115         std::string out;
116         for (auto& c : in_path) {
117             if (c == '\\')
118                 out += "\\\\";
119             else
120                 out += c;
121         }
122         return out;
123     }
escapeJsonWriter124     static std::string escape(std::filesystem::path const& in_path) { return escape(narrow(in_path.native())); }
125 
126    private:
CommaAndNewLineJsonWriter127     void CommaAndNewLine() {
128         if (stack.size() > 0) {
129             if (stack.top() == false) {
130                 stack.top() = true;
131             } else {
132                 output += ",";
133             }
134             output += "\n";
135         }
136     }
IndentJsonWriter137     void Indent() {
138         for (uint32_t i = 0; i < stack.size(); i++) {
139             output += '\t';
140         }
141     }
142 };
143