Skip to content

Commit

Permalink
Use byte[] for bytes type
Browse files Browse the repository at this point in the history
byte[] is the standard type used for IO operations within dotnet
ecosystem. Since `bytes` type would normally be used in IO context,
representings `bytes` as `List<byte>` was not a good choice. Passing
any `byte[]` IO data between C# and Rust would involve an additional
copy from `byte[]` to `List<byte>`. Using `byte[]` directly in uniffi
bindings removes the need for this extra copy.

List of IO classes using `byte[]`:
FileStream, BinaryReader, BinaryWriter, MemoryStream, Socket,
NetworkStream, GZipStream, DeflareStream, Aes, RSA, SHA256,
WebClient, HttpClient.
  • Loading branch information
arg0d committed Nov 15, 2023
1 parent dac800c commit cf0368c
Show file tree
Hide file tree
Showing 12 changed files with 26 additions and 87 deletions.
25 changes: 1 addition & 24 deletions bindgen/src/gen_cs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,6 @@ pub struct TypeAlias {
original_type: String,
}

fn get_bytes_underlying_type() -> Type {
Type::Sequence {
inner_type: Box::new(Type::UInt8),
}
}

impl<'a> TypeRenderer<'a> {
fn new(cs_config: &'a Config, ci: &'a ComponentInterface) -> Self {
Self {
Expand All @@ -125,23 +119,6 @@ impl<'a> TypeRenderer<'a> {
}
}

fn get_cs_types(&self) -> BTreeSet<Type> {
let mut types: BTreeSet<Type> = self.ci.iter_types().cloned().collect();

// Replace Type::Bytes with Type::Sequence<u8>
if types.remove(&Type::Bytes) {
let bytes_type = get_bytes_underlying_type();
types.insert(bytes_type.clone());

match bytes_type {
Type::Sequence { inner_type } => types.insert(*inner_type),
_ => panic!("incorrect bytes type: {:?}", bytes_type),
};
}

types
}

// Get the package name for an external type
fn external_type_package_name(&self, module_path: &str, namespace: &str) -> String {
// config overrides are keyed by the crate name, default fallback is the namespace.
Expand Down Expand Up @@ -269,7 +246,7 @@ impl<T: AsType> AsCodeType for T {
Type::Float64 => Box::new(primitives::Float64CodeType),
Type::Boolean => Box::new(primitives::BooleanCodeType),
Type::String => Box::new(primitives::StringCodeType),
Type::Bytes => get_bytes_underlying_type().as_codetype(),
Type::Bytes => Box::new(primitives::BytesCodeType),

Type::Timestamp => Box::new(miscellany::TimestampCodeType),
Type::Duration => Box::new(miscellany::DurationCodeType),
Expand Down
1 change: 1 addition & 0 deletions bindgen/src/gen_cs/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,4 @@ impl_code_type_for_primitive!(UInt32CodeType, "uint", "UInt32");
impl_code_type_for_primitive!(UInt64CodeType, "ulong", "UInt64");
impl_code_type_for_primitive!(Float32CodeType, "float", "Float");
impl_code_type_for_primitive!(Float64CodeType, "double", "Double");
impl_code_type_for_primitive!(BytesCodeType, "byte[]", "ByteArray");
21 changes: 21 additions & 0 deletions bindgen/templates/BytesTemplate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{#/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */#}

class {{ ffi_converter_name }}: FfiConverterRustBuffer<{{ type_name }}> {
public static {{ ffi_converter_name }} INSTANCE = new {{ ffi_converter_name }}();

public override {{ type_name }} Read(BigEndianStream stream) {
var length = stream.ReadInt();
return stream.ReadBytes(length);
}

public override int AllocationSize({{ type_name }} value) {
return 4 + value.Length;
}

public override void Write({{ type_name }} value, BigEndianStream stream) {
stream.WriteInt(value.Length);
stream.WriteBytes(value);
}
}
4 changes: 2 additions & 2 deletions bindgen/templates/Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

{%- import "macros.cs" as cs %}

{%- for type_ in self.get_cs_types() %}
{%- for type_ in ci.iter_types() %}
{%- let type_name = type_|type_name %}
{%- let ffi_converter_name = type_|ffi_converter_name %}
{%- let canonical_type_name = type_|canonical_name %}
Expand Down Expand Up @@ -78,7 +78,7 @@
{% include "SequenceTemplate.cs" %}

{%- when Type::Bytes %}
{{ "Type::Bytes not supposed to be rendered"|panic }}
{% include "BytesTemplate.cs" %}

{%- when Type::Map { key_type, value_type } %}
{% include "MapTemplate.cs" %}
Expand Down
16 changes: 0 additions & 16 deletions dotnet-tests/UniffiCS.binding_tests/TestBytesType.cs

This file was deleted.

2 changes: 1 addition & 1 deletion dotnet-tests/UniffiCS.binding_tests/TestCoverall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ public void MultiThreadedCallsWork() {
[Fact]
public void TestBytes() {
using (var coveralls = new Coveralls("test_bytes")) {
Assert.Equal(new List<byte> { 3, 2, 1 }, coveralls.Reverse(new List<byte> { 1, 2, 3 }));
Assert.Equal(new byte[] { 3, 2, 1 }, coveralls.Reverse(new byte[] { 1, 2, 3}));
}
}
}
1 change: 0 additions & 1 deletion fixtures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ path = "src/lib.rs"
crate-type = ["cdylib", "lib"]

[dependencies]
bytes-type = { path = "bytes-type" }
global-methods-class-name = { path = "global-methods-class-name" }
uniffi-cs-custom-types-builtin = { path = "custom-types-builtin" }
uniffi-cs-disposable-fixture = { path = "disposable" }
Expand Down
18 changes: 0 additions & 18 deletions fixtures/bytes-type/Cargo.toml

This file was deleted.

7 changes: 0 additions & 7 deletions fixtures/bytes-type/build.rs

This file was deleted.

7 changes: 0 additions & 7 deletions fixtures/bytes-type/src/bytes_type.udl

This file was deleted.

10 changes: 0 additions & 10 deletions fixtures/bytes-type/src/lib.rs

This file was deleted.

1 change: 0 additions & 1 deletion fixtures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ mod uniffi_fixtures {
uniffi_fixture_docstring::uniffi_reexport_scaffolding!();
uniffi_trait_methods::uniffi_reexport_scaffolding!();

bytes_type::uniffi_reexport_scaffolding!();
global_methods_class_name::uniffi_reexport_scaffolding!();
uniffi_cs_custom_types_builtin::uniffi_reexport_scaffolding!();
uniffi_cs_disposable::uniffi_reexport_scaffolding!();
Expand Down

0 comments on commit cf0368c

Please sign in to comment.