1 //===--------------------- JSON.cpp -----------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Utility/JSON.h"
11 
12 using namespace lldb_private;
13 
14 std::string
15 JSONString::json_string_quote_metachars (const std::string &s)
16 {
17     if (s.find('"') == std::string::npos)
18         return s;
19 
20     std::string output;
21     const size_t s_size = s.size();
22     const char *s_chars = s.c_str();
23     for (size_t i = 0; i < s_size; i++)
24     {
25         unsigned char ch = *(s_chars + i);
26         if (ch == '"')
27         {
28             output.push_back ('\\');
29         }
30         output.push_back (ch);
31     }
32     return output;
33 }
34 
35 JSONString::JSONString () :
36 JSONValue(JSONValue::Kind::String),
37 m_data()
38 {
39 }
40 
41 JSONString::JSONString (const char* s) :
42 JSONValue(JSONValue::Kind::String),
43 m_data(s ? s : "")
44 {
45 }
46 
47 JSONString::JSONString (const std::string& s) :
48 JSONValue(JSONValue::Kind::String),
49 m_data(s)
50 {
51 }
52 
53 void
54 JSONString::Write (Stream& s)
55 {
56     s.Printf("\"%s\"", json_string_quote_metachars(m_data).c_str());
57 }
58 
59 JSONNumber::JSONNumber () :
60 JSONValue(JSONValue::Kind::Number),
61 m_data(0)
62 {
63 }
64 
65 JSONNumber::JSONNumber (int64_t i) :
66 JSONValue(JSONValue::Kind::Number),
67 m_data(i)
68 {
69 }
70 
71 void
72 JSONNumber::Write (Stream& s)
73 {
74     s.Printf("%" PRId64, m_data);
75 }
76 
77 JSONTrue::JSONTrue () :
78 JSONValue(JSONValue::Kind::True)
79 {
80 }
81 
82 void
83 JSONTrue::Write(Stream& s)
84 {
85     s.Printf("true");
86 }
87 
88 JSONFalse::JSONFalse () :
89 JSONValue(JSONValue::Kind::False)
90 {
91 }
92 
93 void
94 JSONFalse::Write(Stream& s)
95 {
96     s.Printf("false");
97 }
98 
99 JSONNull::JSONNull () :
100 JSONValue(JSONValue::Kind::Null)
101 {
102 }
103 
104 void
105 JSONNull::Write(Stream& s)
106 {
107     s.Printf("null");
108 }
109 
110 JSONObject::JSONObject () :
111 JSONValue(JSONValue::Kind::Object)
112 {
113 }
114 
115 void
116 JSONObject::Write (Stream& s)
117 {
118     bool first = true;
119     s.PutChar('{');
120     auto iter = m_elements.begin(), end = m_elements.end();
121     for (;iter != end; iter++)
122     {
123         if (first)
124             first = false;
125         else
126             s.PutChar(',');
127         JSONString key(iter->first);
128         JSONValue::SP value(iter->second);
129         key.Write(s);
130         s.PutChar(':');
131         value->Write(s);
132     }
133     s.PutChar('}');
134 }
135 
136 bool
137 JSONObject::SetObject (const std::string& key,
138                        JSONValue::SP value)
139 {
140     if (key.empty() || nullptr == value.get())
141         return false;
142     m_elements[key] = value;
143     return true;
144 }
145 
146 JSONValue::SP
147 JSONObject::GetObject (const std::string& key)
148 {
149     auto iter = m_elements.find(key), end = m_elements.end();
150     if (iter == end)
151         return JSONValue::SP();
152     return iter->second;
153 }
154 
155 JSONArray::JSONArray () :
156 JSONValue(JSONValue::Kind::Array)
157 {
158 }
159 
160 void
161 JSONArray::Write (Stream& s)
162 {
163     bool first = true;
164     s.PutChar('[');
165     auto iter = m_elements.begin(), end = m_elements.end();
166     for (;iter != end; iter++)
167     {
168         if (first)
169             first = false;
170         else
171             s.PutChar(',');
172         (*iter)->Write(s);
173     }
174     s.PutChar(']');
175 }
176 
177 bool
178 JSONArray::SetObject (Index i,
179                       JSONValue::SP value)
180 {
181     if (value.get() == nullptr)
182         return false;
183     if (i < m_elements.size())
184     {
185         m_elements[i] = value;
186         return true;
187     }
188     if (i == m_elements.size())
189     {
190         m_elements.push_back(value);
191         return true;
192     }
193     return false;
194 }
195 
196 bool
197 JSONArray::AppendObject (JSONValue::SP value)
198 {
199     if (value.get() == nullptr)
200         return false;
201     m_elements.push_back(value);
202     return true;
203 }
204 
205 JSONValue::SP
206 JSONArray::GetObject (Index i)
207 {
208     if (i < m_elements.size())
209         return m_elements[i];
210     return JSONValue::SP();
211 }
212 
213 JSONArray::Size
214 JSONArray::GetNumElements ()
215 {
216     return m_elements.size();
217 }
218