| Flutter iOS Embedder |

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"
18 #include "include/flutter/standard_codec_serializer.h"
19 #include "include/flutter/standard_message_codec.h"
20 #include "include/flutter/standard_method_codec.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
83 StandardCodecSerializer::StandardCodecSerializer() = default;
84
85 StandardCodecSerializer::~StandardCodecSerializer() = default;
86
87 const StandardCodecSerializer& StandardCodecSerializer::GetInstance() {
88 static StandardCodecSerializer sInstance;
89 return sInstance;
90 };
91
92 EncodableValue StandardCodecSerializer::ReadValue(
93 ByteStreamReader* stream) const {
94 uint8_t type = stream->ReadByte();
95 return ReadValueOfType(type, stream);
96 }
97
98 void StandardCodecSerializer::WriteValue(const EncodableValue& value,
99 ByteStreamWriter* stream) const {
100 stream->WriteByte(static_cast<uint8_t>(EncodedTypeForValue(value)));
101 // TODO(cbracken): Consider replacing this with std::visit.
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
168 EncodableValue StandardCodecSerializer::ReadValueOfType(
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
229 size_t StandardCodecSerializer::ReadSize(ByteStreamReader* stream) const {
230 uint8_t byte = stream->ReadByte();
231 if (byte < 254) {
232 return byte;
233 } else if (byte == 254) {
234 uint16_t value = 0;
235 stream->ReadBytes(reinterpret_cast<uint8_t*>(&value), 2);
236 return value;
237 } else {
238 uint32_t value = 0;
239 stream->ReadBytes(reinterpret_cast<uint8_t*>(&value), 4);
240 return value;
241 }
242 }
243
244 void StandardCodecSerializer::WriteSize(size_t size,
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
293 const StandardMessageCodec& StandardMessageCodec::GetInstance(
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
312 StandardMessageCodec::StandardMessageCodec(
313 const StandardCodecSerializer* serializer)
314 : serializer_(serializer) {}
315
316 StandardMessageCodec::~StandardMessageCodec() = default;
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>>
329 StandardMessageCodec::EncodeMessageInternal(
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
340 const StandardMethodCodec& StandardMethodCodec::GetInstance(
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
359 StandardMethodCodec::StandardMethodCodec(
360 const StandardCodecSerializer* serializer)
361 : serializer_(serializer) {}
362
363 StandardMethodCodec::~StandardMethodCodec() = default;
364
365 std::unique_ptr<MethodCall<EncodableValue>>
366 StandardMethodCodec::DecodeMethodCallInternal(const uint8_t* message,
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>>
383 StandardMethodCodec::EncodeMethodCallInternal(
384 const MethodCall<EncodableValue>& method_call) const {
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>>
397 StandardMethodCodec::EncodeSuccessEnvelopeInternal(
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>>
411 StandardMethodCodec::EncodeErrorEnvelopeInternal(
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
432 bool StandardMethodCodec::DecodeAndProcessResponseEnvelopeInternal(
433 const uint8_t* response,
434 size_t response_size,
435 MethodResult<EncodableValue>* result) const {
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
flutter::StandardMessageCodec::EncodeMessageInternal
std::unique_ptr< std::vector< uint8_t > > EncodeMessageInternal(const EncodableValue &message) const override
Definition: standard_codec.cc:329
flutter::StandardCodecSerializer::ReadValue
EncodableValue ReadValue(ByteStreamReader *stream) const
Definition: standard_codec.cc:92
flutter::ByteStreamReader::ReadByte
virtual uint8_t ReadByte()=0
flutter::ByteStreamReader::ReadDouble
double ReadDouble()
Definition: byte_streams.h:44
flutter::EncodableValue::IsNull
bool IsNull() const
Definition: encodable_value.h:203
flutter::ByteBufferStreamReader::ReadByte
uint8_t ReadByte() override
Definition: byte_buffer_streams.h:29
flutter::StandardCodecSerializer::ReadValueOfType
virtual EncodableValue ReadValueOfType(uint8_t type, ByteStreamReader *stream) const
Definition: standard_codec.cc:168
flutter::StandardCodecSerializer::WriteValue
virtual void WriteValue(const EncodableValue &value, ByteStreamWriter *stream) const
Definition: standard_codec.cc:98
flutter::StandardMethodCodec
Definition: standard_method_codec.h:18
standard_method_codec.h
standard_codec_serializer.h
flutter::ByteStreamReader::ReadBytes
virtual void ReadBytes(uint8_t *buffer, size_t length)=0
flutter::ByteStreamWriter::WriteInt32
void WriteInt32(int32_t value)
Definition: byte_streams.h:68
flutter::ByteStreamReader::ReadInt64
int64_t ReadInt64()
Definition: byte_streams.h:37
flutter::StandardCodecSerializer::ReadSize
size_t ReadSize(ByteStreamReader *stream) const
Definition: standard_codec.cc:229
flutter::ByteStreamReader
Definition: byte_streams.h:13
flutter::StandardMethodCodec::StandardMethodCodec
StandardMethodCodec(StandardMethodCodec const &)=delete
standard_message_codec.h
flutter::StandardCodecSerializer::GetInstance
static const StandardCodecSerializer & GetInstance()
Definition: standard_codec.cc:87
flutter::MethodCall
Definition: method_call.h:18
flutter::ByteBufferStreamReader
Definition: byte_buffer_streams.h:19
flutter::MethodResult::Error
void Error(const std::string &error_code, const std::string &error_message, const T &error_details)
Definition: method_result.h:41
flutter::StandardMethodCodec::~StandardMethodCodec
~StandardMethodCodec()
flutter::StandardMethodCodec::EncodeMethodCallInternal
std::unique_ptr< std::vector< uint8_t > > EncodeMethodCallInternal(const MethodCall< EncodableValue > &method_call) const override
Definition: standard_codec.cc:383
flutter::StandardMethodCodec::DecodeMethodCallInternal
std::unique_ptr< MethodCall< EncodableValue > > DecodeMethodCallInternal(const uint8_t *message, size_t message_size) const override
Definition: standard_codec.cc:366
flutter
Definition: accessibility_bridge.h:28
flutter::ByteStreamWriter::WriteDouble
void WriteDouble(double value)
Definition: byte_streams.h:78
flutter::StandardMessageCodec
Definition: standard_message_codec.h:18
flutter::StandardCodecSerializer::StandardCodecSerializer
StandardCodecSerializer()
flutter::StandardCodecSerializer
Definition: standard_codec_serializer.h:18
byte_buffer_streams.h
flutter::EncodableValue
Definition: encodable_value.h:165
flutter::MethodCall::method_name
const std::string & method_name() const
Definition: method_call.h:31
flutter::StandardMethodCodec::DecodeAndProcessResponseEnvelopeInternal
bool DecodeAndProcessResponseEnvelopeInternal(const uint8_t *response, size_t response_size, MethodResult< EncodableValue > *result) const override
Definition: standard_codec.cc:432
flutter::StandardMessageCodec::GetInstance
static const StandardMessageCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
Definition: standard_codec.cc:293
flutter::MethodResult::Success
void Success(const T &result)
Definition: method_result.h:29
flutter::ByteStreamWriter::WriteBytes
virtual void WriteBytes(const uint8_t *bytes, size_t length)=0
flutter::EncodableList
std::vector< EncodableValue > EncodableList
Definition: encodable_value.h:94
flutter::MethodResult< EncodableValue >
flutter::StandardMethodCodec::EncodeErrorEnvelopeInternal
std::unique_ptr< std::vector< uint8_t > > EncodeErrorEnvelopeInternal(const std::string &error_code, const std::string &error_message, const EncodableValue *error_details) const override
Definition: standard_codec.cc:411
flutter::StandardCodecSerializer::~StandardCodecSerializer
virtual ~StandardCodecSerializer()
flutter::StandardMessageCodec::StandardMessageCodec
StandardMessageCodec(StandardMessageCodec const &)=delete
flutter::ByteStreamWriter::WriteAlignment
virtual void WriteAlignment(uint8_t alignment)=0
flutter::StandardMessageCodec::DecodeMessageInternal
std::unique_ptr< EncodableValue > DecodeMessageInternal(const uint8_t *binary_message, const size_t message_size) const override
Definition: standard_codec.cc:318
flutter::StandardCodecSerializer::WriteSize
void WriteSize(size_t size, ByteStreamWriter *stream) const
Definition: standard_codec.cc:244
flutter::EncodableMap
std::map< EncodableValue, EncodableValue > EncodableMap
Definition: encodable_value.h:95
flutter::ByteStreamReader::ReadInt32
int32_t ReadInt32()
Definition: byte_streams.h:30
flutter::StandardMethodCodec::EncodeSuccessEnvelopeInternal
std::unique_ptr< std::vector< uint8_t > > EncodeSuccessEnvelopeInternal(const EncodableValue *result) const override
Definition: standard_codec.cc:397
flutter::ByteStreamWriter::WriteByte
virtual void WriteByte(uint8_t byte)=0
flutter::StandardMethodCodec::GetInstance
static const StandardMethodCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
Definition: standard_codec.cc:340
flutter::MethodCall::arguments
const T * arguments() const
Definition: method_call.h:34
flutter::ByteStreamWriter
Definition: byte_streams.h:52
flutter::ByteStreamReader::ReadAlignment
virtual void ReadAlignment(uint8_t alignment)=0
flutter::ByteBufferStreamWriter
Definition: byte_buffer_streams.h:65
flutter::ByteStreamWriter::WriteInt64
void WriteInt64(int64_t value)
Definition: byte_streams.h:73
flutter::StandardMessageCodec::~StandardMessageCodec
~StandardMessageCodec()