Flutter Engine
standard_codec.cc
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 // This file contains what would normally be standard_codec_serializer.cc,
6 // standard_message_codec.cc, and standard_method_codec.cc. They are grouped
7 // together to simplify use of the client wrapper, since the common case is
8 // that any client that needs one of these files needs all three.
9 
10 #include <cassert>
11 #include <cstring>
12 #include <iostream>
13 #include <map>
14 #include <string>
15 #include <vector>
16 
17 #include "byte_buffer_streams.h"
21 
22 namespace flutter {
23 
24 // ===== standard_codec_serializer.h =====
25 
26 namespace {
27 
28 // The order/values here must match the constants in message_codecs.dart.
29 enum class EncodedType {
30  kNull = 0,
31  kTrue,
32  kFalse,
33  kInt32,
34  kInt64,
35  kLargeInt, // No longer used. If encountered, treat as kString.
36  kFloat64,
37  kString,
38  kUInt8List,
39  kInt32List,
40  kInt64List,
41  kFloat64List,
42  kList,
43  kMap,
44  kFloat32List,
45 };
46 
47 // Returns the encoded type that should be written when serializing |value|.
48 EncodedType EncodedTypeForValue(const EncodableValue& value) {
49  switch (value.index()) {
50  case 0:
51  return EncodedType::kNull;
52  case 1:
53  return std::get<bool>(value) ? EncodedType::kTrue : EncodedType::kFalse;
54  case 2:
55  return EncodedType::kInt32;
56  case 3:
57  return EncodedType::kInt64;
58  case 4:
59  return EncodedType::kFloat64;
60  case 5:
61  return EncodedType::kString;
62  case 6:
63  return EncodedType::kUInt8List;
64  case 7:
65  return EncodedType::kInt32List;
66  case 8:
67  return EncodedType::kInt64List;
68  case 9:
69  return EncodedType::kFloat64List;
70  case 10:
71  return EncodedType::kList;
72  case 11:
73  return EncodedType::kMap;
74  case 13:
75  return EncodedType::kFloat32List;
76  }
77  assert(false);
78  return EncodedType::kNull;
79 }
80 
81 } // namespace
82 
84 
86 
88  static StandardCodecSerializer sInstance;
89  return sInstance;
90 };
91 
93  ByteStreamReader* stream) const {
94  uint8_t type = stream->ReadByte();
95  return ReadValueOfType(type, stream);
96 }
97 
99  ByteStreamWriter* stream) const {
100  stream->WriteByte(static_cast<uint8_t>(EncodedTypeForValue(value)));
101  // TODO: Consider replacing this this with a std::visitor.
102  switch (value.index()) {
103  case 0:
104  case 1:
105  // Null and bool are encoded directly in the type.
106  break;
107  case 2:
108  stream->WriteInt32(std::get<int32_t>(value));
109  break;
110  case 3:
111  stream->WriteInt64(std::get<int64_t>(value));
112  break;
113  case 4:
114  stream->WriteAlignment(8);
115  stream->WriteDouble(std::get<double>(value));
116  break;
117  case 5: {
118  const auto& string_value = std::get<std::string>(value);
119  size_t size = string_value.size();
120  WriteSize(size, stream);
121  if (size > 0) {
122  stream->WriteBytes(
123  reinterpret_cast<const uint8_t*>(string_value.data()), size);
124  }
125  break;
126  }
127  case 6:
128  WriteVector(std::get<std::vector<uint8_t>>(value), stream);
129  break;
130  case 7:
131  WriteVector(std::get<std::vector<int32_t>>(value), stream);
132  break;
133  case 8:
134  WriteVector(std::get<std::vector<int64_t>>(value), stream);
135  break;
136  case 9:
137  WriteVector(std::get<std::vector<double>>(value), stream);
138  break;
139  case 10: {
140  const auto& list = std::get<EncodableList>(value);
141  WriteSize(list.size(), stream);
142  for (const auto& item : list) {
143  WriteValue(item, stream);
144  }
145  break;
146  }
147  case 11: {
148  const auto& map = std::get<EncodableMap>(value);
149  WriteSize(map.size(), stream);
150  for (const auto& pair : map) {
151  WriteValue(pair.first, stream);
152  WriteValue(pair.second, stream);
153  }
154  break;
155  }
156  case 12:
157  std::cerr
158  << "Unhandled custom type in StandardCodecSerializer::WriteValue. "
159  << "Custom types require codec extensions." << std::endl;
160  break;
161  case 13: {
162  WriteVector(std::get<std::vector<float>>(value), stream);
163  break;
164  }
165  }
166 }
167 
169  uint8_t type,
170  ByteStreamReader* stream) const {
171  switch (static_cast<EncodedType>(type)) {
172  case EncodedType::kNull:
173  return EncodableValue();
174  case EncodedType::kTrue:
175  return EncodableValue(true);
176  case EncodedType::kFalse:
177  return EncodableValue(false);
178  case EncodedType::kInt32:
179  return EncodableValue(stream->ReadInt32());
180  case EncodedType::kInt64:
181  return EncodableValue(stream->ReadInt64());
182  case EncodedType::kFloat64:
183  stream->ReadAlignment(8);
184  return EncodableValue(stream->ReadDouble());
185  case EncodedType::kLargeInt:
186  case EncodedType::kString: {
187  size_t size = ReadSize(stream);
188  std::string string_value;
189  string_value.resize(size);
190  stream->ReadBytes(reinterpret_cast<uint8_t*>(&string_value[0]), size);
191  return EncodableValue(string_value);
192  }
193  case EncodedType::kUInt8List:
194  return ReadVector<uint8_t>(stream);
195  case EncodedType::kInt32List:
196  return ReadVector<int32_t>(stream);
197  case EncodedType::kInt64List:
198  return ReadVector<int64_t>(stream);
199  case EncodedType::kFloat64List:
200  return ReadVector<double>(stream);
201  case EncodedType::kList: {
202  size_t length = ReadSize(stream);
203  EncodableList list_value;
204  list_value.reserve(length);
205  for (size_t i = 0; i < length; ++i) {
206  list_value.push_back(ReadValue(stream));
207  }
208  return EncodableValue(list_value);
209  }
210  case EncodedType::kMap: {
211  size_t length = ReadSize(stream);
212  EncodableMap map_value;
213  for (size_t i = 0; i < length; ++i) {
214  EncodableValue key = ReadValue(stream);
215  EncodableValue value = ReadValue(stream);
216  map_value.emplace(std::move(key), std::move(value));
217  }
218  return EncodableValue(map_value);
219  }
220  case EncodedType::kFloat32List: {
221  return ReadVector<float>(stream);
222  }
223  }
224  std::cerr << "Unknown type in StandardCodecSerializer::ReadValueOfType: "
225  << static_cast<int>(type) << std::endl;
226  return EncodableValue();
227 }
228 
230  uint8_t byte = stream->ReadByte();
231  if (byte < 254) {
232  return byte;
233  } else if (byte == 254) {
234  uint16_t value;
235  stream->ReadBytes(reinterpret_cast<uint8_t*>(&value), 2);
236  return value;
237  } else {
238  uint32_t value;
239  stream->ReadBytes(reinterpret_cast<uint8_t*>(&value), 4);
240  return value;
241  }
242 }
243 
245  ByteStreamWriter* stream) const {
246  if (size < 254) {
247  stream->WriteByte(static_cast<uint8_t>(size));
248  } else if (size <= 0xffff) {
249  stream->WriteByte(254);
250  uint16_t value = static_cast<uint16_t>(size);
251  stream->WriteBytes(reinterpret_cast<uint8_t*>(&value), 2);
252  } else {
253  stream->WriteByte(255);
254  uint32_t value = static_cast<uint32_t>(size);
255  stream->WriteBytes(reinterpret_cast<uint8_t*>(&value), 4);
256  }
257 }
258 
259 template <typename T>
260 EncodableValue StandardCodecSerializer::ReadVector(
261  ByteStreamReader* stream) const {
262  size_t count = ReadSize(stream);
263  std::vector<T> vector;
264  vector.resize(count);
265  uint8_t type_size = static_cast<uint8_t>(sizeof(T));
266  if (type_size > 1) {
267  stream->ReadAlignment(type_size);
268  }
269  stream->ReadBytes(reinterpret_cast<uint8_t*>(vector.data()),
270  count * type_size);
271  return EncodableValue(vector);
272 }
273 
274 template <typename T>
275 void StandardCodecSerializer::WriteVector(const std::vector<T> vector,
276  ByteStreamWriter* stream) const {
277  size_t count = vector.size();
278  WriteSize(count, stream);
279  if (count == 0) {
280  return;
281  }
282  uint8_t type_size = static_cast<uint8_t>(sizeof(T));
283  if (type_size > 1) {
284  stream->WriteAlignment(type_size);
285  }
286  stream->WriteBytes(reinterpret_cast<const uint8_t*>(vector.data()),
287  count * type_size);
288 }
289 
290 // ===== standard_message_codec.h =====
291 
292 // static
294  const StandardCodecSerializer* serializer) {
295  if (!serializer) {
296  serializer = &StandardCodecSerializer::GetInstance();
297  }
298  static auto* sInstances = new std::map<const StandardCodecSerializer*,
299  std::unique_ptr<StandardMessageCodec>>;
300  auto it = sInstances->find(serializer);
301  if (it == sInstances->end()) {
302  // Uses new due to private constructor (to prevent API clients from
303  // accidentally passing temporary codec instances to channels).
304  auto emplace_result = sInstances->emplace(
305  serializer, std::unique_ptr<StandardMessageCodec>(
306  new StandardMessageCodec(serializer)));
307  it = emplace_result.first;
308  }
309  return *(it->second);
310 }
311 
313  const StandardCodecSerializer* serializer)
314  : serializer_(serializer) {}
315 
317 
318 std::unique_ptr<EncodableValue> StandardMessageCodec::DecodeMessageInternal(
319  const uint8_t* binary_message,
320  size_t message_size) const {
321  if (!binary_message) {
322  return std::make_unique<EncodableValue>();
323  }
324  ByteBufferStreamReader stream(binary_message, message_size);
325  return std::make_unique<EncodableValue>(serializer_->ReadValue(&stream));
326 }
327 
328 std::unique_ptr<std::vector<uint8_t>>
330  const EncodableValue& message) const {
331  auto encoded = std::make_unique<std::vector<uint8_t>>();
332  ByteBufferStreamWriter stream(encoded.get());
333  serializer_->WriteValue(message, &stream);
334  return encoded;
335 }
336 
337 // ===== standard_method_codec.h =====
338 
339 // static
341  const StandardCodecSerializer* serializer) {
342  if (!serializer) {
343  serializer = &StandardCodecSerializer::GetInstance();
344  }
345  static auto* sInstances = new std::map<const StandardCodecSerializer*,
346  std::unique_ptr<StandardMethodCodec>>;
347  auto it = sInstances->find(serializer);
348  if (it == sInstances->end()) {
349  // Uses new due to private constructor (to prevent API clients from
350  // accidentally passing temporary codec instances to channels).
351  auto emplace_result = sInstances->emplace(
352  serializer, std::unique_ptr<StandardMethodCodec>(
353  new StandardMethodCodec(serializer)));
354  it = emplace_result.first;
355  }
356  return *(it->second);
357 }
358 
360  const StandardCodecSerializer* serializer)
361  : serializer_(serializer) {}
362 
364 
365 std::unique_ptr<MethodCall<EncodableValue>>
367  size_t message_size) const {
368  ByteBufferStreamReader stream(message, message_size);
369  EncodableValue method_name_value = serializer_->ReadValue(&stream);
370  const auto* method_name = std::get_if<std::string>(&method_name_value);
371  if (!method_name) {
372  std::cerr << "Invalid method call; method name is not a string."
373  << std::endl;
374  return nullptr;
375  }
376  auto arguments =
377  std::make_unique<EncodableValue>(serializer_->ReadValue(&stream));
378  return std::make_unique<MethodCall<EncodableValue>>(*method_name,
379  std::move(arguments));
380 }
381 
382 std::unique_ptr<std::vector<uint8_t>>
385  auto encoded = std::make_unique<std::vector<uint8_t>>();
386  ByteBufferStreamWriter stream(encoded.get());
387  serializer_->WriteValue(EncodableValue(method_call.method_name()), &stream);
388  if (method_call.arguments()) {
389  serializer_->WriteValue(*method_call.arguments(), &stream);
390  } else {
391  serializer_->WriteValue(EncodableValue(), &stream);
392  }
393  return encoded;
394 }
395 
396 std::unique_ptr<std::vector<uint8_t>>
398  const EncodableValue* result) const {
399  auto encoded = std::make_unique<std::vector<uint8_t>>();
400  ByteBufferStreamWriter stream(encoded.get());
401  stream.WriteByte(0);
402  if (result) {
403  serializer_->WriteValue(*result, &stream);
404  } else {
405  serializer_->WriteValue(EncodableValue(), &stream);
406  }
407  return encoded;
408 }
409 
410 std::unique_ptr<std::vector<uint8_t>>
412  const std::string& error_code,
413  const std::string& error_message,
414  const EncodableValue* error_details) const {
415  auto encoded = std::make_unique<std::vector<uint8_t>>();
416  ByteBufferStreamWriter stream(encoded.get());
417  stream.WriteByte(1);
418  serializer_->WriteValue(EncodableValue(error_code), &stream);
419  if (error_message.empty()) {
420  serializer_->WriteValue(EncodableValue(), &stream);
421  } else {
422  serializer_->WriteValue(EncodableValue(error_message), &stream);
423  }
424  if (error_details) {
425  serializer_->WriteValue(*error_details, &stream);
426  } else {
427  serializer_->WriteValue(EncodableValue(), &stream);
428  }
429  return encoded;
430 }
431 
433  const uint8_t* response,
434  size_t response_size,
436  ByteBufferStreamReader stream(response, response_size);
437  uint8_t flag = stream.ReadByte();
438  switch (flag) {
439  case 0: {
440  EncodableValue value = serializer_->ReadValue(&stream);
441  if (value.IsNull()) {
442  result->Success();
443  } else {
444  result->Success(value);
445  }
446  return true;
447  }
448  case 1: {
449  EncodableValue code = serializer_->ReadValue(&stream);
450  EncodableValue message = serializer_->ReadValue(&stream);
451  EncodableValue details = serializer_->ReadValue(&stream);
452  const std::string& message_string =
453  message.IsNull() ? "" : std::get<std::string>(message);
454  if (details.IsNull()) {
455  result->Error(std::get<std::string>(code), message_string);
456  } else {
457  result->Error(std::get<std::string>(code), message_string, details);
458  }
459  return true;
460  }
461  default:
462  return false;
463  }
464 }
465 
466 } // namespace flutter
size_t ReadSize(ByteStreamReader *stream) const
virtual void WriteAlignment(uint8_t alignment)=0
KeyCallType type
G_BEGIN_DECLS FlMethodCall * method_call
virtual void WriteValue(const EncodableValue &value, ByteStreamWriter *stream) const
virtual void ReadAlignment(uint8_t alignment)=0
const T * arguments() const
Definition: method_call.h:34
virtual void ReadBytes(uint8_t *buffer, size_t length)=0
virtual void WriteByte(uint8_t byte)=0
std::unique_ptr< std::vector< uint8_t > > EncodeErrorEnvelopeInternal(const std::string &error_code, const std::string &error_message, const EncodableValue *error_details) const override
void Error(const std::string &error_code, const std::string &error_message, const T &error_details)
Definition: method_result.h:41
StandardMessageCodec(StandardMessageCodec const &)=delete
GAsyncResult * result
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
EncodableValue ReadValue(ByteStreamReader *stream) const
void WriteDouble(double value)
Definition: byte_streams.h:78
static const StandardCodecSerializer & GetInstance()
static const StandardMessageCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
void Success(const T &result)
Definition: method_result.h:29
uint8_t value
std::unique_ptr< EncodableValue > DecodeMessageInternal(const uint8_t *binary_message, const size_t message_size) const override
virtual void WriteBytes(const uint8_t *bytes, size_t length)=0
void WriteInt32(int32_t value)
Definition: byte_streams.h:68
FlutterSemanticsFlag flag
std::unique_ptr< std::vector< uint8_t > > EncodeMessageInternal(const EncodableValue &message) const override
virtual EncodableValue ReadValueOfType(uint8_t type, ByteStreamReader *stream) const
size_t length
std::vector< EncodableValue > EncodableList
bool DecodeAndProcessResponseEnvelopeInternal(const uint8_t *response, size_t response_size, MethodResult< EncodableValue > *result) const override
static const StandardMethodCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
std::unique_ptr< std::vector< uint8_t > > EncodeSuccessEnvelopeInternal(const EncodableValue *result) const override
void WriteInt64(int64_t value)
Definition: byte_streams.h:73
void WriteSize(size_t size, ByteStreamWriter *stream) const
StandardMethodCodec(StandardMethodCodec const &)=delete
std::map< EncodableValue, EncodableValue > EncodableMap
std::unique_ptr< MethodCall< EncodableValue > > DecodeMethodCallInternal(const uint8_t *message, size_t message_size) const override
const std::string & method_name() const
Definition: method_call.h:31
virtual uint8_t ReadByte()=0
std::unique_ptr< std::vector< uint8_t > > EncodeMethodCallInternal(const MethodCall< EncodableValue > &method_call) const override