Let Swift allocate as much memory as it needs and then transfer ownership to Rust

This commit is contained in:
Shadowfacts 2022-08-17 21:19:53 -04:00
parent f9d3a5e397
commit 20d5480534
2 changed files with 10 additions and 20 deletions

View File

@ -2,17 +2,18 @@ import Foundation
import Splash
@_cdecl("highlight_swift")
public func highlight(codePtr: UnsafeRawPointer, codeLen: UInt64, outPtr: UnsafeMutableRawPointer, maxLen: UInt64) -> UInt64 {
public func highlight(codePtr: UnsafeRawPointer, codeLen: UInt64, htmlLenPtr: UnsafeMutablePointer<UInt64>) -> UnsafeMutableRawPointer {
// don't free, the underlying data is owned by rust
let code = String(bytesNoCopy: UnsafeMutableRawPointer(mutating: codePtr), length: Int(codeLen), encoding: .utf8, freeWhenDone: false)!
let highligher = SyntaxHighlighter(format: MyOutputFormat())
var html = highligher.highlight(code)
precondition(html.utf8.count <= maxLen)
return html.withUTF8 { buf in
buf.copyBytes(to: UnsafeMutableRawBufferPointer(start: outPtr, count: Int(maxLen)))
return UInt64(buf.count)
let outPtr = UnsafeMutableBufferPointer<UInt8>.allocate(capacity: html.utf8.count)
_ = html.withUTF8 { buf in
buf.copyBytes(to: outPtr, count: buf.count)
}
htmlLenPtr.pointee = UInt64(html.utf8.count)
return UnsafeMutableRawPointer(outPtr.baseAddress!)
}
struct MyOutputFormat: OutputFormat {

View File

@ -1,24 +1,13 @@
pub fn highlight(code: &str) -> String {
unsafe {
let mut buf = Vec::new();
buf.reserve(
2usize
.pow(1 + (code.len() as f32).log2().ceil() as u32)
.max(1024),
);
let used = highlight_swift(
code.as_ptr(),
code.len() as u64,
buf.as_mut_ptr(),
buf.capacity() as u64,
);
buf.set_len(used as usize);
String::from_utf8_unchecked(buf)
let mut html_len: u64 = 0;
let html_ptr = highlight_swift(code.as_ptr(), code.len() as u64, &mut html_len);
String::from_raw_parts(html_ptr, html_len as usize, html_len as usize)
}
}
extern "C" {
fn highlight_swift(code_ptr: *const u8, code_len: u64, out_ptr: *mut u8, max_len: u64) -> u64;
fn highlight_swift(code_ptr: *const u8, code_len: u64, html_len_ptr: *mut u64) -> *mut u8;
}
#[cfg(test)]