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