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