Flutter Engine
message.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_FML_MESSAGE_H_
6 #define FLUTTER_FML_MESSAGE_H_
7 
8 #include <algorithm>
9 #include <cstdint>
10 #include <cstring>
11 #include <memory>
12 #include <type_traits>
13 #include <utility>
14 
15 #include "flutter/fml/compiler_specific.h"
16 #include "flutter/fml/macros.h"
17 
18 namespace fml {
19 
20 #define FML_SERIALIZE(message, value) \
21  if (!message.Encode(value)) { \
22  return false; \
23  }
24 
25 #define FML_SERIALIZE_TRAITS(message, value, traits) \
26  if (!message.Encode<traits>(value)) { \
27  return false; \
28  }
29 
30 #define FML_DESERIALIZE(message, value) \
31  if (!message.Decode(value)) { \
32  return false; \
33  }
34 
35 #define FML_DESERIALIZE_TRAITS(message, value, traits) \
36  if (!message.Decode<traits>(value)) { \
37  return false; \
38  }
39 
40 class Message;
41 
43  public:
44  virtual ~MessageSerializable() = default;
45 
46  virtual bool Serialize(Message& message) const = 0;
47 
48  virtual bool Deserialize(Message& message) = 0;
49 
50  virtual size_t GetSerializableTag() const;
51 };
52 
53 // The traits passed to the encode/decode calls that accept traits should be
54 // something like the following.
55 //
56 // class MessageSerializableTraits {
57 // static size_t GetSerializableTag(const T&);
58 // static std::unique_ptr<T> CreateForSerializableTag(size_t tag);
59 // };
60 
61 template <class T>
62 struct Serializable : public std::integral_constant<
63  bool,
64  std::is_trivially_copyable<T>::value ||
65  std::is_base_of<MessageSerializable, T>::value> {
66 };
67 
68 // Utility class to encode and decode |Serializable| types to and from a buffer.
69 // Elements have to be read back into the same order they were written.
70 class Message {
71  public:
72  Message();
73 
74  ~Message();
75 
76  const uint8_t* GetBuffer() const;
77 
78  size_t GetBufferSize() const;
79 
80  size_t GetDataLength() const;
81 
82  size_t GetSizeRead() const;
83 
84  void ResetRead();
85 
86  // Encoders.
87 
88  template <typename T,
90  [[nodiscard]] bool Encode(const T& value) {
91  if (auto* buffer = PrepareEncode(sizeof(T))) {
92  ::memcpy(buffer, &value, sizeof(T));
93  return true;
94  }
95  return false;
96  }
97 
98  [[nodiscard]] bool Encode(const MessageSerializable& value) {
99  return value.Serialize(*this);
100  }
101 
102  template <typename Traits,
103  typename T,
104  typename = std::enable_if_t<
106  [[nodiscard]] bool Encode(const std::unique_ptr<T>& value) {
107  // Encode if null.
108  if (!Encode(static_cast<bool>(value))) {
109  return false;
110  }
111 
112  if (!value) {
113  return true;
114  }
115 
116  // Encode the type.
117  if (!Encode(Traits::GetSerializableTag(*value.get()))) {
118  return false;
119  }
120 
121  // Encode the value.
122  if (!Encode(*value.get())) {
123  return false;
124  }
125 
126  return true;
127  }
128 
129  // Decoders.
130 
131  template <typename T,
133  [[nodiscard]] bool Decode(T& value) {
134  if (auto* buffer = PrepareDecode(sizeof(T))) {
135  ::memcpy(&value, buffer, sizeof(T));
136  return true;
137  }
138  return false;
139  }
140 
141  [[nodiscard]] bool Decode(MessageSerializable& value) {
142  return value.Deserialize(*this);
143  }
144 
145  template <typename Traits,
146  typename T,
147  typename = std::enable_if_t<
149  [[nodiscard]] bool Decode(std::unique_ptr<T>& value) {
150  // Decode if null.
151  bool is_null = false;
152  if (!Decode(is_null)) {
153  return false;
154  }
155 
156  if (is_null) {
157  return true;
158  }
159 
160  // Decode type.
161  size_t tag = 0;
162  if (!Decode(tag)) {
163  return false;
164  }
165 
166  std::unique_ptr<T> new_value = Traits::CreateForSerializableTag(tag);
167  if (!new_value) {
168  return false;
169  }
170 
171  // Decode value.
172  if (!Decode(*new_value.get())) {
173  return false;
174  }
175 
176  std::swap(value, new_value);
177 
178  return true;
179  }
180 
181  private:
182  uint8_t* buffer_ = nullptr;
183  size_t buffer_length_ = 0;
184  size_t data_length_ = 0;
185  size_t size_read_ = 0;
186 
187  [[nodiscard]] bool Reserve(size_t size);
188 
189  [[nodiscard]] bool Resize(size_t size);
190 
191  [[nodiscard]] uint8_t* PrepareEncode(size_t size);
192 
193  [[nodiscard]] uint8_t* PrepareDecode(size_t size);
194 
196 };
197 
198 } // namespace fml
199 
200 #endif // FLUTTER_FML_MESSAGE_H_
bool Decode(T &value)
Definition: message.h:133
bool Encode(const std::unique_ptr< T > &value)
Definition: message.h:106
bool Encode(const MessageSerializable &value)
Definition: message.h:98
virtual bool Deserialize(Message &message)=0
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
void swap(scoped_nsprotocol< C > &p1, scoped_nsprotocol< C > &p2)
Definition: ascii_trie.cc:9
bool Decode(std::unique_ptr< T > &value)
Definition: message.h:149
uint8_t value
virtual bool Serialize(Message &message) const =0
virtual ~MessageSerializable()=default
bool Encode(const T &value)
Definition: message.h:90
bool Decode(MessageSerializable &value)
Definition: message.h:141
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:27
virtual size_t GetSerializableTag() const
Definition: message.cc:11