Skip to content

Commit

Permalink
update data array stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
Brendonovich committed Apr 5, 2023
1 parent 7b998ab commit 07269e5
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 58 deletions.
4 changes: 2 additions & 2 deletions src-rs/swift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ pub trait SwiftObject {

swift!(pub(crate) fn retain_object(obj: *const c_void));
swift!(pub(crate) fn release_object(obj: *const c_void));
swift!(pub(crate) fn allocate_string(data: *const u8, size: UInt) -> SRString);
swift!(pub(crate) fn allocate_data(data: *const u8, size: UInt) -> SRData);
swift!(pub(crate) fn data_from_bytes(data: *const u8, size: Int) -> SRData);
swift!(pub(crate) fn string_from_bytes(data: *const u8, size: Int) -> SRString);

/// Declares a function defined in a swift library.
/// As long as this macro is used, retain counts of arguments
Expand Down
14 changes: 8 additions & 6 deletions src-rs/types/data.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::swift::{self, SwiftObject};
use crate::{
swift::{self, SwiftObject},
Int,
};

use super::{array::SRArray, SRObject};

Expand All @@ -23,8 +26,8 @@ type Data = SRArray<u8>;
pub struct SRData(SRObject<Data>);

impl SRData {
pub fn as_array(&self) -> Vec<u8> {
self.0.as_ref().to_vec()
pub fn as_slice(&self) -> &[u8] {
self
}
}

Expand All @@ -51,9 +54,8 @@ impl AsRef<[u8]> for SRData {
}

impl From<&Vec<u8>> for SRData {
fn from(value: &Vec<u8>) -> SRData {
let data = value.as_slice();
unsafe { swift::allocate_data(data.as_ptr(), data.len()) }
fn from(value: &Vec<u8>) -> Self {
unsafe { swift::data_from_bytes(value.as_ptr(), value.len() as Int) }
}
}

Expand Down
6 changes: 3 additions & 3 deletions src-rs/types/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{

use crate::{
swift::{self, SwiftObject},
SRData, SRObject,
Int, SRData, SRObject,
};

/// String type that can be shared between Swift and Rust.
Expand Down Expand Up @@ -52,8 +52,8 @@ impl AsRef<[u8]> for SRString {
}

impl From<&str> for SRString {
fn from(string: &str) -> SRString {
unsafe { swift::allocate_string(string.as_ptr(), string.len()) }
fn from(string: &str) -> Self {
unsafe { swift::string_from_bytes(string.as_ptr(), string.len() as Int) }
}
}

Expand Down
38 changes: 24 additions & 14 deletions src-swift/lib.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public class SRArray<T>: NSObject {
self.pointer = UnsafePointer(self.array)
self.length = data.count
}

public func toArray() -> [T] {
return Array(self.array)
}
}

public class SRObjectArray: NSObject {
Expand All @@ -39,9 +43,13 @@ public class SRData: NSObject {
public init(_ data: [UInt8]) {
self.data = SRArray(data)
}

public init (_ srArray: SRArray<UInt8>) {
self.data = srArray
}

public func array() -> [UInt8]{
return self.data.array
public func toArray() -> [UInt8] {
return self.data.toArray()
}
}

Expand All @@ -54,18 +62,15 @@ public class SRString: SRData {
super.init(Array(string.utf8))
}

init(_ data: SRData) {
super.init(data.data)
}

public func toString() -> String {
return String(bytes: self.data.array, encoding: .utf8)!
}
}

@_cdecl("allocate_string")
func allocateString(data: UnsafePointer<UInt8>, size: Int) -> SRString {
let buffer = UnsafeBufferPointer(start: data, count: size)
let string = String(bytes: buffer, encoding: .utf8)!
return SRString(string)
}

@_cdecl("retain_object")
func retainObject(ptr: UnsafeMutableRawPointer) {
let _ = Unmanaged<AnyObject>.fromOpaque(ptr).retain()
Expand All @@ -76,9 +81,14 @@ func releaseObject(ptr: UnsafeMutableRawPointer) {
let _ = Unmanaged<AnyObject>.fromOpaque(ptr).release()
}

@_cdecl("allocate_data")
func allocateData(data: UnsafePointer<UInt8>, size: Int) -> SRData {
let bufferPointer = UnsafeRawBufferPointer(start: data, count: size)
let newData: [UInt8] = Array(bufferPointer)
return SRData(newData)
@_cdecl("data_from_bytes")
func dataFromBytes(data: UnsafePointer<UInt8>, size: Int) -> SRData {
let buffer = UnsafeBufferPointer(start: data, count: size)
return SRData(Array(buffer))
}

@_cdecl("string_from_bytes")
func stringFromBytes(data: UnsafePointer<UInt8>, size: Int) -> SRString {
let data = dataFromBytes(data: data, size: size);
return SRString(data)
}
2 changes: 1 addition & 1 deletion tests/swift-pkg/doctests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,5 @@ func getData() -> SRData {

@_cdecl("send_and_get_data")
func sendAndGetData(data: SRData) -> SRData {
return SRData(data.array())
return SRData(data.toArray())
}
5 changes: 5 additions & 0 deletions tests/swift-pkg/lib.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,8 @@ func complexData() -> SRObjectArray {
Complex(a: SRString("Oscar"), b: 3, c: false),
])
}

@_cdecl("reflect_data")
func reflectData(input: SRData) -> SRData {
return SRData(input.toArray())
}
59 changes: 27 additions & 32 deletions tests/test_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,7 @@ macro_rules! test_with_leaks {
}};
}

#[test]
#[serial]
fn test_string() {
test_with_leaks!(|| {
let name: SRString = "Brendan".into();
let greeting = unsafe { get_greeting(&name) };
assert_eq!(greeting.as_str(), "Hello Brendan!");
});
}
swift!(fn echo(string: &SRString) -> SRString);

#[test]
#[serial]
Expand All @@ -72,6 +64,18 @@ fn test_reflection() {
});
}

swift!(fn get_greeting(name: &SRString) -> SRString);

#[test]
#[serial]
fn test_string() {
test_with_leaks!(|| {
let name: SRString = "Brendan".into();
let greeting = unsafe { get_greeting(&name) };
assert_eq!(greeting.as_str(), "Hello Brendan!");
});
}

#[test]
#[serial]
fn test_memory_pressure() {
Expand Down Expand Up @@ -100,6 +104,15 @@ fn test_autoreleasepool() {
});
}

#[repr(C)]
struct Complex {
a: SRString,
b: Int,
c: Bool,
}

swift!(fn complex_data() -> SRObjectArray<Complex>);

#[test]
#[serial]
fn test_complex() {
Expand All @@ -114,39 +127,21 @@ fn test_complex() {
});
}

swift!(fn send_and_get_data(data: &SRData) -> SRData);

#[test]
#[serial]
fn test_data() {
test_with_leaks!(|| {
let mut v = vec![];

let str: &str = "hello";
let bytes: Vec<u8> = str.as_bytes().to_vec();
let bytes = &str.as_bytes().to_vec();
for _ in 0..10_000 {
let swift_byte: SRData = SRData::from(&bytes);
let data = unsafe { send_and_get_data(swift_byte) };
assert_eq!(
data.as_array().as_slice(),
SRData::from(&bytes).as_array().as_slice()
);
v.push(data);
let data = unsafe { send_and_get_data(&bytes.into()) };
assert_eq!(data.as_slice(), bytes);
}
});
}

swift!(fn get_greeting(name: &SRString) -> SRString);
swift!(fn echo(string: &SRString) -> SRString);

#[repr(C)]
struct Complex {
a: SRString,
b: Int,
c: Bool,
}

swift!(fn complex_data() -> SRObjectArray<Complex>);
swift!(fn send_and_get_data(data: SRData) -> SRData);

const DEBUG_PLIST_XML: &str = r#"<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
Expand Down

0 comments on commit 07269e5

Please sign in to comment.