1c9a2f6efSGreg Clayton //===-- JSONGenerator.h ----------------------------------------*- C++ -*-===// 2c9a2f6efSGreg Clayton // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6c9a2f6efSGreg Clayton // 7c9a2f6efSGreg Clayton //===----------------------------------------------------------------------===// 8c9a2f6efSGreg Clayton 9cdc514e4SJonas Devlieghere #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_JSONGENERATOR_H 10cdc514e4SJonas Devlieghere #define LLDB_TOOLS_DEBUGSERVER_SOURCE_JSONGENERATOR_H 11c9a2f6efSGreg Clayton 12c9a2f6efSGreg Clayton #include <iomanip> 13c9a2f6efSGreg Clayton #include <sstream> 14c9a2f6efSGreg Clayton #include <string> 15c9a2f6efSGreg Clayton #include <utility> 16c9a2f6efSGreg Clayton #include <vector> 17c9a2f6efSGreg Clayton 18f05b42e9SAdrian Prantl /// \class JSONGenerator JSONGenerator.h 19d8f460e8SAdrian Prantl /// A class which can construct structured data for the sole purpose 20c9a2f6efSGreg Clayton /// of printing it in JSON format. 21c9a2f6efSGreg Clayton /// 22c9a2f6efSGreg Clayton /// A stripped down version of lldb's StructuredData objects which are much 23c9a2f6efSGreg Clayton /// general purpose. This variant is intended only for assembling information 24c9a2f6efSGreg Clayton /// and printing it as a JSON string. 25c9a2f6efSGreg Clayton 26b9c1b51eSKate Stone class JSONGenerator { 27c9a2f6efSGreg Clayton public: 28c9a2f6efSGreg Clayton class Object; 29c9a2f6efSGreg Clayton class Array; 30c9a2f6efSGreg Clayton class Integer; 31c9a2f6efSGreg Clayton class Float; 32c9a2f6efSGreg Clayton class Boolean; 33c9a2f6efSGreg Clayton class String; 34c9a2f6efSGreg Clayton class Dictionary; 35c9a2f6efSGreg Clayton class Generic; 36c9a2f6efSGreg Clayton 37c9a2f6efSGreg Clayton typedef std::shared_ptr<Object> ObjectSP; 38c9a2f6efSGreg Clayton typedef std::shared_ptr<Array> ArraySP; 39c9a2f6efSGreg Clayton typedef std::shared_ptr<Integer> IntegerSP; 40c9a2f6efSGreg Clayton typedef std::shared_ptr<Float> FloatSP; 41c9a2f6efSGreg Clayton typedef std::shared_ptr<Boolean> BooleanSP; 42c9a2f6efSGreg Clayton typedef std::shared_ptr<String> StringSP; 43c9a2f6efSGreg Clayton typedef std::shared_ptr<Dictionary> DictionarySP; 44c9a2f6efSGreg Clayton typedef std::shared_ptr<Generic> GenericSP; 45c9a2f6efSGreg Clayton 46b9c1b51eSKate Stone enum class Type { 47c9a2f6efSGreg Clayton eTypeInvalid = -1, 48c9a2f6efSGreg Clayton eTypeNull = 0, 49c9a2f6efSGreg Clayton eTypeGeneric, 50c9a2f6efSGreg Clayton eTypeArray, 51c9a2f6efSGreg Clayton eTypeInteger, 52c9a2f6efSGreg Clayton eTypeFloat, 53c9a2f6efSGreg Clayton eTypeBoolean, 54c9a2f6efSGreg Clayton eTypeString, 55c9a2f6efSGreg Clayton eTypeDictionary 56c9a2f6efSGreg Clayton }; 57c9a2f6efSGreg Clayton 58b9c1b51eSKate Stone class Object : public std::enable_shared_from_this<Object> { 59c9a2f6efSGreg Clayton public: m_type(t)60b9c1b51eSKate Stone Object(Type t = Type::eTypeInvalid) : m_type(t) {} 61c9a2f6efSGreg Clayton ~Object()62b9c1b51eSKate Stone virtual ~Object() {} 63c9a2f6efSGreg Clayton IsValid()64b9c1b51eSKate Stone virtual bool IsValid() const { return true; } 65c9a2f6efSGreg Clayton Clear()66b9c1b51eSKate Stone virtual void Clear() { m_type = Type::eTypeInvalid; } 67c9a2f6efSGreg Clayton GetType()68b9c1b51eSKate Stone Type GetType() const { return m_type; } 69c9a2f6efSGreg Clayton SetType(Type t)70b9c1b51eSKate Stone void SetType(Type t) { m_type = t; } 71c9a2f6efSGreg Clayton GetAsArray()72b9c1b51eSKate Stone Array *GetAsArray() { 73c9a2f6efSGreg Clayton if (m_type == Type::eTypeArray) 74c9a2f6efSGreg Clayton return (Array *)this; 75c9a2f6efSGreg Clayton return NULL; 76c9a2f6efSGreg Clayton } 77c9a2f6efSGreg Clayton GetAsDictionary()78b9c1b51eSKate Stone Dictionary *GetAsDictionary() { 79c9a2f6efSGreg Clayton if (m_type == Type::eTypeDictionary) 80c9a2f6efSGreg Clayton return (Dictionary *)this; 81c9a2f6efSGreg Clayton return NULL; 82c9a2f6efSGreg Clayton } 83c9a2f6efSGreg Clayton GetAsInteger()84b9c1b51eSKate Stone Integer *GetAsInteger() { 85c9a2f6efSGreg Clayton if (m_type == Type::eTypeInteger) 86c9a2f6efSGreg Clayton return (Integer *)this; 87c9a2f6efSGreg Clayton return NULL; 88c9a2f6efSGreg Clayton } 89c9a2f6efSGreg Clayton GetAsFloat()90b9c1b51eSKate Stone Float *GetAsFloat() { 91c9a2f6efSGreg Clayton if (m_type == Type::eTypeFloat) 92c9a2f6efSGreg Clayton return (Float *)this; 93c9a2f6efSGreg Clayton return NULL; 94c9a2f6efSGreg Clayton } 95c9a2f6efSGreg Clayton GetAsBoolean()96b9c1b51eSKate Stone Boolean *GetAsBoolean() { 97c9a2f6efSGreg Clayton if (m_type == Type::eTypeBoolean) 98c9a2f6efSGreg Clayton return (Boolean *)this; 99c9a2f6efSGreg Clayton return NULL; 100c9a2f6efSGreg Clayton } 101c9a2f6efSGreg Clayton GetAsString()102b9c1b51eSKate Stone String *GetAsString() { 103c9a2f6efSGreg Clayton if (m_type == Type::eTypeString) 104c9a2f6efSGreg Clayton return (String *)this; 105c9a2f6efSGreg Clayton return NULL; 106c9a2f6efSGreg Clayton } 107c9a2f6efSGreg Clayton GetAsGeneric()108b9c1b51eSKate Stone Generic *GetAsGeneric() { 109c9a2f6efSGreg Clayton if (m_type == Type::eTypeGeneric) 110c9a2f6efSGreg Clayton return (Generic *)this; 111c9a2f6efSGreg Clayton return NULL; 112c9a2f6efSGreg Clayton } 113c9a2f6efSGreg Clayton 114b9c1b51eSKate Stone virtual void Dump(std::ostream &s) const = 0; 115c9a2f6efSGreg Clayton 116*7ebcd889SJason Molenda virtual void DumpBinaryEscaped(std::ostream &s) const = 0; 117*7ebcd889SJason Molenda 118c9a2f6efSGreg Clayton private: 119c9a2f6efSGreg Clayton Type m_type; 120c9a2f6efSGreg Clayton }; 121c9a2f6efSGreg Clayton 122b9c1b51eSKate Stone class Array : public Object { 123c9a2f6efSGreg Clayton public: Array()124b9c1b51eSKate Stone Array() : Object(Type::eTypeArray) {} 125c9a2f6efSGreg Clayton ~Array()126b9c1b51eSKate Stone virtual ~Array() {} 127c9a2f6efSGreg Clayton AddItem(ObjectSP item)128b9c1b51eSKate Stone void AddItem(ObjectSP item) { m_items.push_back(item); } 129c9a2f6efSGreg Clayton Dump(std::ostream & s)130b9c1b51eSKate Stone void Dump(std::ostream &s) const override { 131c9a2f6efSGreg Clayton s << "["; 132c9a2f6efSGreg Clayton const size_t arrsize = m_items.size(); 133b9c1b51eSKate Stone for (size_t i = 0; i < arrsize; ++i) { 134c9a2f6efSGreg Clayton m_items[i]->Dump(s); 135c9a2f6efSGreg Clayton if (i + 1 < arrsize) 136c9a2f6efSGreg Clayton s << ","; 137c9a2f6efSGreg Clayton } 138c9a2f6efSGreg Clayton s << "]"; 139c9a2f6efSGreg Clayton } 140c9a2f6efSGreg Clayton DumpBinaryEscaped(std::ostream & s)141*7ebcd889SJason Molenda void DumpBinaryEscaped(std::ostream &s) const override { 142*7ebcd889SJason Molenda s << "["; 143*7ebcd889SJason Molenda const size_t arrsize = m_items.size(); 144*7ebcd889SJason Molenda for (size_t i = 0; i < arrsize; ++i) { 145*7ebcd889SJason Molenda m_items[i]->DumpBinaryEscaped(s); 146*7ebcd889SJason Molenda if (i + 1 < arrsize) 147*7ebcd889SJason Molenda s << ","; 148*7ebcd889SJason Molenda } 149*7ebcd889SJason Molenda s << "]"; 150*7ebcd889SJason Molenda } 151*7ebcd889SJason Molenda 152c9a2f6efSGreg Clayton protected: 153c9a2f6efSGreg Clayton typedef std::vector<ObjectSP> collection; 154c9a2f6efSGreg Clayton collection m_items; 155c9a2f6efSGreg Clayton }; 156c9a2f6efSGreg Clayton 157b9c1b51eSKate Stone class Integer : public Object { 158c9a2f6efSGreg Clayton public: Object(Type::eTypeInteger)159b9c1b51eSKate Stone Integer(uint64_t value = 0) : Object(Type::eTypeInteger), m_value(value) {} 160c9a2f6efSGreg Clayton ~Integer()161b9c1b51eSKate Stone virtual ~Integer() {} 162c9a2f6efSGreg Clayton SetValue(uint64_t value)163b9c1b51eSKate Stone void SetValue(uint64_t value) { m_value = value; } 164c9a2f6efSGreg Clayton Dump(std::ostream & s)165b9c1b51eSKate Stone void Dump(std::ostream &s) const override { s << m_value; } 166c9a2f6efSGreg Clayton DumpBinaryEscaped(std::ostream & s)167*7ebcd889SJason Molenda void DumpBinaryEscaped(std::ostream &s) const override { Dump(s); } 168*7ebcd889SJason Molenda 169c9a2f6efSGreg Clayton protected: 170c9a2f6efSGreg Clayton uint64_t m_value; 171c9a2f6efSGreg Clayton }; 172c9a2f6efSGreg Clayton 173b9c1b51eSKate Stone class Float : public Object { 174c9a2f6efSGreg Clayton public: Object(Type::eTypeFloat)175b9c1b51eSKate Stone Float(double d = 0.0) : Object(Type::eTypeFloat), m_value(d) {} 176c9a2f6efSGreg Clayton ~Float()177b9c1b51eSKate Stone virtual ~Float() {} 178c9a2f6efSGreg Clayton SetValue(double value)179b9c1b51eSKate Stone void SetValue(double value) { m_value = value; } 180c9a2f6efSGreg Clayton Dump(std::ostream & s)181b9c1b51eSKate Stone void Dump(std::ostream &s) const override { s << m_value; } 182c9a2f6efSGreg Clayton DumpBinaryEscaped(std::ostream & s)183*7ebcd889SJason Molenda void DumpBinaryEscaped(std::ostream &s) const override { Dump(s); } 184*7ebcd889SJason Molenda 185c9a2f6efSGreg Clayton protected: 186c9a2f6efSGreg Clayton double m_value; 187c9a2f6efSGreg Clayton }; 188c9a2f6efSGreg Clayton 189b9c1b51eSKate Stone class Boolean : public Object { 190c9a2f6efSGreg Clayton public: Object(Type::eTypeBoolean)191b9c1b51eSKate Stone Boolean(bool b = false) : Object(Type::eTypeBoolean), m_value(b) {} 192c9a2f6efSGreg Clayton ~Boolean()193b9c1b51eSKate Stone virtual ~Boolean() {} 194c9a2f6efSGreg Clayton SetValue(bool value)195b9c1b51eSKate Stone void SetValue(bool value) { m_value = value; } 196c9a2f6efSGreg Clayton Dump(std::ostream & s)197b9c1b51eSKate Stone void Dump(std::ostream &s) const override { 198a6682a41SJonas Devlieghere if (m_value) 199c9a2f6efSGreg Clayton s << "true"; 200c9a2f6efSGreg Clayton else 201c9a2f6efSGreg Clayton s << "false"; 202c9a2f6efSGreg Clayton } 203c9a2f6efSGreg Clayton DumpBinaryEscaped(std::ostream & s)204*7ebcd889SJason Molenda void DumpBinaryEscaped(std::ostream &s) const override { Dump(s); } 205*7ebcd889SJason Molenda 206c9a2f6efSGreg Clayton protected: 207c9a2f6efSGreg Clayton bool m_value; 208c9a2f6efSGreg Clayton }; 209c9a2f6efSGreg Clayton 210b9c1b51eSKate Stone class String : public Object { 211c9a2f6efSGreg Clayton public: String()212b9c1b51eSKate Stone String() : Object(Type::eTypeString), m_value() {} 213c9a2f6efSGreg Clayton String(const std::string & s)214b9c1b51eSKate Stone String(const std::string &s) : Object(Type::eTypeString), m_value(s) {} 215c9a2f6efSGreg Clayton String(const std::string && s)216b9c1b51eSKate Stone String(const std::string &&s) : Object(Type::eTypeString), m_value(s) {} 217c9a2f6efSGreg Clayton SetValue(const std::string & string)218b9c1b51eSKate Stone void SetValue(const std::string &string) { m_value = string; } 219c9a2f6efSGreg Clayton Dump(std::ostream & s)220b9c1b51eSKate Stone void Dump(std::ostream &s) const override { 221*7ebcd889SJason Molenda s << '"'; 222c9a2f6efSGreg Clayton const size_t strsize = m_value.size(); 223b9c1b51eSKate Stone for (size_t i = 0; i < strsize; ++i) { 224c9a2f6efSGreg Clayton char ch = m_value[i]; 225c9a2f6efSGreg Clayton if (ch == '"') 226*7ebcd889SJason Molenda s << '\\'; 227*7ebcd889SJason Molenda s << ch; 228c9a2f6efSGreg Clayton } 229*7ebcd889SJason Molenda s << '"'; 230*7ebcd889SJason Molenda } 231*7ebcd889SJason Molenda DumpBinaryEscaped(std::ostream & s)232*7ebcd889SJason Molenda void DumpBinaryEscaped(std::ostream &s) const override { 233*7ebcd889SJason Molenda s << '"'; 234*7ebcd889SJason Molenda const size_t strsize = m_value.size(); 235*7ebcd889SJason Molenda for (size_t i = 0; i < strsize; ++i) { 236*7ebcd889SJason Molenda char ch = m_value[i]; 237*7ebcd889SJason Molenda if (ch == '"') 238*7ebcd889SJason Molenda s << '\\'; 239*7ebcd889SJason Molenda // gdb remote serial protocol binary escaping 240*7ebcd889SJason Molenda if (ch == '#' || ch == '$' || ch == '}' || ch == '*') { 241*7ebcd889SJason Molenda s << '}'; // 0x7d next character is escaped 242*7ebcd889SJason Molenda s << static_cast<char>(ch ^ 0x20); 243*7ebcd889SJason Molenda } else { 244*7ebcd889SJason Molenda s << ch; 245*7ebcd889SJason Molenda } 246*7ebcd889SJason Molenda } 247*7ebcd889SJason Molenda s << '"'; 248c9a2f6efSGreg Clayton } 249c9a2f6efSGreg Clayton 250c9a2f6efSGreg Clayton protected: 251c9a2f6efSGreg Clayton std::string m_value; 252c9a2f6efSGreg Clayton }; 253c9a2f6efSGreg Clayton 254b9c1b51eSKate Stone class Dictionary : public Object { 255c9a2f6efSGreg Clayton public: Dictionary()256b9c1b51eSKate Stone Dictionary() : Object(Type::eTypeDictionary), m_dict() {} 257c9a2f6efSGreg Clayton ~Dictionary()258b9c1b51eSKate Stone virtual ~Dictionary() {} 259c9a2f6efSGreg Clayton AddItem(std::string key,ObjectSP value)260b9c1b51eSKate Stone void AddItem(std::string key, ObjectSP value) { 261c9a2f6efSGreg Clayton m_dict.push_back(Pair(key, value)); 262c9a2f6efSGreg Clayton } 263c9a2f6efSGreg Clayton AddIntegerItem(std::string key,uint64_t value)264b9c1b51eSKate Stone void AddIntegerItem(std::string key, uint64_t value) { 265c9a2f6efSGreg Clayton AddItem(key, ObjectSP(new Integer(value))); 266c9a2f6efSGreg Clayton } 267c9a2f6efSGreg Clayton AddFloatItem(std::string key,double value)268b9c1b51eSKate Stone void AddFloatItem(std::string key, double value) { 269c9a2f6efSGreg Clayton AddItem(key, ObjectSP(new Float(value))); 270c9a2f6efSGreg Clayton } 271c9a2f6efSGreg Clayton AddStringItem(std::string key,std::string value)272b9c1b51eSKate Stone void AddStringItem(std::string key, std::string value) { 273c9a2f6efSGreg Clayton AddItem(key, ObjectSP(new String(std::move(value)))); 274c9a2f6efSGreg Clayton } 275c9a2f6efSGreg Clayton AddBytesAsHexASCIIString(std::string key,const uint8_t * src,size_t src_len)276b9c1b51eSKate Stone void AddBytesAsHexASCIIString(std::string key, const uint8_t *src, 277b9c1b51eSKate Stone size_t src_len) { 278b9c1b51eSKate Stone if (src && src_len) { 279c9a2f6efSGreg Clayton std::ostringstream strm; 280c9a2f6efSGreg Clayton for (size_t i = 0; i < src_len; i++) 281b9c1b51eSKate Stone strm << std::setfill('0') << std::hex << std::right << std::setw(2) 282b9c1b51eSKate Stone << ((uint32_t)(src[i])); 283c9a2f6efSGreg Clayton AddItem(key, ObjectSP(new String(std::move(strm.str())))); 284b9c1b51eSKate Stone } else { 285c9a2f6efSGreg Clayton AddItem(key, ObjectSP(new String())); 286c9a2f6efSGreg Clayton } 287c9a2f6efSGreg Clayton } 288c9a2f6efSGreg Clayton AddBooleanItem(std::string key,bool value)289b9c1b51eSKate Stone void AddBooleanItem(std::string key, bool value) { 290c9a2f6efSGreg Clayton AddItem(key, ObjectSP(new Boolean(value))); 291c9a2f6efSGreg Clayton } 292c9a2f6efSGreg Clayton Dump(std::ostream & s)293b9c1b51eSKate Stone void Dump(std::ostream &s) const override { 294c9a2f6efSGreg Clayton bool have_printed_one_elem = false; 295c9a2f6efSGreg Clayton s << "{"; 296b9c1b51eSKate Stone for (collection::const_iterator iter = m_dict.begin(); 297b9c1b51eSKate Stone iter != m_dict.end(); ++iter) { 298a6682a41SJonas Devlieghere if (!have_printed_one_elem) { 299c9a2f6efSGreg Clayton have_printed_one_elem = true; 300b9c1b51eSKate Stone } else { 301c9a2f6efSGreg Clayton s << ","; 302c9a2f6efSGreg Clayton } 303c9a2f6efSGreg Clayton s << "\"" << iter->first.c_str() << "\":"; 304c9a2f6efSGreg Clayton iter->second->Dump(s); 305c9a2f6efSGreg Clayton } 306c9a2f6efSGreg Clayton s << "}"; 307c9a2f6efSGreg Clayton } 308c9a2f6efSGreg Clayton DumpBinaryEscaped(std::ostream & s)309*7ebcd889SJason Molenda void DumpBinaryEscaped(std::ostream &s) const override { 310*7ebcd889SJason Molenda bool have_printed_one_elem = false; 311*7ebcd889SJason Molenda s << "{"; 312*7ebcd889SJason Molenda for (collection::const_iterator iter = m_dict.begin(); 313*7ebcd889SJason Molenda iter != m_dict.end(); ++iter) { 314*7ebcd889SJason Molenda if (!have_printed_one_elem) { 315*7ebcd889SJason Molenda have_printed_one_elem = true; 316*7ebcd889SJason Molenda } else { 317*7ebcd889SJason Molenda s << ","; 318*7ebcd889SJason Molenda } 319*7ebcd889SJason Molenda s << "\"" << binary_encode_string(iter->first) << "\":"; 320*7ebcd889SJason Molenda iter->second->DumpBinaryEscaped(s); 321*7ebcd889SJason Molenda } 322*7ebcd889SJason Molenda // '}' must be escaped for the gdb remote serial 323*7ebcd889SJason Molenda // protocol. 324*7ebcd889SJason Molenda s << "}"; 325*7ebcd889SJason Molenda s << static_cast<char>('}' ^ 0x20); 326*7ebcd889SJason Molenda } 327*7ebcd889SJason Molenda 328c9a2f6efSGreg Clayton protected: binary_encode_string(const std::string & s)329*7ebcd889SJason Molenda std::string binary_encode_string(const std::string &s) const { 330*7ebcd889SJason Molenda std::string output; 331*7ebcd889SJason Molenda const size_t s_size = s.size(); 332*7ebcd889SJason Molenda const char *s_chars = s.c_str(); 333*7ebcd889SJason Molenda 334*7ebcd889SJason Molenda for (size_t i = 0; i < s_size; i++) { 335*7ebcd889SJason Molenda unsigned char ch = *(s_chars + i); 336*7ebcd889SJason Molenda if (ch == '#' || ch == '$' || ch == '}' || ch == '*') { 337*7ebcd889SJason Molenda output.push_back('}'); // 0x7d 338*7ebcd889SJason Molenda output.push_back(ch ^ 0x20); 339*7ebcd889SJason Molenda } else { 340*7ebcd889SJason Molenda output.push_back(ch); 341*7ebcd889SJason Molenda } 342*7ebcd889SJason Molenda } 343*7ebcd889SJason Molenda return output; 344*7ebcd889SJason Molenda } 345*7ebcd889SJason Molenda 346b9c1b51eSKate Stone // Keep the dictionary as a vector so the dictionary doesn't reorder itself 347b9c1b51eSKate Stone // when you dump it 348c9a2f6efSGreg Clayton // We aren't accessing keys by name, so this won't affect performance 349c9a2f6efSGreg Clayton typedef std::pair<std::string, ObjectSP> Pair; 350c9a2f6efSGreg Clayton typedef std::vector<Pair> collection; 351c9a2f6efSGreg Clayton collection m_dict; 352c9a2f6efSGreg Clayton }; 353c9a2f6efSGreg Clayton 354b9c1b51eSKate Stone class Null : public Object { 355c9a2f6efSGreg Clayton public: Null()356b9c1b51eSKate Stone Null() : Object(Type::eTypeNull) {} 357c9a2f6efSGreg Clayton ~Null()358b9c1b51eSKate Stone virtual ~Null() {} 359c9a2f6efSGreg Clayton IsValid()360b9c1b51eSKate Stone bool IsValid() const override { return false; } 361c9a2f6efSGreg Clayton Dump(std::ostream & s)362b9c1b51eSKate Stone void Dump(std::ostream &s) const override { s << "null"; } 363c9a2f6efSGreg Clayton DumpBinaryEscaped(std::ostream & s)364*7ebcd889SJason Molenda void DumpBinaryEscaped(std::ostream &s) const override { Dump(s); } 365*7ebcd889SJason Molenda 366c9a2f6efSGreg Clayton protected: 367c9a2f6efSGreg Clayton }; 368c9a2f6efSGreg Clayton 369b9c1b51eSKate Stone class Generic : public Object { 370c9a2f6efSGreg Clayton public: 371c9a2f6efSGreg Clayton explicit Generic(void *object = nullptr) Object(Type::eTypeGeneric)372b9c1b51eSKate Stone : Object(Type::eTypeGeneric), m_object(object) {} 373c9a2f6efSGreg Clayton SetValue(void * value)374b9c1b51eSKate Stone void SetValue(void *value) { m_object = value; } 375c9a2f6efSGreg Clayton GetValue()376b9c1b51eSKate Stone void *GetValue() const { return m_object; } 377c9a2f6efSGreg Clayton IsValid()378b9c1b51eSKate Stone bool IsValid() const override { return m_object != nullptr; } 379c9a2f6efSGreg Clayton 380c9a2f6efSGreg Clayton void Dump(std::ostream &s) const override; 381c9a2f6efSGreg Clayton 382*7ebcd889SJason Molenda void DumpBinaryEscaped(std::ostream &s) const override; 383*7ebcd889SJason Molenda 384c9a2f6efSGreg Clayton private: 385c9a2f6efSGreg Clayton void *m_object; 386c9a2f6efSGreg Clayton }; 387c9a2f6efSGreg Clayton 388c9a2f6efSGreg Clayton }; // class JSONGenerator 389c9a2f6efSGreg Clayton 390cdc514e4SJonas Devlieghere #endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_JSONGENERATOR_H 391