Hash :
45ee87e2
Author :
Date :
2021-05-17T13:45:25
Capture/Replay: Don't try to serialize blob without data The construct std::vector v; &v[0] doesn't go well with a checked STL, because the element 0 doesn't exists in an empty vector, and obviously it doesn't know that whether the pointer gets de-referenced later. Bug: angleproject:5980 Change-Id: I690c99bd12d74112fe1081ea3134b6ffb11ad23b Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2900226 Reviewed-by: Cody Northrop <cnorthrop@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Gert Wollny <gert.wollny@collabora.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// JsonSerializer.h: Implementation of a JSON based serializer
//
#ifndef LIBANGLE_JSONSERIALIZER_H_
#define LIBANGLE_JSONSERIALIZER_H_
#include "common/angleutils.h"
#if !defined(ANGLE_HAS_RAPIDJSON)
# error RapidJSON must be available to build this file.
#endif // !defined(ANGLE_HAS_RAPIDJSON)
#include <rapidjson/document.h>
#include <map>
#include <memory>
#include <sstream>
#include <stack>
#include <type_traits>
namespace angle
{
// Rapidjson has problems picking the right AddMember template for long
// integer types, so let's just make these values use 64 bit variants
template <typename T>
struct StoreAs
{
using Type = T;
};
template <>
struct StoreAs<unsigned long>
{
using Type = uint64_t;
};
template <>
struct StoreAs<signed long>
{
using Type = int64_t;
};
class JsonSerializer : public angle::NonCopyable
{
public:
JsonSerializer();
~JsonSerializer();
void startDocument(const std::string &name);
void endDocument();
void addCString(const std::string &name, const char *value);
void addString(const std::string &name, const std::string &value);
void addBlob(const std::string &name, const uint8_t *value, size_t length);
void startGroup(const std::string &name);
void endGroup();
const char *data() const;
std::vector<uint8_t> getData() const;
size_t length() const;
template <typename T>
void addScalar(const std::string &name, T value)
{
typename StoreAs<T>::Type v = value;
mGroupValueStack.top().insert(std::make_pair(name, rapidjson::Value(v)));
}
template <typename T>
void addVector(const std::string &name, const std::vector<T> &value)
{
rapidjson::Value array(rapidjson::kArrayType);
array.SetArray();
for (typename StoreAs<T>::Type v : value)
array.PushBack(v, mAllocator);
mGroupValueStack.top().insert(std::make_pair(name, std::move(array)));
}
template <typename T>
void addVectorAsHash(const std::string &name, const std::vector<T> &value)
{
if (!value.empty())
{
addBlob(name, reinterpret_cast<const uint8_t *>(&value[0]), value.size() * sizeof(T));
}
else
{
addCString(name, "null");
}
}
void addVectorOfStrings(const std::string &name, const std::vector<std::string> &value);
private:
using SortedValueGroup = std::multimap<std::string, rapidjson::Value>;
rapidjson::Value makeValueGroup(SortedValueGroup &group);
using ValuePointer = std::unique_ptr<rapidjson::Value>;
rapidjson::Document mDoc;
rapidjson::Document::AllocatorType &mAllocator;
std::stack<std::string> mGroupNameStack;
std::stack<SortedValueGroup> mGroupValueStack;
std::string mResult;
};
} // namespace angle
#endif // JSONSERIALIZER_H