Skip to content

Commit

Permalink
Merge pull request #44 from LeviticusNelson/master
Browse files Browse the repository at this point in the history
add method to convert to and from SRData
  • Loading branch information
Brendonovich committed Apr 4, 2023
2 parents a695ab9 + ece0589 commit 7b998ab
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 3 deletions.
1 change: 1 addition & 0 deletions src-rs/swift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ 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);

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

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

Expand All @@ -22,6 +22,12 @@ type Data = SRArray<u8>;
#[repr(transparent)]
pub struct SRData(SRObject<Data>);

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

impl SwiftObject for SRData {
type Shape = Data;

Expand All @@ -44,6 +50,13 @@ 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()) }
}
}

#[cfg(feature = "serde")]
impl serde::Serialize for SRData {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
Expand Down
11 changes: 11 additions & 0 deletions src-swift/lib.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public class SRData: NSObject {
public init(_ data: [UInt8]) {
self.data = SRArray(data)
}

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

public class SRString: SRData {
Expand Down Expand Up @@ -71,3 +75,10 @@ func retainObject(ptr: UnsafeMutableRawPointer) {
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)
}
9 changes: 7 additions & 2 deletions tests/swift-pkg/doctests.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import SwiftRs
import Foundation
import SwiftRs

// SRArray
//
//
// Notice that IntArray and ArrayStruct are almost identical!
// The only actual difference between these types is how they're used in Rust,
// but if you added more fields to ArrayStruct then that wouldn't be the case anymore.
Expand Down Expand Up @@ -68,3 +68,8 @@ func echo(string: SRString) -> SRString {
func getData() -> SRData {
return SRData([1, 2, 3])
}

@_cdecl("send_and_get_data")
func sendAndGetData(data: SRData) -> SRData {
return SRData(data.array())
}
21 changes: 21 additions & 0 deletions tests/test_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,26 @@ fn test_complex() {
});
}

#[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();
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);
}
});
}

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

Expand All @@ -125,6 +145,7 @@ struct Complex {
}

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">
Expand Down

0 comments on commit 7b998ab

Please sign in to comment.