9#ifndef LLDB_UTILITY_STRUCTUREDDATA_H
10#define LLDB_UTILITY_STRUCTUREDDATA_H
12#include "llvm/ADT/STLExtras.h"
13#include "llvm/ADT/SmallVector.h"
14#include "llvm/ADT/StringMap.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/Support/JSON.h"
55 template <
typename N>
class Integer;
78 typedef std::variant<UnsignedIntegerSP, SignedIntegerSP>
IntegerSP;
80 class Object :
public std::enable_shared_from_this<Object> {
87 virtual bool IsValid()
const {
return true; }
97 ?
static_cast<Array *
>(
this)
134 ?
static_cast<Float *
>(
this)
140 return ((f !=
nullptr) ? f->
GetValue() : fail_value);
151 return ((b !=
nullptr) ? b->
GetValue() : fail_value);
156 ?
static_cast<String *
>(
this)
178 virtual void Serialize(llvm::json::OStream &s)
const = 0;
181 llvm::json::OStream jso(s.
AsRawOstream(), pretty_print ? 2 : 0);
202 ForEach(std::function<
bool(
Object *
object)>
const &foreach_callback)
const {
203 for (
const auto &object_sp :
m_items) {
204 if (!foreach_callback(object_sp.get()))
225 template <
class IntType>
228 if constexpr (std::numeric_limits<IntType>::is_signed) {
229 if (
auto *signed_value = item_sp->GetAsSignedInteger())
230 return static_cast<IntType
>(signed_value->GetValue());
232 if (
auto *unsigned_value = item_sp->GetAsUnsignedInteger())
233 return static_cast<IntType
>(unsigned_value->GetValue());
241 if (
auto *string_value = item_sp->GetAsString())
242 return string_value->GetValue();
261 if (
auto *dict = item_sp->GetAsDictionary())
272 static_assert(std::is_integral<T>::value ||
273 std::is_floating_point<T>::value,
274 "value type should be integral");
275 if constexpr (std::numeric_limits<T>::is_signed)
276 AddItem(std::make_shared<SignedInteger>(value));
278 AddItem(std::make_shared<UnsignedInteger>(value));
284 AddItem(std::make_shared<String>(std::move(value)));
288 AddItem(std::make_shared<Boolean>(value));
291 void Serialize(llvm::json::OStream &s)
const override;
302 static_assert(std::is_integral<N>::value,
"N must be an integral type");
306 :
Object(std::numeric_limits<N>::is_signed
307 ?
lldb::eStructuredDataTypeSignedInteger
308 :
lldb::eStructuredDataTypeUnsignedInteger),
317 s.value(
static_cast<N
>(
m_value));
321 s.
Printf(std::numeric_limits<N>::is_signed ?
"%" PRId64 :
"%" PRIu64,
341 void Serialize(llvm::json::OStream &s)
const override;
360 void Serialize(llvm::json::OStream &s)
const override;
378 void Serialize(llvm::json::OStream &s)
const override;
392 SetType(lldb::eStructuredDataTypeInvalid);
406 for (
const auto &pair :
m_dict) {
407 if (!callback(pair.first(), pair.second.get()))
416 llvm::SmallVector<llvm::StringRef> keys;
417 keys.reserve(
m_dict.size());
418 for (
const auto &pair :
m_dict)
419 keys.push_back(pair.first());
421 for (llvm::StringRef key : keys) {
422 if (!callback(key,
m_dict.lookup(key).get()))
428 auto array_sp = std::make_shared<Array>();
429 for (
auto iter =
m_dict.begin(); iter !=
m_dict.end(); ++iter) {
430 auto key_object_sp = std::make_shared<String>(iter->first());
431 array_sp->Push(key_object_sp);
437 return m_dict.lookup(key);
441 bool success =
false;
443 if (value_sp.get()) {
453 template <
class IntType>
457 if constexpr (std::numeric_limits<IntType>::is_signed) {
458 if (
auto signed_value = value_sp->GetAsSignedInteger()) {
459 result =
static_cast<IntType
>(signed_value->GetValue());
463 if (
auto unsigned_value = value_sp->GetAsUnsignedInteger()) {
464 result =
static_cast<IntType
>(unsigned_value->GetValue());
472 template <
class IntType>
474 IntType default_val)
const {
477 result = default_val;
482 llvm::StringRef &result)
const {
484 if (value_sp.get()) {
485 if (
auto string_value = value_sp->GetAsString()) {
486 result = string_value->GetValue();
494 const char *default_val)
const {
498 result = default_val;
500 result = llvm::StringRef();
509 if (value_sp.get()) {
511 return (result !=
nullptr);
519 if (value_sp.get()) {
521 return (result !=
nullptr);
526 bool HasKey(llvm::StringRef key)
const {
return m_dict.contains(key); }
529 m_dict.insert_or_assign(key, std::move(value_sp));
533 static_assert(std::is_integral<T>::value ||
534 std::is_floating_point<T>::value,
535 "value type should be integral");
536 if constexpr (std::numeric_limits<T>::is_signed)
537 AddItem(key, std::make_shared<SignedInteger>(value));
539 AddItem(key, std::make_shared<UnsignedInteger>(value));
543 AddItem(key, std::make_shared<Float>(value));
547 AddItem(key, std::make_shared<String>(std::move(value)));
551 AddItem(key, std::make_shared<Boolean>(value));
554 void Serialize(llvm::json::OStream &s)
const override;
568 bool IsValid()
const override {
return false; }
570 void Serialize(llvm::json::OStream &s)
const override;
586 void Serialize(llvm::json::OStream &s)
const override;
595 return std::make_shared<Integer<T>>(value);
599 return std::make_shared<StructuredData::Float>(value);
602 return std::make_shared<StructuredData::Boolean>(value);
605 return std::make_shared<StructuredData::String>(value);
608 return std::make_shared<StructuredData::Generic>(value);
613 auto dict_sp = std::make_shared<StructuredData::Dictionary>();
614 dict_sp->AddItem(key, value_sp);
static llvm::raw_ostream & error(Stream &strm)
A stream class that can stream formatted output to a file.
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
void IndentLess(unsigned amount=2)
Decrement the current indentation level.
void IndentMore(unsigned amount=2)
Increment the current indentation level.
~Array() override=default
void AddItem(const ObjectSP &item)
void AddIntegerItem(T value)
void Serialize(llvm::json::OStream &s) const override
void AddFloatItem(double value)
ObjectSP GetItemAtIndex(size_t idx) const
void AddStringItem(llvm::StringRef value)
void AddBooleanItem(bool value)
std::vector< ObjectSP > collection
void GetDescription(lldb_private::Stream &s) const override
std::optional< IntType > GetItemAtIndexAsInteger(size_t idx) const
bool ForEach(std::function< bool(Object *object)> const &foreach_callback) const
ObjectSP operator[](size_t idx)
void Push(const ObjectSP &item)
std::optional< Dictionary * > GetItemAtIndexAsDictionary(size_t idx) const
Retrieves the element at index idx from a StructuredData::Array if it is a Dictionary.
std::optional< llvm::StringRef > GetItemAtIndexAsString(size_t idx) const
void Serialize(llvm::json::OStream &s) const override
~Boolean() override=default
void SetValue(bool value)
void GetDescription(lldb_private::Stream &s) const override
void AddBooleanItem(llvm::StringRef key, bool value)
void Serialize(llvm::json::OStream &s) const override
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
~Dictionary() override=default
void ForEachSorted(std::function< bool(llvm::StringRef key, Object *object)> const &callback) const
Like ForEach, but visits the entries in key order, for stable output.
Dictionary(ObjectSP obj_sp)
bool GetValueForKeyAsBoolean(llvm::StringRef key, bool &result) const
void AddFloatItem(llvm::StringRef key, double value)
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result, IntType default_val) const
llvm::StringMap< ObjectSP > m_dict
void AddIntegerItem(llvm::StringRef key, T value)
ObjectSP GetValueForKey(llvm::StringRef key) const
void AddStringItem(llvm::StringRef key, llvm::StringRef value)
void GetDescription(lldb_private::Stream &s) const override
bool HasKey(llvm::StringRef key) const
void AddItem(llvm::StringRef key, ObjectSP value_sp)
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
void ForEach(std::function< bool(llvm::StringRef key, Object *object)> const &callback) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result, const char *default_val) const
bool GetValueForKeyAsDictionary(llvm::StringRef key, Dictionary *&result) const
void SetValue(double value)
~Float() override=default
void Serialize(llvm::json::OStream &s) const override
void GetDescription(lldb_private::Stream &s) const override
void SetValue(void *value)
void GetDescription(lldb_private::Stream &s) const override
void Serialize(llvm::json::OStream &s) const override
Generic(void *object=nullptr)
bool IsValid() const override
void GetDescription(lldb_private::Stream &s) const override
void Serialize(llvm::json::OStream &s) const override
~Integer() override=default
void GetDescription(lldb_private::Stream &s) const override
bool IsValid() const override
void Serialize(llvm::json::OStream &s) const override
Dictionary * GetAsDictionary()
lldb::StructuredDataType m_type
virtual void Serialize(llvm::json::OStream &s) const =0
llvm::StringRef GetStringValue(const char *fail_value=nullptr)
void DumpToStdout(bool pretty_print=true) const
virtual void GetDescription(lldb_private::Stream &s) const
double GetFloatValue(double fail_value=0.0)
UnsignedInteger * GetAsUnsignedInteger()
virtual bool IsValid() const
Object(lldb::StructuredDataType t=lldb::eStructuredDataTypeInvalid)
int64_t GetSignedIntegerValue(int64_t fail_value=0)
bool GetBooleanValue(bool fail_value=false)
void SetType(lldb::StructuredDataType t)
void Dump(lldb_private::Stream &s, bool pretty_print=true) const
lldb::StructuredDataType GetType() const
SignedInteger * GetAsSignedInteger()
uint64_t GetUnsignedIntegerValue(uint64_t fail_value=0)
ObjectSP GetObjectForDotSeparatedPath(llvm::StringRef path)
virtual ~Object()=default
void GetDescription(lldb_private::Stream &s) const override
void SetValue(llvm::StringRef S)
llvm::StringRef GetValue()
void Serialize(llvm::json::OStream &s) const override
String(llvm::StringRef S)
A class which can hold structured data.
static StructuredData::ObjectSP FromFloat(double value)
static bool IsRecordType(const ObjectSP object_sp)
static StructuredData::ObjectSP FromString(llvm::StringRef value)
std::shared_ptr< Generic > GenericSP
std::shared_ptr< UnsignedInteger > UnsignedIntegerSP
std::shared_ptr< Float > FloatSP
static ObjectSP FromInteger(T value)
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
Integer< int64_t > SignedInteger
static StructuredData::ObjectSP FromKeyValue(llvm::StringRef key, const StructuredData::ObjectSP &value_sp)
static ObjectSP ParseJSON(llvm::StringRef json_text)
std::shared_ptr< String > StringSP
static StructuredData::ObjectSP FromBoolean(bool value)
std::shared_ptr< Array > ArraySP
std::shared_ptr< Boolean > BooleanSP
static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error)
std::shared_ptr< SignedInteger > SignedIntegerSP
static StructuredData::ObjectSP FromGeneric(void *value)
std::variant< UnsignedIntegerSP, SignedIntegerSP > IntegerSP
Integer< uint64_t > UnsignedInteger
A class that represents a running process on the host machine.
@ eStructuredDataTypeFloat
@ eStructuredDataTypeDictionary
@ eStructuredDataTypeInvalid
@ eStructuredDataTypeInteger
@ eStructuredDataTypeGeneric
@ eStructuredDataTypeArray
@ eStructuredDataTypeSignedInteger
@ eStructuredDataTypeUnsignedInteger
@ eStructuredDataTypeBoolean
@ eStructuredDataTypeString