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