Index: lldb/trunk/include/lldb/Core/StructuredDataImpl.h =================================================================== --- lldb/trunk/include/lldb/Core/StructuredDataImpl.h +++ lldb/trunk/include/lldb/Core/StructuredDataImpl.h @@ -54,7 +54,8 @@ return error; } - m_data_sp->Dump(stream); + llvm::json::OStream s(stream.AsRawOstream()); + m_data_sp->Serialize(s); return error; } Index: lldb/trunk/include/lldb/Utility/StructuredData.h =================================================================== --- lldb/trunk/include/lldb/Utility/StructuredData.h +++ lldb/trunk/include/lldb/Utility/StructuredData.h @@ -10,9 +10,11 @@ #define liblldb_StructuredData_h_ #include "llvm/ADT/StringRef.h" +#include "llvm/Support/JSON.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Stream.h" #include "lldb/lldb-enumerations.h" #include @@ -28,7 +30,6 @@ namespace lldb_private { class Status; -class Stream; } namespace lldb_private { @@ -150,7 +151,12 @@ void DumpToStdout(bool pretty_print = true) const; - virtual void Dump(Stream &s, bool pretty_print = true) const = 0; + virtual void Serialize(llvm::json::OStream &s) const = 0; + + void Dump(lldb_private::Stream &s, bool pretty_print = true) const { + llvm::json::OStream jso(s.AsRawOstream(), pretty_print ? 2 : 0); + Serialize(jso); + } private: lldb::StructuredDataType m_type; @@ -269,7 +275,7 @@ void AddItem(ObjectSP item) { m_items.push_back(item); } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; protected: typedef std::vector collection; @@ -287,7 +293,7 @@ uint64_t GetValue() { return m_value; } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; protected: uint64_t m_value; @@ -304,7 +310,7 @@ double GetValue() { return m_value; } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; protected: double m_value; @@ -321,7 +327,7 @@ bool GetValue() { return m_value; } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; protected: bool m_value; @@ -337,7 +343,7 @@ llvm::StringRef GetValue() { return m_value; } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; protected: std::string m_value; @@ -506,7 +512,7 @@ AddItem(key, std::make_shared(value)); } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; protected: typedef std::map collection; @@ -521,7 +527,7 @@ bool IsValid() const override { return false; } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; }; class Generic : public Object { @@ -535,7 +541,7 @@ bool IsValid() const override { return m_object != nullptr; } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; private: void *m_object; Index: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -5089,7 +5089,7 @@ if (log) { if (json_sp) { StreamString json_str; - json_sp->Dump(json_str); + json_sp->Dump(json_str, true); json_str.Flush(); LLDB_LOGF(log, "ProcessGDBRemote::%s() " Index: lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h =================================================================== --- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -43,7 +43,7 @@ bool IsValid() const override { return GetValue() && GetValue() != Py_None; } - void Dump(Stream &s, bool pretty_print = true) const override; + void Serialize(llvm::json::OStream &s) const override; private: DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject); Index: lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp =================================================================== --- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -29,8 +29,8 @@ using namespace lldb_private; using namespace lldb; -void StructuredPythonObject::Dump(Stream &s, bool pretty_print) const { - s << "Python Obj: 0x" << GetValue(); +void StructuredPythonObject::Serialize(llvm::json::OStream &s) const { + s.value(llvm::formatv("Python Obj: {0:X}", GetValue()).str()); } // PythonObject Index: lldb/trunk/source/Utility/StructuredData.cpp =================================================================== --- lldb/trunk/source/Utility/StructuredData.cpp +++ lldb/trunk/source/Utility/StructuredData.cpp @@ -11,7 +11,6 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/JSON.h" #include "lldb/Utility/Status.h" -#include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/MemoryBuffer.h" @@ -21,6 +20,7 @@ #include using namespace lldb_private; +using namespace llvm; // Functions that use a JSONParser to parse JSON into StructuredData static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser); @@ -181,98 +181,48 @@ } void StructuredData::Object::DumpToStdout(bool pretty_print) const { - StreamString stream; - Dump(stream, pretty_print); - llvm::outs() << stream.GetString(); + json::OStream stream(llvm::outs(), pretty_print ? 2 : 0); + Serialize(stream); } -void StructuredData::Array::Dump(Stream &s, bool pretty_print) const { - bool first = true; - s << "["; - if (pretty_print) { - s << "\n"; - s.IndentMore(); - } +void StructuredData::Array::Serialize(json::OStream &s) const { + s.arrayBegin(); for (const auto &item_sp : m_items) { - if (first) { - first = false; - } else { - s << ","; - if (pretty_print) - s << "\n"; - } - - if (pretty_print) - s.Indent(); - item_sp->Dump(s, pretty_print); - } - if (pretty_print) { - s.IndentLess(); - s.EOL(); - s.Indent(); + item_sp->Serialize(s); } - s << "]"; + s.arrayEnd(); } -void StructuredData::Integer::Dump(Stream &s, bool pretty_print) const { - s.Printf("%" PRIu64, m_value); +void StructuredData::Integer::Serialize(json::OStream &s) const { + s.value(static_cast(m_value)); } -void StructuredData::Float::Dump(Stream &s, bool pretty_print) const { - s.Printf("%lg", m_value); +void StructuredData::Float::Serialize(json::OStream &s) const { + s.value(m_value); } -void StructuredData::Boolean::Dump(Stream &s, bool pretty_print) const { - if (m_value) - s.PutCString("true"); - else - s.PutCString("false"); +void StructuredData::Boolean::Serialize(json::OStream &s) const { + s.value(m_value); } -void StructuredData::String::Dump(Stream &s, bool pretty_print) const { - std::string quoted; - const size_t strsize = m_value.size(); - for (size_t i = 0; i < strsize; ++i) { - char ch = m_value[i]; - if (ch == '"' || ch == '\\') - quoted.push_back('\\'); - quoted.push_back(ch); - } - s.Printf("\"%s\"", quoted.c_str()); +void StructuredData::String::Serialize(json::OStream &s) const { + s.value(m_value); } -void StructuredData::Dictionary::Dump(Stream &s, bool pretty_print) const { - bool first = true; - s << "{"; - if (pretty_print) { - s << "\n"; - s.IndentMore(); - } +void StructuredData::Dictionary::Serialize(json::OStream &s) const { + s.objectBegin(); for (const auto &pair : m_dict) { - if (first) - first = false; - else { - s << ","; - if (pretty_print) - s << "\n"; - } - if (pretty_print) - s.Indent(); - s << "\"" << pair.first.AsCString() << "\" : "; - pair.second->Dump(s, pretty_print); - } - if (pretty_print) { - s.IndentLess(); - s.EOL(); - s.Indent(); + s.attributeBegin(pair.first.AsCString()); + pair.second->Serialize(s); + s.attributeEnd(); } - s << "}"; + s.objectEnd(); } -void StructuredData::Null::Dump(Stream &s, bool pretty_print) const { - s << "null"; +void StructuredData::Null::Serialize(json::OStream &s) const { + s.value(nullptr); } -void StructuredData::Generic::Dump(Stream &s, bool pretty_print) const { - s << "0x" << m_object; +void StructuredData::Generic::Serialize(json::OStream &s) const { + s.value(llvm::formatv("{0:X}", m_object)); } Index: lldb/trunk/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp =================================================================== --- lldb/trunk/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp +++ lldb/trunk/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp @@ -384,9 +384,9 @@ // Since the line is exceeding 80 characters. std::string expected_packet1 = - R"(jTraceStart:{"buffersize" : 8192,"metabuffersize" : 8192,"params" :)"; + R"(jTraceStart:{"buffersize":8192,"metabuffersize":8192,"params":)"; std::string expected_packet2 = - R"( {"psb" : 1,"tracetech" : "intel-pt"},"threadid" : 35,"type" : 1})"; + R"({"psb":1,"tracetech":"intel-pt"},"threadid":35,"type":1})"; HandlePacket(server, (expected_packet1 + expected_packet2), "1"); ASSERT_TRUE(error.Success()); ASSERT_EQ(result.get(), 1u); @@ -409,8 +409,7 @@ return client.SendStopTracePacket(trace_id, thread_id); }); - const char *expected_packet = - R"(jTraceStop:{"threadid" : 35,"traceid" : 3})"; + const char *expected_packet = R"(jTraceStop:{"threadid":35,"traceid":3})"; HandlePacket(server, expected_packet, "OK"); ASSERT_TRUE(result.get().Success()); @@ -435,8 +434,8 @@ }); std::string expected_packet1 = - R"(jTraceBufferRead:{"buffersize" : 32,"offset" : 0,"threadid" : 35,)"; - std::string expected_packet2 = R"("traceid" : 3})"; + R"(jTraceBufferRead:{"buffersize":32,"offset":0,"threadid":35,)"; + std::string expected_packet2 = R"("traceid":3})"; HandlePacket(server, expected_packet1+expected_packet2, "123456"); ASSERT_TRUE(result.get().Success()); ASSERT_EQ(buffer.size(), 3u); @@ -467,8 +466,8 @@ }); std::string expected_packet1 = - R"(jTraceMetaRead:{"buffersize" : 32,"offset" : 0,"threadid" : 35,)"; - std::string expected_packet2 = R"("traceid" : 3})"; + R"(jTraceMetaRead:{"buffersize":32,"offset":0,"threadid":35,)"; + std::string expected_packet2 = R"("traceid":3})"; HandlePacket(server, expected_packet1+expected_packet2, "123456"); ASSERT_TRUE(result.get().Success()); ASSERT_EQ(buffer.size(), 3u); @@ -497,11 +496,10 @@ }); const char *expected_packet = - R"(jTraceConfigRead:{"threadid" : 35,"traceid" : 3})"; + R"(jTraceConfigRead:{"threadid":35,"traceid":3})"; std::string response1 = - R"({"buffersize" : 8192,"params" : {"psb" : 1,"tracetech" : "intel-pt"})"; - std::string response2 = - R"(],"metabuffersize" : 8192,"threadid" : 35,"type" : 1}])"; + R"({"buffersize":8192,"params":{"psb":1,"tracetech":"intel-pt"})"; + std::string response2 = R"(],"metabuffersize":8192,"threadid":35,"type":1}])"; HandlePacket(server, expected_packet, response1+response2); ASSERT_TRUE(result.get().Success()); ASSERT_EQ(options.getTraceBufferSize(), 8192u);