1 //===-- JSONGenerator.h ----------------------------------------*- 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 #ifndef __JSONGenerator_h_ 11 #define __JSONGenerator_h_ 12 13 // C Includes 14 // C++ Includes 15 16 #include <iomanip> 17 #include <sstream> 18 #include <string> 19 #include <utility> 20 #include <vector> 21 22 //---------------------------------------------------------------------- 23 /// @class JSONGenerator JSONGenerator.h 24 /// @brief A class which can construct structured data for the sole purpose 25 /// of printing it in JSON format. 26 /// 27 /// A stripped down version of lldb's StructuredData objects which are much 28 /// general purpose. This variant is intended only for assembling information 29 /// and printing it as a JSON string. 30 //---------------------------------------------------------------------- 31 32 class JSONGenerator 33 { 34 public: 35 36 class Object; 37 class Array; 38 class Integer; 39 class Float; 40 class Boolean; 41 class String; 42 class Dictionary; 43 class Generic; 44 45 typedef std::shared_ptr<Object> ObjectSP; 46 typedef std::shared_ptr<Array> ArraySP; 47 typedef std::shared_ptr<Integer> IntegerSP; 48 typedef std::shared_ptr<Float> FloatSP; 49 typedef std::shared_ptr<Boolean> BooleanSP; 50 typedef std::shared_ptr<String> StringSP; 51 typedef std::shared_ptr<Dictionary> DictionarySP; 52 typedef std::shared_ptr<Generic> GenericSP; 53 54 enum class Type 55 { 56 eTypeInvalid = -1, 57 eTypeNull = 0, 58 eTypeGeneric, 59 eTypeArray, 60 eTypeInteger, 61 eTypeFloat, 62 eTypeBoolean, 63 eTypeString, 64 eTypeDictionary 65 }; 66 67 class Object : 68 public std::enable_shared_from_this<Object> 69 { 70 public: 71 72 Object (Type t = Type::eTypeInvalid) : 73 m_type (t) 74 { 75 } 76 77 virtual ~Object () 78 { 79 } 80 81 virtual bool 82 IsValid() const 83 { 84 return true; 85 } 86 87 virtual void 88 Clear () 89 { 90 m_type = Type::eTypeInvalid; 91 } 92 93 Type 94 GetType () const 95 { 96 return m_type; 97 } 98 99 void 100 SetType (Type t) 101 { 102 m_type = t; 103 } 104 105 Array * 106 GetAsArray () 107 { 108 if (m_type == Type::eTypeArray) 109 return (Array *)this; 110 return NULL; 111 } 112 113 Dictionary * 114 GetAsDictionary () 115 { 116 if (m_type == Type::eTypeDictionary) 117 return (Dictionary *)this; 118 return NULL; 119 } 120 121 Integer * 122 GetAsInteger () 123 { 124 if (m_type == Type::eTypeInteger) 125 return (Integer *)this; 126 return NULL; 127 } 128 129 Float * 130 GetAsFloat () 131 { 132 if (m_type == Type::eTypeFloat) 133 return (Float *)this; 134 return NULL; 135 } 136 137 Boolean * 138 GetAsBoolean () 139 { 140 if (m_type == Type::eTypeBoolean) 141 return (Boolean *)this; 142 return NULL; 143 } 144 145 String * 146 GetAsString () 147 { 148 if (m_type == Type::eTypeString) 149 return (String *)this; 150 return NULL; 151 } 152 153 Generic * 154 GetAsGeneric() 155 { 156 if (m_type == Type::eTypeGeneric) 157 return (Generic *)this; 158 return NULL; 159 } 160 161 virtual void 162 Dump (std::ostream &s) const = 0; 163 164 private: 165 Type m_type; 166 }; 167 168 class Array : public Object 169 { 170 public: 171 Array () : 172 Object (Type::eTypeArray) 173 { 174 } 175 176 virtual 177 ~Array() 178 { 179 } 180 181 void 182 AddItem(ObjectSP item) 183 { 184 m_items.push_back(item); 185 } 186 187 void Dump(std::ostream &s) const override 188 { 189 s << "["; 190 const size_t arrsize = m_items.size(); 191 for (size_t i = 0; i < arrsize; ++i) 192 { 193 m_items[i]->Dump(s); 194 if (i + 1 < arrsize) 195 s << ","; 196 } 197 s << "]"; 198 } 199 200 protected: 201 typedef std::vector<ObjectSP> collection; 202 collection m_items; 203 }; 204 205 206 class Integer : public Object 207 { 208 public: 209 Integer (uint64_t value = 0) : 210 Object (Type::eTypeInteger), 211 m_value (value) 212 { 213 } 214 215 virtual ~Integer() 216 { 217 } 218 219 void 220 SetValue (uint64_t value) 221 { 222 m_value = value; 223 } 224 225 void Dump(std::ostream &s) const override 226 { 227 s << m_value; 228 } 229 230 protected: 231 uint64_t m_value; 232 }; 233 234 class Float : public Object 235 { 236 public: 237 Float (double d = 0.0) : 238 Object (Type::eTypeFloat), 239 m_value (d) 240 { 241 } 242 243 virtual ~Float() 244 { 245 } 246 247 void 248 SetValue (double value) 249 { 250 m_value = value; 251 } 252 253 void Dump(std::ostream &s) const override 254 { 255 s << m_value; 256 } 257 258 protected: 259 double m_value; 260 }; 261 262 class Boolean : public Object 263 { 264 public: 265 Boolean (bool b = false) : 266 Object (Type::eTypeBoolean), 267 m_value (b) 268 { 269 } 270 271 virtual ~Boolean() 272 { 273 } 274 275 void 276 SetValue (bool value) 277 { 278 m_value = value; 279 } 280 281 void Dump(std::ostream &s) const override 282 { 283 if (m_value == true) 284 s << "true"; 285 else 286 s << "false"; 287 } 288 289 protected: 290 bool m_value; 291 }; 292 293 294 295 class String : public Object 296 { 297 public: 298 String () : 299 Object (Type::eTypeString), 300 m_value () 301 { 302 } 303 304 String (const std::string &s) : 305 Object (Type::eTypeString), 306 m_value (s) 307 { 308 } 309 310 String (const std::string &&s) : 311 Object (Type::eTypeString), 312 m_value (s) 313 { 314 } 315 316 void 317 SetValue (const std::string &string) 318 { 319 m_value = string; 320 } 321 322 void Dump(std::ostream &s) const override 323 { 324 std::string quoted; 325 const size_t strsize = m_value.size(); 326 for (size_t i = 0; i < strsize ; ++i) 327 { 328 char ch = m_value[i]; 329 if (ch == '"') 330 quoted.push_back ('\\'); 331 quoted.push_back (ch); 332 } 333 s << '"' << quoted.c_str() << '"'; 334 } 335 336 protected: 337 std::string m_value; 338 }; 339 340 class Dictionary : public Object 341 { 342 public: 343 Dictionary () : 344 Object (Type::eTypeDictionary), 345 m_dict () 346 { 347 } 348 349 virtual ~Dictionary() 350 { 351 } 352 353 void 354 AddItem (std::string key, ObjectSP value) 355 { 356 m_dict.push_back(Pair(key, value)); 357 } 358 359 void 360 AddIntegerItem (std::string key, uint64_t value) 361 { 362 AddItem (key, ObjectSP (new Integer(value))); 363 } 364 365 void 366 AddFloatItem (std::string key, double value) 367 { 368 AddItem (key, ObjectSP (new Float(value))); 369 } 370 371 void 372 AddStringItem (std::string key, std::string value) 373 { 374 AddItem (key, ObjectSP (new String(std::move(value)))); 375 } 376 377 void 378 AddBytesAsHexASCIIString (std::string key, const uint8_t *src, size_t src_len) 379 { 380 if (src && src_len) 381 { 382 std::ostringstream strm; 383 for (size_t i = 0; i < src_len; i++) 384 strm << std::setfill('0') << std::hex << std::right << std::setw(2) << ((uint32_t)(src[i])); 385 AddItem (key, ObjectSP (new String(std::move(strm.str())))); 386 } 387 else 388 { 389 AddItem (key, ObjectSP (new String())); 390 } 391 } 392 393 void 394 AddBooleanItem (std::string key, bool value) 395 { 396 AddItem (key, ObjectSP (new Boolean(value))); 397 } 398 399 void Dump(std::ostream &s) const override 400 { 401 bool have_printed_one_elem = false; 402 s << "{"; 403 for (collection::const_iterator iter = m_dict.begin(); iter != m_dict.end(); ++iter) 404 { 405 if (have_printed_one_elem == false) 406 { 407 have_printed_one_elem = true; 408 } 409 else 410 { 411 s << ","; 412 } 413 s << "\"" << iter->first.c_str() << "\":"; 414 iter->second->Dump(s); 415 } 416 s << "}"; 417 } 418 419 protected: 420 // Keep the dictionary as a vector so the dictionary doesn't reorder itself when you dump it 421 // We aren't accessing keys by name, so this won't affect performance 422 typedef std::pair<std::string, ObjectSP> Pair; 423 typedef std::vector<Pair> collection; 424 collection m_dict; 425 }; 426 427 class Null : public Object 428 { 429 public: 430 Null () : 431 Object (Type::eTypeNull) 432 { 433 } 434 435 virtual ~Null() 436 { 437 } 438 439 bool 440 IsValid() const override 441 { 442 return false; 443 } 444 445 void Dump(std::ostream &s) const override 446 { 447 s << "null"; 448 } 449 450 protected: 451 }; 452 453 class Generic : public Object 454 { 455 public: 456 explicit Generic(void *object = nullptr) 457 : Object(Type::eTypeGeneric) 458 , m_object(object) 459 { 460 } 461 462 void 463 SetValue(void *value) 464 { 465 m_object = value; 466 } 467 468 void * 469 GetValue() const 470 { 471 return m_object; 472 } 473 474 bool 475 IsValid() const override 476 { 477 return m_object != nullptr; 478 } 479 480 void Dump(std::ostream &s) const override; 481 482 private: 483 void *m_object; 484 }; 485 486 }; // class JSONGenerator 487 488 489 490 #endif // __JSONGenerator_h_ 491