Path: blob/master/Utilities/cmcppdap/include/dap/serialization.h
3158 views
// Copyright 2019 Google LLC1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// https://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314#ifndef dap_serialization_h15#define dap_serialization_h1617#include "typeof.h"18#include "types.h"1920#include <cstddef> // ptrdiff_t21#include <type_traits>2223namespace dap {2425// Field describes a single field of a struct.26struct Field {27std::string name; // name of the field28ptrdiff_t offset; // offset of the field to the base of the struct29const TypeInfo* type; // type of the field30};3132////////////////////////////////////////////////////////////////////////////////33// Deserializer34////////////////////////////////////////////////////////////////////////////////3536// Deserializer is the interface used to decode data from structured storage.37// Methods that return a bool use this to indicate success.38class Deserializer {39public:40virtual ~Deserializer() = default;4142// deserialization methods for simple data types.43// If the stored object is not of the correct type, then these function will44// return false.45virtual bool deserialize(boolean*) const = 0;46virtual bool deserialize(integer*) const = 0;47virtual bool deserialize(number*) const = 0;48virtual bool deserialize(string*) const = 0;49virtual bool deserialize(object*) const = 0;50virtual bool deserialize(any*) const = 0;5152// count() returns the number of elements in the array object referenced by53// this Deserializer.54virtual size_t count() const = 0;5556// array() calls the provided std::function for deserializing each array57// element in the array object referenced by this Deserializer.58virtual bool array(const std::function<bool(Deserializer*)>&) const = 0;5960// field() calls the provided std::function for deserializing the field with61// the given name from the struct object referenced by this Deserializer.62virtual bool field(const std::string& name,63const std::function<bool(Deserializer*)>&) const = 0;6465// deserialize() delegates to TypeOf<T>::type()->deserialize().66template <typename T,67typename = std::enable_if<TypeOf<T>::has_custom_serialization>>68inline bool deserialize(T*) const;6970// deserialize() decodes an array.71template <typename T>72inline bool deserialize(dap::array<T>*) const;7374// deserialize() decodes an optional.75template <typename T>76inline bool deserialize(dap::optional<T>*) const;7778// deserialize() decodes an variant.79template <typename T0, typename... Types>80inline bool deserialize(dap::variant<T0, Types...>*) const;8182// deserialize() decodes the struct field f with the given name.83template <typename T>84inline bool field(const std::string& name, T* f) const;85};8687template <typename T, typename>88bool Deserializer::deserialize(T* ptr) const {89return TypeOf<T>::type()->deserialize(this, ptr);90}9192template <typename T>93bool Deserializer::deserialize(dap::array<T>* vec) const {94auto n = count();95vec->resize(n);96size_t i = 0;97if (!array([&](Deserializer* d) { return d->deserialize(&(*vec)[i++]); })) {98return false;99}100return true;101}102103template <typename T>104bool Deserializer::deserialize(dap::optional<T>* opt) const {105T v;106if (deserialize(&v)) {107*opt = v;108}109return true;110}111112template <typename T0, typename... Types>113bool Deserializer::deserialize(dap::variant<T0, Types...>* var) const {114return deserialize(&var->value);115}116117template <typename T>118bool Deserializer::field(const std::string& name, T* v) const {119return this->field(name,120[&](const Deserializer* d) { return d->deserialize(v); });121}122123////////////////////////////////////////////////////////////////////////////////124// Serializer125////////////////////////////////////////////////////////////////////////////////126class FieldSerializer;127128// Serializer is the interface used to encode data to structured storage.129// A Serializer is associated with a single storage object, whos type and value130// is assigned by a call to serialize().131// If serialize() is called multiple times on the same Serializer instance,132// the last type and value is stored.133// Methods that return a bool use this to indicate success.134class Serializer {135public:136virtual ~Serializer() = default;137138// serialization methods for simple data types.139virtual bool serialize(boolean) = 0;140virtual bool serialize(integer) = 0;141virtual bool serialize(number) = 0;142virtual bool serialize(const string&) = 0;143virtual bool serialize(const dap::object&) = 0;144virtual bool serialize(const any&) = 0;145146// array() encodes count array elements to the array object referenced by this147// Serializer. The std::function will be called count times, each time with a148// Serializer that should be used to encode the n'th array element's data.149virtual bool array(size_t count, const std::function<bool(Serializer*)>&) = 0;150151// object() begins encoding the object referenced by this Serializer.152// The std::function will be called with a FieldSerializer to serialize the153// object's fields.154virtual bool object(const std::function<bool(dap::FieldSerializer*)>&) = 0;155156// remove() deletes the object referenced by this Serializer.157// remove() can be used to serialize optionals with no value assigned.158virtual void remove() = 0;159160// serialize() delegates to TypeOf<T>::type()->serialize().161template <typename T,162typename = std::enable_if<TypeOf<T>::has_custom_serialization>>163inline bool serialize(const T&);164165// serialize() encodes the given array.166template <typename T>167inline bool serialize(const dap::array<T>&);168169// serialize() encodes the given optional.170template <typename T>171inline bool serialize(const dap::optional<T>& v);172173// serialize() encodes the given variant.174template <typename T0, typename... Types>175inline bool serialize(const dap::variant<T0, Types...>&);176177// deserialize() encodes the given string.178inline bool serialize(const char* v);179protected:180static inline const TypeInfo* get_any_type(const any&);181static inline const void* get_any_val(const any&);182};183184inline const TypeInfo* Serializer::get_any_type(const any& a){185return a.type;186}187const void* Serializer::get_any_val(const any& a) {188return a.value;189}190191template <typename T, typename>192bool Serializer::serialize(const T& object) {193return TypeOf<T>::type()->serialize(this, &object);194}195196template <typename T>197bool Serializer::serialize(const dap::array<T>& vec) {198auto it = vec.begin();199return array(vec.size(), [&](Serializer* s) { return s->serialize(*it++); });200}201202template <typename T>203bool Serializer::serialize(const dap::optional<T>& opt) {204if (!opt.has_value()) {205remove();206return true;207}208return serialize(opt.value());209}210211template <typename T0, typename... Types>212bool Serializer::serialize(const dap::variant<T0, Types...>& var) {213return serialize(var.value);214}215216bool Serializer::serialize(const char* v) {217return serialize(std::string(v));218}219220////////////////////////////////////////////////////////////////////////////////221// FieldSerializer222////////////////////////////////////////////////////////////////////////////////223224// FieldSerializer is the interface used to serialize fields of an object.225class FieldSerializer {226public:227using SerializeFunc = std::function<bool(Serializer*)>;228template <typename T>229using IsSerializeFunc = std::is_convertible<T, SerializeFunc>;230231virtual ~FieldSerializer() = default;232233// field() encodes a field to the struct object referenced by this Serializer.234// The SerializeFunc will be called with a Serializer used to encode the235// field's data.236virtual bool field(const std::string& name, const SerializeFunc&) = 0;237238// field() encodes the field with the given name and value.239template <240typename T,241typename = typename std::enable_if<!IsSerializeFunc<T>::value>::type>242inline bool field(const std::string& name, const T& v);243};244245template <typename T, typename>246bool FieldSerializer::field(const std::string& name, const T& v) {247return this->field(name, [&](Serializer* s) { return s->serialize(v); });248}249250} // namespace dap251252#endif // dap_serialization_h253254255