Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -835,12 +835,13 @@ FILE: ../../../flutter/shell/platform/android/surface/android_surface_mock.h
FILE: ../../../flutter/shell/platform/android/vsync_waiter_android.cc
FILE: ../../../flutter/shell/platform/android/vsync_waiter_android.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/basic_message_channel_unittests.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/byte_stream_wrappers.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/byte_buffer_streams.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/encodable_value_unittests.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/engine_method_result.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/event_channel_unittests.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/basic_message_channel.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/binary_messenger.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/byte_streams.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/encodable_value.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/engine_method_result.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/event_channel.h
Expand All @@ -855,6 +856,7 @@ FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/method_result_functions.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registry.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/standard_codec_serializer.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/standard_message_codec.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/include/flutter/standard_method_codec.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/method_call_unittests.cc
Expand All @@ -863,7 +865,6 @@ FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/method_result_fu
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/plugin_registrar.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/plugin_registrar_unittests.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/standard_codec.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/standard_codec_serializer.h
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/standard_message_codec_unittests.cc
FILE: ../../../flutter/shell/platform/common/cpp/client_wrapper/standard_method_codec_unittests.cc
FILE: ../../../flutter/shell/platform/common/cpp/incoming_message_dispatcher.cc
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/common/cpp/client_wrapper/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ executable("client_wrapper_unittests") {
"plugin_registrar_unittests.cc",
"standard_message_codec_unittests.cc",
"standard_method_codec_unittests.cc",
"testing/test_codec_extensions.cc",
"testing/test_codec_extensions.h",
]

deps = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,38 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_
#define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_

// Utility classes for interacting with a buffer of bytes as a stream, for use
// in message channel codecs.
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_BUFFER_STREAMS_H_
#define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_BUFFER_STREAMS_H_

#include <cassert>
#include <cstdint>
#include <cstring>
#include <iostream>
#include <vector>

#include "include/flutter/byte_streams.h"

namespace flutter {

// Wraps an array of bytes with utility methods for treating it as a readable
// stream.
class ByteBufferStreamReader {
// Implementation of ByteStreamReader base on a byte array.
class ByteBufferStreamReader : public ByteStreamReader {
public:
// Createa a reader reading from |bytes|, which must have a length of |size|.
// |bytes| must remain valid for the lifetime of this object.
explicit ByteBufferStreamReader(const uint8_t* bytes, size_t size)
: bytes_(bytes), size_(size) {}

// Reads and returns the next byte from the stream.
uint8_t ReadByte() {
// |ByteStreamReader|
uint8_t ReadByte() override {
if (location_ >= size_) {
std::cerr << "Invalid read in StandardCodecByteStreamReader" << std::endl;
return 0;
}
return bytes_[location_++];
}

// Reads the next |length| bytes from the stream into |buffer|. The caller
// is responsible for ensuring that |buffer| is large enough.
void ReadBytes(uint8_t* buffer, size_t length) {
// |ByteStreamReader|
void ReadBytes(uint8_t* buffer, size_t length) override {
if (location_ + length > size_) {
std::cerr << "Invalid read in StandardCodecByteStreamReader" << std::endl;
return;
Expand All @@ -44,9 +42,8 @@ class ByteBufferStreamReader {
location_ += length;
}

// Advances the read cursor to the next multiple of |alignment| relative to
// the start of the wrapped byte buffer, unless it is already aligned.
void ReadAlignment(uint8_t alignment) {
// |ByteStreamReader|
void ReadAlignment(uint8_t alignment) override {
uint8_t mod = location_ % alignment;
if (mod) {
location_ += alignment - mod;
Expand All @@ -62,30 +59,26 @@ class ByteBufferStreamReader {
size_t location_ = 0;
};

// Wraps an array of bytes with utility methods for treating it as a writable
// stream.
class ByteBufferStreamWriter {
// Implementation of ByteStreamWriter based on a byte array.
class ByteBufferStreamWriter : public ByteStreamWriter {
public:
// Createa a writter that writes into |buffer|.
// Creates a writer that writes into |buffer|.
// |buffer| must remain valid for the lifetime of this object.
explicit ByteBufferStreamWriter(std::vector<uint8_t>* buffer)
: bytes_(buffer) {
assert(buffer);
}

// Writes |byte| to the wrapped buffer.
// |ByteStreamWriter|
void WriteByte(uint8_t byte) { bytes_->push_back(byte); }

// Writes the next |length| bytes from |bytes| into the wrapped buffer.
// The caller is responsible for ensuring that |buffer| is large enough.
// |ByteStreamWriter|
void WriteBytes(const uint8_t* bytes, size_t length) {
assert(length > 0);
bytes_->insert(bytes_->end(), bytes, bytes + length);
}

// Writes 0s until the next multiple of |alignment| relative to
// the start of the wrapped byte buffer, unless the write positition is
// already aligned.
// |ByteStreamWriter|
void WriteAlignment(uint8_t alignment) {
uint8_t mod = bytes_->size() % alignment;
if (mod) {
Expand All @@ -102,4 +95,4 @@ class ByteBufferStreamWriter {

} // namespace flutter

#endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_STREAM_WRAPPERS_H_
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_BYTE_BUFFER_STREAMS_H_
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ core_cpp_client_wrapper_includes =
get_path_info([
"include/flutter/basic_message_channel.h",
"include/flutter/binary_messenger.h",
"include/flutter/byte_streams.h",
"include/flutter/encodable_value.h",
"include/flutter/engine_method_result.h",
"include/flutter/event_channel.h",
Expand All @@ -20,6 +21,7 @@ core_cpp_client_wrapper_includes =
"include/flutter/method_result.h",
"include/flutter/plugin_registrar.h",
"include/flutter/plugin_registry.h",
"include/flutter/standard_codec_serializer.h",
"include/flutter/standard_message_codec.h",
"include/flutter/standard_method_codec.h",
],
Expand All @@ -29,10 +31,9 @@ core_cpp_client_wrapper_includes =
# reasonable (without forcing different kinds of clients to take unnecessary
# code) to simplify use.
core_cpp_client_wrapper_sources = get_path_info([
"byte_stream_wrappers.h",
"byte_buffer_streams.h",
"engine_method_result.cc",
"plugin_registrar.cc",
"standard_codec_serializer.h",
"standard_codec.cc",
],
"abspath")
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_BYTE_STREAMS_H_
#define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_BYTE_STREAMS_H_

// Interfaces for interacting with a stream of bytes, for use in codecs.

namespace flutter {

// An interface for a class that reads from a byte stream.
class ByteStreamReader {
public:
// Reads and returns the next byte from the stream.
virtual uint8_t ReadByte() = 0;

// Reads the next |length| bytes from the stream into |buffer|. The caller
// is responsible for ensuring that |buffer| is large enough.
virtual void ReadBytes(uint8_t* buffer, size_t length) = 0;

// Advances the read cursor to the next multiple of |alignment| relative to
// the start of the stream, unless it is already aligned.
virtual void ReadAlignment(uint8_t alignment) = 0;

// Reads and returns the next 32-bit integer from the stream.
int32_t ReadInt32() {
int32_t value = 0;
ReadBytes(reinterpret_cast<uint8_t*>(&value), 4);
return value;
}

// Reads and returns the next 64-bit integer from the stream.
int64_t ReadInt64() {
int64_t value = 0;
ReadBytes(reinterpret_cast<uint8_t*>(&value), 8);
return value;
}

// Reads and returns the next 64-bit floating point number from the stream.
double ReadDouble() {
double value = 0;
ReadBytes(reinterpret_cast<uint8_t*>(&value), 8);
return value;
}
};

// An interface for a class that writes to a byte stream.
class ByteStreamWriter {
public:
// Writes |byte| to the stream.
virtual void WriteByte(uint8_t byte) = 0;

// Writes the next |length| bytes from |bytes| to the stream
virtual void WriteBytes(const uint8_t* bytes, size_t length) = 0;

// Writes 0s until the next multiple of |alignment| relative to the start
// of the stream, unless the write positition is already aligned.
virtual void WriteAlignment(uint8_t alignment) = 0;

// Writes the given 32-bit int to the stream.
void WriteInt32(int32_t value) {
WriteBytes(reinterpret_cast<const uint8_t*>(&value), 4);
}

// Writes the given 64-bit int to the stream.
void WriteInt64(int64_t value) {
WriteBytes(reinterpret_cast<const uint8_t*>(&value), 8);
}

// Writes the given 36-bit double to the stream.
void WriteDouble(double value) {
WriteBytes(reinterpret_cast<const uint8_t*>(&value), 8);
}
};

} // namespace flutter

#endif // FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_BYTE_STREAMS_H_
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_ENCODABLE_VALUE_H_
#define FLUTTER_SHELL_PLATFORM_COMMON_CPP_CLIENT_WRAPPER_INCLUDE_FLUTTER_ENCODABLE_VALUE_H_

#include <assert.h>

#include <any>
#include <cassert>
#include <cstdint>
#include <map>
#include <string>
Expand All @@ -25,6 +25,57 @@ static_assert(sizeof(double) == 8, "EncodableValue requires a 64-bit double");
// version, or it will break when the legacy version is removed.
#ifndef USE_LEGACY_ENCODABLE_VALUE

// A container for arbitrary types in EncodableValue.
//
// This is used in conjunction with StandardCodecExtension to allow using other
// types with a StandardMethodCodec/StandardMessageCodec. It is implicitly
// convertible to EncodableValue, so constructing an EncodableValue from a
// custom type can generally be written as:
// CustomEncodableValue(MyType(...))
// rather than:
// EncodableValue(CustomEncodableValue(MyType(...)))
//
// For extracting recieved custom types, it is implicitly convertible to
// std::any. For example:
// const MyType& my_type_value =
// std::any_cast<MyType>(std::get<CustomEncodableValue>(value));
//
// If RTTI is enabled, different extension types can be checked with type():
// if (custom_value->type() == typeid(SomeData)) { ... }
// Clients that wish to disable RTTI would need to decide on another approach
// for distinguishing types (e.g., in StandardCodecExtension::WriteValueOfType)
// if multiple custom types are needed. For instance, wrapping all of the
// extension types in an EncodableValue-style variant, and only ever storing
// that variant in CustomEncodableValue.
class CustomEncodableValue {
public:
explicit CustomEncodableValue(const std::any& value) : value_(value) {}
~CustomEncodableValue() = default;

// Allow implict conversion to std::any to allow direct use of any_cast.
operator std::any &() { return value_; }
operator const std::any &() const { return value_; }

#if __has_feature(cxx_rtti)
// Passthrough to std::any's type().
const std::type_info& type() const noexcept { return value_.type(); }
#endif

// This operator exists only to provide a stable ordering for use as a
// std::map key, to satisfy the compiler requirements for EncodableValue.
// It does not attempt to provide useful ordering semantics, and using a
// custom value as a map key is not recommended.
bool operator<(const CustomEncodableValue& other) const {
return this < &other;
}
bool operator==(const CustomEncodableValue& other) const {
return this == &other;
}

private:
std::any value_;
};

class EncodableValue;

// Convenience type aliases.
Expand All @@ -48,7 +99,8 @@ using EncodableValueVariant = std::variant<std::monostate,
std::vector<int64_t>,
std::vector<double>,
EncodableList,
EncodableMap>;
EncodableMap,
CustomEncodableValue>;
} // namespace internal

// An object that can contain any value or collection type supported by
Expand Down Expand Up @@ -76,7 +128,7 @@ using EncodableValueVariant = std::variant<std::monostate,
//
// The primary API surface for this object is std::variant. For instance,
// getting a string value from an EncodableValue, with type checking:
// if (std::get<std::string>(value)) {
// if (std::holds_alternative<std::string>(value)) {
// std::string some_string = std::get<std::string>(value);
// }
//
Expand All @@ -99,6 +151,13 @@ class EncodableValue : public internal::EncodableValueVariant {
return *this;
}

// Allow implicit conversion from CustomEncodableValue; the only reason to
// make a CustomEncodableValue (which can only be constructed explicitly) is
// to use it with EncodableValue, so the risk of unintended conversions is
// minimal, and it avoids the need for the verbose:
// EncodableValue(CustomEncodableValue(...)).
EncodableValue(const CustomEncodableValue& v) : super(v) {}

// Override the conversion constructors from std::variant to make them
// explicit, to avoid implicit conversion.
//
Expand Down
Loading