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