Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
22namespace flutter {
23
24// ===== standard_codec_serializer.h =====
25
26namespace {
27
28// The order/values here must match the constants in message_codecs.dart.
29enum 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|.
48EncodedType 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(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
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);
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 = 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
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
259template <typename T>
260EncodableValue 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
274template <typename T>
275void 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) {
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
318std::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
328std::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) {
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
365std::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
382std::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
396std::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
410std::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
int count
virtual void WriteValue(const EncodableValue &value, ByteStreamWriter *stream) const
void WriteSize(size_t size, ByteStreamWriter *stream) const
static const StandardCodecSerializer & GetInstance()
EncodableValue ReadValue(ByteStreamReader *stream) const
virtual EncodableValue ReadValueOfType(uint8_t type, ByteStreamReader *stream) const
size_t ReadSize(ByteStreamReader *stream) const
static const StandardMessageCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
std::unique_ptr< EncodableValue > DecodeMessageInternal(const uint8_t *binary_message, const size_t message_size) const override
StandardMessageCodec(StandardMessageCodec const &)=delete
std::unique_ptr< std::vector< uint8_t > > EncodeMessageInternal(const EncodableValue &message) const override
std::unique_ptr< std::vector< uint8_t > > EncodeErrorEnvelopeInternal(const std::string &error_code, const std::string &error_message, const EncodableValue *error_details) const override
std::unique_ptr< std::vector< uint8_t > > EncodeMethodCallInternal(const MethodCall< EncodableValue > &method_call) const override
StandardMethodCodec(StandardMethodCodec const &)=delete
std::unique_ptr< std::vector< uint8_t > > EncodeSuccessEnvelopeInternal(const EncodableValue *result) const override
std::unique_ptr< MethodCall< EncodableValue > > DecodeMethodCallInternal(const uint8_t *message, size_t message_size) const override
static const StandardMethodCodec & GetInstance(const StandardCodecSerializer *serializer=nullptr)
bool DecodeAndProcessResponseEnvelopeInternal(const uint8_t *response, size_t response_size, MethodResult< EncodableValue > *result) const override
FlutterSemanticsFlag flag
G_BEGIN_DECLS G_MODULE_EXPORT FlMethodCall * method_call
uint8_t value
GAsyncResult * result
size_t length
Win32Message message
std::vector< EncodableValue > EncodableList
std::map< EncodableValue, EncodableValue > EncodableMap
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition switches.h:259
@ kNull
Definition paint.cc:59
#define T