Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Utility/StructuredData.h
Line
Count
Source (jump to first uncovered line)
1
//===-- StructuredData.h ----------------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLDB_UTILITY_STRUCTUREDDATA_H
10
#define LLDB_UTILITY_STRUCTUREDDATA_H
11
12
#include "llvm/ADT/StringRef.h"
13
#include "llvm/Support/JSON.h"
14
15
#include "lldb/Utility/ConstString.h"
16
#include "lldb/Utility/FileSpec.h"
17
#include "lldb/Utility/Stream.h"
18
#include "lldb/lldb-enumerations.h"
19
20
#include <cassert>
21
#include <cstddef>
22
#include <cstdint>
23
#include <functional>
24
#include <map>
25
#include <memory>
26
#include <string>
27
#include <type_traits>
28
#include <utility>
29
#include <vector>
30
31
namespace lldb_private {
32
class Status;
33
}
34
35
namespace lldb_private {
36
37
/// \class StructuredData StructuredData.h "lldb/Utility/StructuredData.h"
38
/// A class which can hold structured data
39
///
40
/// The StructuredData class is designed to hold the data from a JSON or plist
41
/// style file -- a serialized data structure with dictionaries (maps,
42
/// hashes), arrays, and concrete values like integers, floating point
43
/// numbers, strings, booleans.
44
///
45
/// StructuredData does not presuppose any knowledge of the schema for the
46
/// data it is holding; it can parse JSON data, for instance, and other parts
47
/// of lldb can iterate through the parsed data set to find keys and values
48
/// that may be present.
49
50
class StructuredData {
51
public:
52
  class Object;
53
  class Array;
54
  class Integer;
55
  class Float;
56
  class Boolean;
57
  class String;
58
  class Dictionary;
59
  class Generic;
60
61
  typedef std::shared_ptr<Object> ObjectSP;
62
  typedef std::shared_ptr<Array> ArraySP;
63
  typedef std::shared_ptr<Integer> IntegerSP;
64
  typedef std::shared_ptr<Float> FloatSP;
65
  typedef std::shared_ptr<Boolean> BooleanSP;
66
  typedef std::shared_ptr<String> StringSP;
67
  typedef std::shared_ptr<Dictionary> DictionarySP;
68
  typedef std::shared_ptr<Generic> GenericSP;
69
70
  class Object : public std::enable_shared_from_this<Object> {
71
  public:
72
    Object(lldb::StructuredDataType t = lldb::eStructuredDataTypeInvalid)
73
5.63M
        : m_type(t) {}
74
75
5.63M
    virtual ~Object() = default;
76
77
321
    virtual bool IsValid() const { return true; }
78
79
0
    virtual void Clear() { m_type = lldb::eStructuredDataTypeInvalid; }
80
81
15.1k
    lldb::StructuredDataType GetType() const { return m_type; }
82
83
0
    void SetType(lldb::StructuredDataType t) { m_type = t; }
84
85
462k
    Array *GetAsArray() {
86
462k
      return ((m_type == lldb::eStructuredDataTypeArray)
87
462k
                  ? 
static_cast<Array *>(this)462k
88
462k
                  : 
nullptr1
);
89
462k
    }
90
91
1.07M
    Dictionary *GetAsDictionary() {
92
1.07M
      return ((m_type == lldb::eStructuredDataTypeDictionary)
93
1.07M
                  ? static_cast<Dictionary *>(this)
94
18.4E
                  : nullptr);
95
1.07M
    }
96
97
3.17M
    Integer *GetAsInteger() {
98
3.17M
      return ((m_type == lldb::eStructuredDataTypeInteger)
99
3.17M
                  ? 
static_cast<Integer *>(this)3.17M
100
3.17M
                  : 
nullptr1
);
101
3.17M
    }
102
103
79.6k
    uint64_t GetIntegerValue(uint64_t fail_value = 0) {
104
79.6k
      Integer *integer = GetAsInteger();
105
79.6k
      return ((integer != nullptr) ? 
integer->GetValue()79.6k
:
fail_value1
);
106
79.6k
    }
107
108
1
    Float *GetAsFloat() {
109
1
      return ((m_type == lldb::eStructuredDataTypeFloat)
110
1
                  ? static_cast<Float *>(this)
111
1
                  : 
nullptr0
);
112
1
    }
113
114
1
    double GetFloatValue(double fail_value = 0.0) {
115
1
      Float *f = GetAsFloat();
116
1
      return ((f != nullptr) ? f->GetValue() : 
fail_value0
);
117
1
    }
118
119
10.8k
    Boolean *GetAsBoolean() {
120
10.8k
      return ((m_type == lldb::eStructuredDataTypeBoolean)
121
10.8k
                  ? static_cast<Boolean *>(this)
122
10.8k
                  : 
nullptr0
);
123
10.8k
    }
124
125
10.7k
    bool GetBooleanValue(bool fail_value = false) {
126
10.7k
      Boolean *b = GetAsBoolean();
127
10.7k
      return ((b != nullptr) ? b->GetValue() : 
fail_value0
);
128
10.7k
    }
129
130
1.31M
    String *GetAsString() {
131
1.31M
      return ((m_type == lldb::eStructuredDataTypeString)
132
1.31M
                  ? static_cast<String *>(this)
133
1.31M
                  : 
nullptr0
);
134
1.31M
    }
135
136
310k
    llvm::StringRef GetStringValue(const char *fail_value = nullptr) {
137
310k
      String *s = GetAsString();
138
310k
      if (s)
139
310k
        return s->GetValue();
140
141
1
      return fail_value;
142
310k
    }
143
144
2.11k
    Generic *GetAsGeneric() {
145
2.11k
      return ((m_type == lldb::eStructuredDataTypeGeneric)
146
2.11k
                  ? static_cast<Generic *>(this)
147
2.11k
                  : 
nullptr0
);
148
2.11k
    }
149
150
    ObjectSP GetObjectForDotSeparatedPath(llvm::StringRef path);
151
152
    void DumpToStdout(bool pretty_print = true) const;
153
154
    virtual void Serialize(llvm::json::OStream &s) const = 0;
155
156
8.80k
    void Dump(lldb_private::Stream &s, bool pretty_print = true) const {
157
8.80k
      llvm::json::OStream jso(s.AsRawOstream(), pretty_print ? 
27
:
08.80k
);
158
8.80k
      Serialize(jso);
159
8.80k
    }
160
161
  private:
162
    lldb::StructuredDataType m_type;
163
  };
164
165
  class Array : public Object {
166
  public:
167
183k
    Array() : Object(lldb::eStructuredDataTypeArray) {}
168
169
183k
    ~Array() override = default;
170
171
    bool
172
25.1k
    ForEach(std::function<bool(Object *object)> const &foreach_callback) const {
173
61.5k
      for (const auto &object_sp : m_items) {
174
61.5k
        if (!foreach_callback(object_sp.get()))
175
0
          return false;
176
61.5k
      }
177
25.1k
      return true;
178
25.1k
    }
179
180
733k
    size_t GetSize() const { return m_items.size(); }
181
182
0
    ObjectSP operator[](size_t idx) {
183
0
      if (idx < m_items.size())
184
0
        return m_items[idx];
185
0
      return ObjectSP();
186
0
    }
187
188
572k
    ObjectSP GetItemAtIndex(size_t idx) const {
189
572k
      assert(idx < GetSize());
190
572k
      if (idx < m_items.size())
191
572k
        return m_items[idx];
192
0
      return ObjectSP();
193
572k
    }
194
195
    template <class IntType>
196
9
    bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const {
197
9
      ObjectSP value_sp = GetItemAtIndex(idx);
198
9
      if (value_sp.get()) {
199
9
        if (auto int_value = value_sp->GetAsInteger()) {
200
9
          result = static_cast<IntType>(int_value->GetValue());
201
9
          return true;
202
9
        }
203
9
      }
204
0
      return false;
205
9
    }
bool lldb_private::StructuredData::Array::GetItemAtIndexAsInteger<unsigned int>(unsigned long, unsigned int&) const
Line
Count
Source
196
9
    bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const {
197
9
      ObjectSP value_sp = GetItemAtIndex(idx);
198
9
      if (value_sp.get()) {
199
9
        if (auto int_value = value_sp->GetAsInteger()) {
200
9
          result = static_cast<IntType>(int_value->GetValue());
201
9
          return true;
202
9
        }
203
9
      }
204
0
      return false;
205
9
    }
Unexecuted instantiation: bool lldb_private::StructuredData::Array::GetItemAtIndexAsInteger<unsigned long long>(unsigned long, unsigned long long&) const
206
207
    template <class IntType>
208
    bool GetItemAtIndexAsInteger(size_t idx, IntType &result,
209
                                 IntType default_val) const {
210
      bool success = GetItemAtIndexAsInteger(idx, result);
211
      if (!success)
212
        result = default_val;
213
      return success;
214
    }
215
216
142
    bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result) const {
217
142
      ObjectSP value_sp = GetItemAtIndex(idx);
218
142
      if (value_sp.get()) {
219
142
        if (auto string_value = value_sp->GetAsString()) {
220
142
          result = string_value->GetValue();
221
142
          return true;
222
142
        }
223
142
      }
224
0
      return false;
225
142
    }
226
227
    bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result,
228
0
                                llvm::StringRef default_val) const {
229
0
      bool success = GetItemAtIndexAsString(idx, result);
230
0
      if (!success)
231
0
        result = default_val;
232
0
      return success;
233
0
    }
234
235
7
    bool GetItemAtIndexAsString(size_t idx, ConstString &result) const {
236
7
      ObjectSP value_sp = GetItemAtIndex(idx);
237
7
      if (value_sp.get()) {
238
7
        if (auto string_value = value_sp->GetAsString()) {
239
7
          result = ConstString(string_value->GetValue());
240
7
          return true;
241
7
        }
242
7
      }
243
0
      return false;
244
7
    }
245
246
    bool GetItemAtIndexAsString(size_t idx, ConstString &result,
247
0
                                const char *default_val) const {
248
0
      bool success = GetItemAtIndexAsString(idx, result);
249
0
      if (!success)
250
0
        result.SetCString(default_val);
251
0
      return success;
252
0
    }
253
254
152
    bool GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const {
255
152
      result = nullptr;
256
152
      ObjectSP value_sp = GetItemAtIndex(idx);
257
152
      if (value_sp.get()) {
258
152
        result = value_sp->GetAsDictionary();
259
152
        return (result != nullptr);
260
152
      }
261
0
      return false;
262
152
    }
263
264
0
    bool GetItemAtIndexAsArray(size_t idx, Array *&result) const {
265
0
      result = nullptr;
266
0
      ObjectSP value_sp = GetItemAtIndex(idx);
267
0
      if (value_sp.get()) {
268
0
        result = value_sp->GetAsArray();
269
0
        return (result != nullptr);
270
0
      }
271
0
      return false;
272
0
    }
273
274
109
    void Push(const ObjectSP &item) { m_items.push_back(item); }
275
276
766k
    void AddItem(const ObjectSP &item) { m_items.push_back(item); }
277
278
    void Serialize(llvm::json::OStream &s) const override;
279
280
  protected:
281
    typedef std::vector<ObjectSP> collection;
282
    collection m_items;
283
  };
284
285
  class Integer : public Object {
286
  public:
287
    Integer(uint64_t i = 0)
288
3.33M
        : Object(lldb::eStructuredDataTypeInteger), m_value(i) {}
289
290
3.33M
    ~Integer() override = default;
291
292
781
    void SetValue(uint64_t value) { m_value = value; }
293
294
3.17M
    uint64_t GetValue() { return m_value; }
295
296
    void Serialize(llvm::json::OStream &s) const override;
297
298
  protected:
299
    uint64_t m_value;
300
  };
301
302
  class Float : public Object {
303
  public:
304
    Float(double d = 0.0)
305
84
        : Object(lldb::eStructuredDataTypeFloat), m_value(d) {}
306
307
84
    ~Float() override = default;
308
309
0
    void SetValue(double value) { m_value = value; }
310
311
1
    double GetValue() { return m_value; }
312
313
    void Serialize(llvm::json::OStream &s) const override;
314
315
  protected:
316
    double m_value;
317
  };
318
319
  class Boolean : public Object {
320
  public:
321
    Boolean(bool b = false)
322
16.8k
        : Object(lldb::eStructuredDataTypeBoolean), m_value(b) {}
323
324
16.8k
    ~Boolean() override = default;
325
326
12
    void SetValue(bool value) { m_value = value; }
327
328
10.8k
    bool GetValue() { return m_value; }
329
330
    void Serialize(llvm::json::OStream &s) const override;
331
332
  protected:
333
    bool m_value;
334
  };
335
336
  class String : public Object {
337
  public:
338
855
    String() : Object(lldb::eStructuredDataTypeString) {}
339
    explicit String(llvm::StringRef S)
340
1.32M
        : Object(lldb::eStructuredDataTypeString), m_value(S) {}
341
342
855
    void SetValue(llvm::StringRef S) { m_value = std::string(S); }
343
344
1.31M
    llvm::StringRef GetValue() { return m_value; }
345
346
    void Serialize(llvm::json::OStream &s) const override;
347
348
  protected:
349
    std::string m_value;
350
  };
351
352
  class Dictionary : public Object {
353
  public:
354
777k
    Dictionary() : Object(lldb::eStructuredDataTypeDictionary) {}
355
356
0
    Dictionary(ObjectSP obj_sp) : Object(lldb::eStructuredDataTypeDictionary) {
357
0
      if (!obj_sp || obj_sp->GetType() != lldb::eStructuredDataTypeDictionary) {
358
0
        SetType(lldb::eStructuredDataTypeInvalid);
359
0
        return;
360
0
      }
361
0
362
0
      Dictionary *dict = obj_sp->GetAsDictionary();
363
0
      m_dict = dict->m_dict;
364
0
    }
365
366
777k
    ~Dictionary() override = default;
367
368
2
    size_t GetSize() const { return m_dict.size(); }
369
370
    void ForEach(std::function<bool(ConstString key, Object *object)> const
371
26.5k
                     &callback) const {
372
410k
      for (const auto &pair : m_dict) {
373
410k
        if (!callback(pair.first, pair.second.get()))
374
0
          break;
375
410k
      }
376
26.5k
    }
377
378
7
    ObjectSP GetKeys() const {
379
7
      auto object_sp = std::make_shared<Array>();
380
7
      collection::const_iterator iter;
381
116
      for (iter = m_dict.begin(); iter != m_dict.end(); 
++iter109
) {
382
109
        auto key_object_sp = std::make_shared<String>();
383
109
        key_object_sp->SetValue(iter->first.AsCString());
384
109
        object_sp->Push(key_object_sp);
385
109
      }
386
7
      return object_sp;
387
7
    }
388
389
4.66M
    ObjectSP GetValueForKey(llvm::StringRef key) const {
390
4.66M
      ObjectSP value_sp;
391
4.66M
      if (
!key.empty()4.66M
) {
392
4.66M
        ConstString key_cs(key);
393
4.66M
        collection::const_iterator iter = m_dict.find(key_cs);
394
4.66M
        if (iter != m_dict.end())
395
4.65M
          value_sp = iter->second;
396
4.66M
      }
397
4.66M
      return value_sp;
398
4.66M
    }
399
400
105
    bool GetValueForKeyAsBoolean(llvm::StringRef key, bool &result) const {
401
105
      bool success = false;
402
105
      ObjectSP value_sp = GetValueForKey(key);
403
105
      if (value_sp.get()) {
404
105
        Boolean *result_ptr = value_sp->GetAsBoolean();
405
105
        if (result_ptr) {
406
105
          result = result_ptr->GetValue();
407
105
          success = true;
408
105
        }
409
105
      }
410
105
      return success;
411
105
    }
412
    template <class IntType>
413
37.2k
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
414
37.2k
      ObjectSP value_sp = GetValueForKey(key);
415
37.2k
      if (value_sp) {
416
36.9k
        if (auto int_value = value_sp->GetAsInteger()) {
417
36.9k
          result = static_cast<IntType>(int_value->GetValue());
418
36.9k
          return true;
419
36.9k
        }
420
36.9k
      }
421
213
      return false;
422
37.2k
    }
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<int>(llvm::StringRef, int&) const
Line
Count
Source
413
26
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
414
26
      ObjectSP value_sp = GetValueForKey(key);
415
26
      if (value_sp) {
416
26
        if (auto int_value = value_sp->GetAsInteger()) {
417
26
          result = static_cast<IntType>(int_value->GetValue());
418
26
          return true;
419
26
        }
420
26
      }
421
0
      return false;
422
26
    }
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<unsigned long long>(llvm::StringRef, unsigned long long&) const
Line
Count
Source
413
36.2k
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
414
36.2k
      ObjectSP value_sp = GetValueForKey(key);
415
36.2k
      if (value_sp) {
416
36.2k
        if (auto int_value = value_sp->GetAsInteger()) {
417
36.2k
          result = static_cast<IntType>(int_value->GetValue());
418
36.2k
          return true;
419
36.2k
        }
420
36.2k
      }
421
35
      return false;
422
36.2k
    }
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<unsigned int>(llvm::StringRef, unsigned int&) const
Line
Count
Source
413
581
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
414
581
      ObjectSP value_sp = GetValueForKey(key);
415
581
      if (value_sp) {
416
403
        if (auto int_value = value_sp->GetAsInteger()) {
417
403
          result = static_cast<IntType>(int_value->GetValue());
418
403
          return true;
419
403
        }
420
403
      }
421
178
      return false;
422
581
    }
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<unsigned short>(llvm::StringRef, unsigned short&) const
Line
Count
Source
413
5
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
414
5
      ObjectSP value_sp = GetValueForKey(key);
415
5
      if (value_sp) {
416
5
        if (auto int_value = value_sp->GetAsInteger()) {
417
5
          result = static_cast<IntType>(int_value->GetValue());
418
5
          return true;
419
5
        }
420
5
      }
421
0
      return false;
422
5
    }
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<long long>(llvm::StringRef, long long&) const
Line
Count
Source
413
147
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
414
147
      ObjectSP value_sp = GetValueForKey(key);
415
147
      if (value_sp) {
416
147
        if (auto int_value = value_sp->GetAsInteger()) {
417
147
          result = static_cast<IntType>(int_value->GetValue());
418
147
          return true;
419
147
        }
420
147
      }
421
0
      return false;
422
147
    }
Unexecuted instantiation: bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<lldb::Format>(llvm::StringRef, lldb::Format&) const
Unexecuted instantiation: bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<lldb::Encoding>(llvm::StringRef, lldb::Encoding&) const
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<unsigned long>(llvm::StringRef, unsigned long&) const
Line
Count
Source
413
147
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
414
147
      ObjectSP value_sp = GetValueForKey(key);
415
147
      if (value_sp) {
416
147
        if (auto int_value = value_sp->GetAsInteger()) {
417
147
          result = static_cast<IntType>(int_value->GetValue());
418
147
          return true;
419
147
        }
420
147
      }
421
0
      return false;
422
147
    }
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<lldb::StopReason>(llvm::StringRef, lldb::StopReason&) const
Line
Count
Source
413
6
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const {
414
6
      ObjectSP value_sp = GetValueForKey(key);
415
6
      if (value_sp) {
416
6
        if (auto int_value = value_sp->GetAsInteger()) {
417
6
          result = static_cast<IntType>(int_value->GetValue());
418
6
          return true;
419
6
        }
420
6
      }
421
0
      return false;
422
6
    }
423
424
    template <class IntType>
425
    bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result,
426
1.89k
                                 IntType default_val) const {
427
1.89k
      bool success = GetValueForKeyAsInteger<IntType>(key, result);
428
1.89k
      if (!success)
429
196
        result = default_val;
430
1.89k
      return success;
431
1.89k
    }
Unexecuted instantiation: bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<lldb::Format>(llvm::StringRef, lldb::Format&, lldb::Format) const
Unexecuted instantiation: bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<lldb::Encoding>(llvm::StringRef, lldb::Encoding&, lldb::Encoding) const
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<unsigned long>(llvm::StringRef, unsigned long&, unsigned long) const
Line
Count
Source
426
147
                                 IntType default_val) const {
427
147
      bool success = GetValueForKeyAsInteger<IntType>(key, result);
428
147
      if (!success)
429
0
        result = default_val;
430
147
      return success;
431
147
    }
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<unsigned int>(llvm::StringRef, unsigned int&, unsigned int) const
Line
Count
Source
426
423
                                 IntType default_val) const {
427
423
      bool success = GetValueForKeyAsInteger<IntType>(key, result);
428
423
      if (!success)
429
172
        result = default_val;
430
423
      return success;
431
423
    }
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<int>(llvm::StringRef, int&, int) const
Line
Count
Source
426
6
                                 IntType default_val) const {
427
6
      bool success = GetValueForKeyAsInteger<IntType>(key, result);
428
6
      if (!success)
429
0
        result = default_val;
430
6
      return success;
431
6
    }
bool lldb_private::StructuredData::Dictionary::GetValueForKeyAsInteger<unsigned long long>(llvm::StringRef, unsigned long long&, unsigned long long) const
Line
Count
Source
426
1.31k
                                 IntType default_val) const {
427
1.31k
      bool success = GetValueForKeyAsInteger<IntType>(key, result);
428
1.31k
      if (!success)
429
24
        result = default_val;
430
1.31k
      return success;
431
1.31k
    }
432
433
    bool GetValueForKeyAsString(llvm::StringRef key,
434
35.6k
                                llvm::StringRef &result) const {
435
35.6k
      ObjectSP value_sp = GetValueForKey(key);
436
35.6k
      if (value_sp.get()) {
437
35.5k
        if (auto string_value = value_sp->GetAsString()) {
438
35.5k
          result = string_value->GetValue();
439
35.5k
          return true;
440
35.5k
        }
441
35.5k
      }
442
117
      return false;
443
35.6k
    }
444
445
    bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result,
446
147
                                const char *default_val) const {
447
147
      bool success = GetValueForKeyAsString(key, result);
448
147
      if (!success) {
449
0
        if (default_val)
450
0
          result = default_val;
451
0
        else
452
0
          result = llvm::StringRef();
453
0
      }
454
147
      return success;
455
147
    }
456
457
    bool GetValueForKeyAsString(llvm::StringRef key,
458
294
                                ConstString &result) const {
459
294
      ObjectSP value_sp = GetValueForKey(key);
460
294
      if (value_sp.get()) {
461
217
        if (auto string_value = value_sp->GetAsString()) {
462
217
          result = ConstString(string_value->GetValue());
463
217
          return true;
464
217
        }
465
217
      }
466
77
      return false;
467
294
    }
468
469
    bool GetValueForKeyAsString(llvm::StringRef key, ConstString &result,
470
294
                                const char *default_val) const {
471
294
      bool success = GetValueForKeyAsString(key, result);
472
294
      if (!success)
473
77
        result.SetCString(default_val);
474
294
      return success;
475
294
    }
476
477
    bool GetValueForKeyAsDictionary(llvm::StringRef key,
478
146
                                    Dictionary *&result) const {
479
146
      result = nullptr;
480
146
      ObjectSP value_sp = GetValueForKey(key);
481
146
      if (value_sp.get()) {
482
115
        result = value_sp->GetAsDictionary();
483
115
        return (result != nullptr);
484
115
      }
485
31
      return false;
486
146
    }
487
488
219
    bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const {
489
219
      result = nullptr;
490
219
      ObjectSP value_sp = GetValueForKey(key);
491
219
      if (value_sp.get()) {
492
49
        result = value_sp->GetAsArray();
493
49
        return (result != nullptr);
494
49
      }
495
170
      return false;
496
219
    }
497
498
2.76M
    bool HasKey(llvm::StringRef key) const {
499
2.76M
      ConstString key_cs(key);
500
2.76M
      collection::const_iterator search = m_dict.find(key_cs);
501
2.76M
      return search != m_dict.end();
502
2.76M
    }
503
504
4.83M
    void AddItem(llvm::StringRef key, ObjectSP value_sp) {
505
4.83M
      ConstString key_cs(key);
506
4.83M
      m_dict[key_cs] = std::move(value_sp);
507
4.83M
    }
508
509
16.8k
    void AddIntegerItem(llvm::StringRef key, uint64_t value) {
510
16.8k
      AddItem(key, std::make_shared<Integer>(value));
511
16.8k
    }
512
513
0
    void AddFloatItem(llvm::StringRef key, double value) {
514
0
      AddItem(key, std::make_shared<Float>(value));
515
0
    }
516
517
1.05k
    void AddStringItem(llvm::StringRef key, llvm::StringRef value) {
518
1.05k
      AddItem(key, std::make_shared<String>(std::move(value)));
519
1.05k
    }
520
521
3.51k
    void AddBooleanItem(llvm::StringRef key, bool value) {
522
3.51k
      AddItem(key, std::make_shared<Boolean>(value));
523
3.51k
    }
524
525
    void Serialize(llvm::json::OStream &s) const override;
526
527
  protected:
528
    typedef std::map<ConstString, ObjectSP> collection;
529
    collection m_dict;
530
  };
531
532
  class Null : public Object {
533
  public:
534
0
    Null() : Object(lldb::eStructuredDataTypeNull) {}
535
536
0
    ~Null() override = default;
537
538
0
    bool IsValid() const override { return false; }
539
540
    void Serialize(llvm::json::OStream &s) const override;
541
  };
542
543
  class Generic : public Object {
544
  public:
545
    explicit Generic(void *object = nullptr)
546
287
        : Object(lldb::eStructuredDataTypeGeneric), m_object(object) {}
547
548
0
    void SetValue(void *value) { m_object = value; }
549
550
4.42k
    void *GetValue() const { return m_object; }
551
552
0
    bool IsValid() const override { return m_object != nullptr; }
553
554
    void Serialize(llvm::json::OStream &s) const override;
555
556
  private:
557
    void *m_object;
558
  };
559
560
  static ObjectSP ParseJSON(const std::string &json_text);
561
  static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error);
562
};
563
564
} // namespace lldb_private
565
566
#endif // LLDB_UTILITY_STRUCTUREDDATA_H