• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // JsonSerializer.h: Implementation of a JSON based serializer
7 //
8 
9 #ifndef COMMON_JSONSERIALIZER_H_
10 #define COMMON_JSONSERIALIZER_H_
11 
12 #include "common/angleutils.h"
13 
14 #if !defined(ANGLE_HAS_RAPIDJSON)
15 #    error RapidJSON must be available to build this file.
16 #endif  // !defined(ANGLE_HAS_RAPIDJSON)
17 
18 #include <rapidjson/document.h>
19 
20 #include <map>
21 #include <memory>
22 #include <sstream>
23 #include <stack>
24 #include <type_traits>
25 
26 namespace angle
27 {
28 
29 // Rapidjson has problems picking the right AddMember template for long
30 // integer types, so let's just make these values use 64 bit variants
31 template <typename T>
32 struct StoreAs
33 {
34     using Type = T;
35 };
36 
37 template <>
38 struct StoreAs<unsigned long>
39 {
40     using Type = uint64_t;
41 };
42 
43 template <>
44 struct StoreAs<signed long>
45 {
46     using Type = int64_t;
47 };
48 
49 class JsonSerializer : public angle::NonCopyable
50 {
51   public:
52     JsonSerializer();
53     ~JsonSerializer();
54 
55     void addCString(const std::string &name, const char *value);
56 
57     void addString(const std::string &name, const std::string &value);
58 
59     void addBlob(const std::string &name, const uint8_t *value, size_t length);
60 
61     void startGroup(const std::string &name);
62 
63     void endGroup();
64 
65     template <typename T>
66     void addScalar(const std::string &name, T value)
67     {
68         typename StoreAs<T>::Type v = value;
69         addValue(name, rapidjson::Value(v));
70     }
71 
72     template <typename T>
73     void addVector(const std::string &name, const std::vector<T> &value)
74     {
75         rapidjson::Value arr(rapidjson::kArrayType);
76         arr.SetArray();
77 
78         for (typename StoreAs<T>::Type v : value)
79         {
80             arr.PushBack(v, mAllocator);
81         }
82 
83         addValue(name, std::move(arr));
84     }
85 
86     template <typename T>
87     void addVectorAsHash(const std::string &name, const std::vector<T> &value)
88     {
89         if (!value.empty())
90         {
91             addBlob(name, reinterpret_cast<const uint8_t *>(&value[0]), value.size() * sizeof(T));
92         }
93         else
94         {
95             addCString(name, "null");
96         }
97     }
98 
99     void addVectorOfStrings(const std::string &name, const std::vector<std::string> &value);
100 
101     void addBool(const std::string &name, bool value);
102 
103     void addHexValue(const std::string &name, int value);
104 
105     const char *data();
106 
107     std::vector<uint8_t> getData();
108 
109     size_t length();
110 
111   private:
112     using SortedValueGroup = std::multimap<std::string, rapidjson::Value>;
113 
114     rapidjson::Value makeValueGroup(SortedValueGroup &group);
115     void addValue(const std::string &name, rapidjson::Value &&value);
116 
117     void ensureEndDocument();
118 
119     using ValuePointer = std::unique_ptr<rapidjson::Value>;
120 
121     rapidjson::Document mDoc;
122     rapidjson::Document::AllocatorType &mAllocator;
123     std::stack<std::string> mGroupNameStack;
124     std::stack<SortedValueGroup> mGroupValueStack;
125     std::string mResult;
126 };
127 
128 }  // namespace angle
129 
130 #endif  // COMMON_JSONSERIALIZER_H_
131