%PDF- <> %âãÏÓ endobj 2 0 obj <> endobj 3 0 obj <>/ExtGState<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/Annots[ 28 0 R 29 0 R] /MediaBox[ 0 0 595.5 842.25] /Contents 4 0 R/Group<>/Tabs/S>> endobj ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<> endobj 2 0 obj<>endobj 2 0 obj<>es 3 0 R>> endobj 2 0 obj<> ox[ 0.000000 0.000000 609.600000 935.600000]/Fi endobj 3 0 obj<> endobj 7 1 obj<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]>>/Subtype/Form>> stream
// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_CRDTP_SERIALIZER_TRAITS_H_ #define V8_CRDTP_SERIALIZER_TRAITS_H_ #include <memory> #include <string> #include <vector> #include "cbor.h" #include "maybe.h" #include "span.h" namespace v8_crdtp { // ============================================================================= // SerializerTraits - Encodes field values of protocol objects in CBOR. // ============================================================================= // // A family of serialization functions which are used by FieldSerializerTraits // (below) to encode field values in CBOR. Conceptually, it's this: // // Serialize(bool value, std::vector<uint8_t>* out); // Serialize(int32_t value, std::vector<uint8_t>* out); // Serialize(double value, std::vector<uint8_t>* out); // ... // // However, if this was to use straight-forward overloading, implicit // type conversions would lead to ambiguity - e.g., a bool could be // represented as an int32_t, but it should really be encoded as a bool. // The template parameterized / specialized structs accomplish this. // // SerializerTraits<bool>::Serialize(bool value, std::vector<uint8_t>* out); // SerializerTraits<int32>::Serialize(int32_t value, std::vector<uint8_t>* out); // SerializerTraits<double>::Serialize(double value, std::vector<uint8_t>* out); template <typename T> struct SerializerTraits { // |Serializable| (defined in serializable.h) already knows how to serialize // to CBOR, so we can just delegate. This covers domain specific types, // protocol::Binary, etc. // However, we use duck-typing here, because Exported, which is part of the V8 // headers also comes with AppendSerialized, and logically it's the same type, // but it lives in a different namespace (v8_inspector::protocol::Exported). template < typename LikeSerializable, typename std::enable_if_t<std::is_member_pointer<decltype( &LikeSerializable::AppendSerialized)>{}, int> = 0> static void Serialize(const LikeSerializable& value, std::vector<uint8_t>* out) { value.AppendSerialized(out); } }; // This covers std::string, which is assumed to be UTF-8. // The two other string implementations that are used in the protocol bindings: // - WTF::String, for which the SerializerTraits specialization is located // in third_party/blink/renderer/core/inspector/v8-inspector-string.h. // - v8_inspector::String16, implemented in v8/src/inspector/string-16.h // along with its SerializerTraits specialization. template <> struct SerializerTraits<std::string> { static void Serialize(const std::string& str, std::vector<uint8_t>* out) { cbor::EncodeString8(SpanFrom(str), out); } }; template <> struct SerializerTraits<bool> { static void Serialize(bool value, std::vector<uint8_t>* out) { out->push_back(value ? cbor::EncodeTrue() : cbor::EncodeFalse()); } }; template <> struct SerializerTraits<int32_t> { static void Serialize(int32_t value, std::vector<uint8_t>* out) { cbor::EncodeInt32(value, out); } }; template <> struct SerializerTraits<double> { static void Serialize(double value, std::vector<uint8_t>* out) { cbor::EncodeDouble(value, out); } }; template <typename T> struct SerializerTraits<std::vector<T>> { static void Serialize(const std::vector<T>& value, std::vector<uint8_t>* out) { out->push_back(cbor::EncodeIndefiniteLengthArrayStart()); for (const T& element : value) SerializerTraits<T>::Serialize(element, out); out->push_back(cbor::EncodeStop()); } }; template <typename T> struct SerializerTraits<std::unique_ptr<T>> { static void Serialize(const std::unique_ptr<T>& value, std::vector<uint8_t>* out) { SerializerTraits<T>::Serialize(*value, out); } }; // ============================================================================= // FieldSerializerTraits - Encodes fields of protocol objects in CBOR // ============================================================================= // // The generated code (see TypeBuilder_cpp.template) invokes SerializeField, // which then instantiates the FieldSerializerTraits to emit the appropriate // existence checks / dereference for the field value. This avoids emitting // the field name if the value for an optional field isn't set. template <typename T> struct FieldSerializerTraits { static void Serialize(span<uint8_t> field_name, const T& field_value, std::vector<uint8_t>* out) { cbor::EncodeString8(field_name, out); SerializerTraits<T>::Serialize(field_value, out); } }; template <typename T> struct FieldSerializerTraits<detail::PtrMaybe<T>> { static void Serialize(span<uint8_t> field_name, const detail::PtrMaybe<T>& field_value, std::vector<uint8_t>* out) { if (!field_value.isJust()) return; cbor::EncodeString8(field_name, out); SerializerTraits<T>::Serialize(*field_value.fromJust(), out); } }; template <typename T> struct FieldSerializerTraits<detail::ValueMaybe<T>> { static void Serialize(span<uint8_t> field_name, const detail::ValueMaybe<T>& field_value, std::vector<uint8_t>* out) { if (!field_value.isJust()) return; cbor::EncodeString8(field_name, out); SerializerTraits<T>::Serialize(field_value.fromJust(), out); } }; template <typename T> void SerializeField(span<uint8_t> field_name, const T& field_value, std::vector<uint8_t>* out) { FieldSerializerTraits<T>::Serialize(field_name, field_value, out); } } // namespace v8_crdtp #endif // V8_CRDTP_SERIALIZER_TRAITS_H_