]> git.cworth.org Git - apitrace/blob - json.hpp
Fix json output.
[apitrace] / json.hpp
1 /**************************************************************************
2  *
3  * Copyright 2011 Jose Fonseca
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS 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. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 /*
27  * Trace writing functions.
28  */
29
30 #ifndef _JSON_HPP_
31 #define _JSON_HPP_
32
33 #include <assert.h>
34 #include <stddef.h>
35
36 #include <ostream>
37
38
39 class JSONWriter
40 {
41 private:
42     std::ostream &os;
43
44     int level;
45     bool value;
46
47     void newline(void) {
48         os << "\n";
49         for (int i = 0; i < level; ++i) 
50             os << "  ";
51     }
52
53     void separator(void) {
54         if (value) {
55             os << ",";
56         }
57     }
58
59     void escapeString(const char *str) {
60         const unsigned char *p = (const unsigned char *)str;
61         os << "\"";
62         unsigned char c;
63         while ((c = *p++) != 0) {
64             if (c == '\"')
65                 os << "\\\"";
66             else if (c == '\\')
67                 os << "\\\\";
68             else if (c >= 0x20 && c <= 0x7e)
69                 os << c;
70             else if (c == '\t')
71                 os << "\t";
72             else if (c == '\r')
73                 os << "\r";
74             else if (c == '\n')
75                 os << "\n";
76             else {
77                 unsigned octal0 = c & 0x7;
78                 unsigned octal1 = (c >> 3) & 0x7;
79                 unsigned octal2 = (c >> 3) & 0x7;
80                 os << "\\";
81                 if (octal2)
82                     os << octal2;
83                 if (octal1)
84                     os << octal1;
85                 os << octal0;
86             }
87         }
88         os << "\"";
89     }
90
91 public:
92     JSONWriter(std::ostream &_os) : 
93         os(_os), 
94         level(0),
95         value(false)
96     {
97         beginObject();
98     }
99
100     ~JSONWriter() {
101         endObject();
102         newline();
103     }
104
105     inline void beginObject() {
106         separator();
107         os << "{";
108         ++level;
109         value = false;
110     }
111
112     inline void endObject() {
113         --level;
114         if (value)
115             newline();
116         os << "}";
117         value = true;
118     }
119
120     inline void beginMember(const char * name) {
121         separator();
122         newline();
123         escapeString(name);
124         os << ": ";
125         value = false;
126     }
127
128     inline void endMember(void) {
129         assert(value);
130         value = true;
131     }
132
133     inline void beginArray() {
134         separator();
135         os << "[";
136         value = false;
137     }
138
139     inline void endArray(void) {
140         os << "]";
141         value = true;
142     }
143
144     inline void writeString(const char *s) {
145         separator();
146         escapeString(s);
147         value = true;
148     }
149
150     inline void writeNull(void) {
151         separator();
152         os << "null";
153         value = true;
154     }
155
156     inline void writeBool(bool b) {
157         separator();
158         os << (b ? "true" : "false");
159         value = true;
160     }
161
162     template<class T>
163     void writeNumber(T n) {
164         separator();
165         os << n;
166         value = true;
167     }
168 };
169
170 #endif /* _JSON_HPP_ */