| 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 // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
305 auto emplace_result = sInstances->emplace(
306 serializer, std::unique_ptr<StandardMessageCodec>(
307 new StandardMessageCodec(serializer)));
308 it = emplace_result.first;
309 }
310 return *(it->second);
311 }
312
313 StandardMessageCodec::StandardMessageCodec(
314 const StandardCodecSerializer* serializer)
315 : serializer_(serializer) {}
316
317 StandardMessageCodec::~StandardMessageCodec() = default;
318
319 std::unique_ptr<EncodableValue> StandardMessageCodec::DecodeMessageInternal(
320 const uint8_t* binary_message,
321 size_t message_size) const {
322 if (!binary_message) {
323 return std::make_unique<EncodableValue>();
324 }
325 ByteBufferStreamReader stream(binary_message, message_size);
326 return std::make_unique<EncodableValue>(serializer_->ReadValue(&stream));
327 }
328
329 std::unique_ptr<std::vector<uint8_t>>
330 StandardMessageCodec::EncodeMessageInternal(
331 const EncodableValue& message) const {
332 auto encoded = std::make_unique<std::vector<uint8_t>>();
333 ByteBufferStreamWriter stream(encoded.get());
334 serializer_->WriteValue(message, &stream);
335 return encoded;
336 }
337
338 // ===== standard_method_codec.h =====
339
340 // static
341 const StandardMethodCodec& StandardMethodCodec::GetInstance(
342 const StandardCodecSerializer* serializer) {
343 if (!serializer) {
344 serializer = &StandardCodecSerializer::GetInstance();
345 }
346 static auto* sInstances = new std::map<const StandardCodecSerializer*,
347 std::unique_ptr<StandardMethodCodec>>;
348 auto it = sInstances->find(serializer);
349 if (it == sInstances->end()) {
350 // Uses new due to private constructor (to prevent API clients from
351 // accidentally passing temporary codec instances to channels).
352 // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
353 auto emplace_result = sInstances->emplace(
354 serializer, std::unique_ptr<StandardMethodCodec>(
355 new StandardMethodCodec(serializer)));
356 it = emplace_result.first;
357 }
358 return *(it->second);
359 }
360
361 StandardMethodCodec::StandardMethodCodec(
362 const StandardCodecSerializer* serializer)
363 : serializer_(serializer) {}
364
365 StandardMethodCodec::~StandardMethodCodec() = default;
366
367 std::unique_ptr<MethodCall<EncodableValue>>
368 StandardMethodCodec::DecodeMethodCallInternal(const uint8_t* message,
369 size_t message_size) const {
370 ByteBufferStreamReader stream(message, message_size);
371 EncodableValue method_name_value = serializer_->ReadValue(&stream);
372 const auto* method_name = std::get_if<std::string>(&method_name_value);
373 if (!method_name) {
374 std::cerr << "Invalid method call; method name is not a string."
375 << std::endl;
376 return nullptr;
377 }
378 auto arguments =
379 std::make_unique<EncodableValue>(serializer_->ReadValue(&stream));
380 return std::make_unique<MethodCall<EncodableValue>>(*method_name,
381 std::move(arguments));
382 }
383
384 std::unique_ptr<std::vector<uint8_t>>
385 StandardMethodCodec::EncodeMethodCallInternal(
386 const MethodCall<EncodableValue>& method_call) const {
387 auto encoded = std::make_unique<std::vector<uint8_t>>();
388 ByteBufferStreamWriter stream(encoded.get());
389 serializer_->WriteValue(EncodableValue(method_call.method_name()), &stream);
390 if (method_call.arguments()) {
391 serializer_->WriteValue(*method_call.arguments(), &stream);
392 } else {
393 serializer_->WriteValue(EncodableValue(), &stream);
394 }
395 return encoded;
396 }
397
398 std::unique_ptr<std::vector<uint8_t>>
399 StandardMethodCodec::EncodeSuccessEnvelopeInternal(
400 const EncodableValue* result) const {
401 auto encoded = std::make_unique<std::vector<uint8_t>>();
402 ByteBufferStreamWriter stream(encoded.get());
403 stream.WriteByte(0);
404 if (result) {
405 serializer_->WriteValue(*result, &stream);
406 } else {
407 serializer_->WriteValue(EncodableValue(), &stream);
408 }
409 return encoded;
410 }
411
412 std::unique_ptr<std::vector<uint8_t>>
413 StandardMethodCodec::EncodeErrorEnvelopeInternal(
414 const std::string& error_code,
415 const std::string& error_message,
416 const EncodableValue* error_details) const {
417 auto encoded = std::make_unique<std::vector<uint8_t>>();
418 ByteBufferStreamWriter stream(encoded.get());
419 stream.WriteByte(1);
420 serializer_->WriteValue(EncodableValue(error_code), &stream);
421 if (error_message.empty()) {
422 serializer_->WriteValue(EncodableValue(), &stream);
423 } else {
424 serializer_->WriteValue(EncodableValue(error_message), &stream);
425 }
426 if (error_details) {
427 serializer_->WriteValue(*error_details, &stream);
428 } else {
429 serializer_->WriteValue(EncodableValue(), &stream);
430 }
431 return encoded;
432 }
433
434 bool StandardMethodCodec::DecodeAndProcessResponseEnvelopeInternal(
435 const uint8_t* response,
436 size_t response_size,
437 MethodResult<EncodableValue>* result) const {
438 ByteBufferStreamReader stream(response, response_size);
439 uint8_t flag = stream.ReadByte();
440 switch (flag) {
441 case 0: {
442 EncodableValue value = serializer_->ReadValue(&stream);
443 if (value.IsNull()) {
444 result->Success();
445 } else {
446 result->Success(value);
447 }
448 return true;
449 }
450 case 1: {
451 EncodableValue code = serializer_->ReadValue(&stream);
452 EncodableValue message = serializer_->ReadValue(&stream);
453 EncodableValue details = serializer_->ReadValue(&stream);
454 const std::string& message_string =
455 message.IsNull() ? "" : std::get<std::string>(message);
456 if (details.IsNull()) {
457 result->Error(std::get<std::string>(code), message_string);
458 } else {
459 result->Error(std::get<std::string>(code), message_string, details);
460 }
461 return true;
462 }
463 default:
464 return false;
465 }
466 }
467
468 } // namespace flutter
byte_buffer_streams.h
flutter::ByteBufferStreamReader
Definition: byte_buffer_streams.h:19
flutter::ByteBufferStreamReader::ReadByte
uint8_t ReadByte() override
Definition: byte_buffer_streams.h:29
flutter::ByteBufferStreamWriter
Definition: byte_buffer_streams.h:65
flutter::ByteStreamReader
Definition: byte_streams.h:13
flutter::ByteStreamReader::ReadInt32
int32_t ReadInt32()
Definition: byte_streams.h:30
flutter::ByteStreamReader::ReadByte
virtual uint8_t ReadByte()=0
flutter::ByteStreamReader::ReadInt64
int64_t ReadInt64()
Definition: byte_streams.h:37
flutter::ByteStreamReader::ReadBytes
virtual void ReadBytes(uint8_t *buffer, size_t length)=0
flutter::ByteStreamReader::ReadDouble
double ReadDouble()
Definition: byte_streams.h:44
flutter::ByteStreamReader::ReadAlignment
virtual void ReadAlignment(uint8_t alignment)=0
flutter::ByteStreamWriter
Definition: byte_streams.h:52
flutter::ByteStreamWriter::WriteByte
virtual void WriteByte(uint8_t byte)=0
flutter::ByteStreamWriter::WriteInt64
void WriteInt64(int64_t value)
Definition: byte_streams.h:73
flutter::ByteStreamWriter::WriteBytes
virtual void WriteBytes(const uint8_t *bytes, size_t length)=0
flutter::ByteStreamWriter::WriteAlignment
virtual void WriteAlignment(uint8_t alignment)=0
flutter::ByteStreamWriter::WriteDouble
void WriteDouble(double value)
Definition: byte_streams.h:78
flutter::ByteStreamWriter::WriteInt32
void WriteInt32(int32_t value)
Definition: byte_streams.h:68
flutter::EncodableValue
Definition: encodable_value.h:166
flutter::EncodableValue::IsNull
bool IsNull() const
Definition: encodable_value.h:204
flutter::MethodCall
Definition: method_call.h:18
flutter::MethodCall::method_name
const std::string & method_name() const
Definition: method_call.h:31
flutter::MethodCall::arguments
const T * arguments() const
Definition: method_call.h:34
flutter::MethodResult< EncodableValue >
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::MethodResult::Success
void Success(const T &result)
Definition: method_result.h:29
flutter::StandardCodecSerializer
Definition: standard_codec_serializer.h:18
flutter::StandardCodecSerializer::WriteValue
virtual void WriteValue(const EncodableValue &value, ByteStreamWriter *stream) const
Definition: standard_codec.cc:98
flutter::StandardCodecSerializer::~StandardCodecSerializer
virtual ~StandardCodecSerializer()
flutter::StandardCodecSerializer::WriteSize
void WriteSize(size_t size, ByteStreamWriter *stream) const
Definition: standard_codec.cc:244
flutter::StandardCodecSerializer::StandardCodecSerializer
StandardCodecSerializer()
flutter::StandardCodecSerializer::GetInstance
static const StandardCodecSerializer & GetInstance()
Definition: standard_codec.cc:87
flutter::StandardCodecSerializer::ReadValue
EncodableValue ReadValue(ByteStreamReader *stream) const
Definition: standard_codec.cc:92
flutter::StandardCodecSerializer::ReadValueOfType
virtual EncodableValue ReadValueOfType(uint8_t type, ByteStreamReader *stream) const
Definition: standard_codec.cc:168
flutter::StandardCodecSerializer::ReadSize
size_t ReadSize(ByteStreamReader *stream) const
Definition: standard_codec.cc:229
flutter::StandardMessageCodec
Definition: standard_message_codec.h:18
flutter::StandardMessageCodec::~StandardMessageCodec
~StandardMessageCodec()
flutter::StandardMessageCodec::GetInstance
static const StandardMessageCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
Definition: standard_codec.cc:293
flutter::StandardMessageCodec::DecodeMessageInternal
std::unique_ptr< EncodableValue > DecodeMessageInternal(const uint8_t *binary_message, const size_t message_size) const override
Definition: standard_codec.cc:319
flutter::StandardMessageCodec::StandardMessageCodec
StandardMessageCodec(StandardMessageCodec const &)=delete
flutter::StandardMessageCodec::EncodeMessageInternal
std::unique_ptr< std::vector< uint8_t > > EncodeMessageInternal(const EncodableValue &message) const override
Definition: standard_codec.cc:330
flutter::StandardMethodCodec
Definition: standard_method_codec.h:18
flutter::StandardMethodCodec::~StandardMethodCodec
~StandardMethodCodec()
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:413
flutter::StandardMethodCodec::EncodeMethodCallInternal
std::unique_ptr< std::vector< uint8_t > > EncodeMethodCallInternal(const MethodCall< EncodableValue > &method_call) const override
Definition: standard_codec.cc:385
flutter::StandardMethodCodec::StandardMethodCodec
StandardMethodCodec(StandardMethodCodec const &)=delete
flutter::StandardMethodCodec::EncodeSuccessEnvelopeInternal
std::unique_ptr< std::vector< uint8_t > > EncodeSuccessEnvelopeInternal(const EncodableValue *result) const override
Definition: standard_codec.cc:399
flutter::StandardMethodCodec::DecodeMethodCallInternal
std::unique_ptr< MethodCall< EncodableValue > > DecodeMethodCallInternal(const uint8_t *message, size_t message_size) const override
Definition: standard_codec.cc:368
flutter::StandardMethodCodec::GetInstance
static const StandardMethodCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
Definition: standard_codec.cc:341
flutter::StandardMethodCodec::DecodeAndProcessResponseEnvelopeInternal
bool DecodeAndProcessResponseEnvelopeInternal(const uint8_t *response, size_t response_size, MethodResult< EncodableValue > *result) const override
Definition: standard_codec.cc:434
flutter
Definition: accessibility_bridge.h:26
flutter::EncodableList
std::vector< EncodableValue > EncodableList
Definition: encodable_value.h:95
flutter::EncodableMap
std::map< EncodableValue, EncodableValue > EncodableMap
Definition: encodable_value.h:96
standard_codec_serializer.h
standard_message_codec.h
standard_method_codec.h