musikr: fix iostream pinning
This commit is contained in:
parent
74edd1dbdf
commit
249915c3be
5 changed files with 79 additions and 83 deletions
|
@ -1,4 +1,4 @@
|
|||
use crate::taglib::stream::IOStream;
|
||||
use crate::taglib::file::IOStream;
|
||||
use jni::objects::{JObject, JValue};
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
use crate::SharedEnv;
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
use super::stream::BridgeStream;
|
||||
|
||||
#[cxx::bridge]
|
||||
mod bridge_impl {
|
||||
// Expose Rust IOStream to C++
|
||||
extern "Rust" {
|
||||
#[cxx_name = "BridgeStream"]
|
||||
type BridgeStream<'a>;
|
||||
type TIOStream<'a>;
|
||||
|
||||
fn name(self: &mut BridgeStream<'_>) -> String;
|
||||
fn read(self: &mut BridgeStream<'_>, buffer: &mut [u8]) -> usize;
|
||||
fn write(self: &mut BridgeStream<'_>, data: &[u8]);
|
||||
fn seek(self: &mut BridgeStream<'_>, offset: i64, whence: i32);
|
||||
fn truncate(self: &mut BridgeStream<'_>, length: i64);
|
||||
fn tell(self: &mut BridgeStream<'_>) -> i64;
|
||||
fn length(self: &mut BridgeStream<'_>) -> i64;
|
||||
fn is_readonly(self: &BridgeStream<'_>) -> bool;
|
||||
fn name(self: &mut TIOStream<'_>) -> String;
|
||||
fn read(self: &mut TIOStream<'_>, buffer: &mut [u8]) -> usize;
|
||||
fn write(self: &mut TIOStream<'_>, data: &[u8]);
|
||||
fn seek(self: &mut TIOStream<'_>, offset: i64, whence: i32);
|
||||
fn truncate(self: &mut TIOStream<'_>, length: i64);
|
||||
fn tell(self: &mut TIOStream<'_>) -> i64;
|
||||
fn length(self: &mut TIOStream<'_>) -> i64;
|
||||
fn is_readonly(self: &TIOStream<'_>) -> bool;
|
||||
}
|
||||
|
||||
#[namespace = "taglib_shim"]
|
||||
|
@ -40,7 +38,7 @@ mod bridge_impl {
|
|||
fn thisFile(self: Pin<&TFileRef>) -> *mut BaseFile;
|
||||
|
||||
// Create a RustIOStream from a BridgeStream
|
||||
unsafe fn new_RustIOStream(stream: Pin<&mut BridgeStream>) -> UniquePtr<RustIOStream>;
|
||||
unsafe fn new_RustIOStream(stream: Pin<&mut TIOStream>) -> UniquePtr<RustIOStream>;
|
||||
// Create a FileRef from an iostream
|
||||
fn new_FileRef_from_stream(stream: UniquePtr<RustIOStream>) -> UniquePtr<TFileRef>;
|
||||
|
||||
|
@ -154,3 +152,60 @@ mod bridge_impl {
|
|||
}
|
||||
|
||||
pub use bridge_impl::*;
|
||||
|
||||
use std::io::SeekFrom;
|
||||
use std::pin::Pin;
|
||||
use super::file::IOStream;
|
||||
|
||||
#[repr(C)]
|
||||
pub(super) struct TIOStream<'a>(Box<dyn IOStream + 'a>);
|
||||
|
||||
impl<'a> TIOStream<'a> {
|
||||
pub fn new<T: IOStream + 'a>(stream: T) -> Pin<Box<Self>> {
|
||||
Box::pin(TIOStream(Box::new(stream)))
|
||||
}
|
||||
|
||||
|
||||
// Implement the exposed functions for cxx bridge
|
||||
pub fn name(&mut self) -> String {
|
||||
self.0.name()
|
||||
}
|
||||
|
||||
pub fn read(&mut self, buffer: &mut [u8]) -> usize {
|
||||
self.0.read(buffer).unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn write(&mut self, data: &[u8]) {
|
||||
self.0.write_all(data).unwrap();
|
||||
}
|
||||
|
||||
pub fn seek(&mut self, offset: i64, whence: i32) {
|
||||
let pos = match whence {
|
||||
0 => SeekFrom::Start(offset as u64),
|
||||
1 => SeekFrom::Current(offset),
|
||||
2 => SeekFrom::End(offset),
|
||||
_ => panic!("Invalid seek whence"),
|
||||
};
|
||||
self.0.seek(pos).unwrap();
|
||||
}
|
||||
|
||||
pub fn truncate(&mut self, length: i64) {
|
||||
self.0.seek(SeekFrom::Start(length as u64)).unwrap();
|
||||
// TODO: Actually implement truncate once we have a better trait bound
|
||||
}
|
||||
|
||||
pub fn tell(&mut self) -> i64 {
|
||||
self.0.seek(SeekFrom::Current(0)).unwrap() as i64
|
||||
}
|
||||
|
||||
pub fn length(&mut self) -> i64 {
|
||||
let current = self.0.seek(SeekFrom::Current(0)).unwrap();
|
||||
let end = self.0.seek(SeekFrom::End(0)).unwrap();
|
||||
self.0.seek(SeekFrom::Start(current)).unwrap();
|
||||
end as i64
|
||||
}
|
||||
|
||||
pub fn is_readonly(&self) -> bool {
|
||||
self.0.is_readonly()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
use cxx::UniquePtr;
|
||||
use super::bridge::{self, TFileRef};
|
||||
use super::bridge::{self, TFileRef, TIOStream};
|
||||
pub use super::bridge::{BaseFile as File, AudioProperties};
|
||||
use super::xiph::{OpusFile, VorbisFile, FLACFile};
|
||||
use super::stream::BridgeStream;
|
||||
use super::stream::IOStream;
|
||||
use std::io::{Read, Write, Seek};
|
||||
use std::pin::Pin;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub struct FileRef<'a> {
|
||||
stream: BridgeStream<'a>,
|
||||
stream: Pin<Box<TIOStream<'a>>>,
|
||||
file_ref: UniquePtr<TFileRef>
|
||||
}
|
||||
|
||||
impl <'a> FileRef<'a> {
|
||||
pub fn new<T : IOStream + 'a>(stream: T) -> FileRef<'a> {
|
||||
let mut bridge_stream = BridgeStream::new(stream);
|
||||
let iostream = unsafe { bridge::new_RustIOStream(Pin::new(&mut bridge_stream)) };
|
||||
let mut bridge_stream = TIOStream::new(stream);
|
||||
let iostream = unsafe { bridge::new_RustIOStream(bridge_stream.as_mut()) };
|
||||
let file_ref = bridge::new_FileRef_from_stream(iostream);
|
||||
FileRef {
|
||||
stream: bridge_stream,
|
||||
|
@ -197,3 +195,8 @@ impl <'a> Drop for FileRef<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IOStream: Read + Write + Seek {
|
||||
fn name(&mut self) -> String;
|
||||
fn is_readonly(&self) -> bool;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
mod bridge;
|
||||
|
||||
pub mod file;
|
||||
pub mod stream;
|
||||
pub mod tk;
|
||||
pub mod xiph;
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
use std::ffi::{c_void, CString};
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
use std::os::raw::c_char;
|
||||
use cxx::CxxString;
|
||||
|
||||
pub trait IOStream: Read + Write + Seek {
|
||||
fn name(&mut self) -> String;
|
||||
fn is_readonly(&self) -> bool;
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub(super) struct BridgeStream<'a>(Box<dyn IOStream + 'a>);
|
||||
|
||||
impl<'a> BridgeStream<'a> {
|
||||
pub fn new<T: IOStream + 'a>(stream: T) -> Self {
|
||||
BridgeStream(Box::new(stream))
|
||||
}
|
||||
|
||||
// Implement the exposed functions for cxx bridge
|
||||
pub fn name(&mut self) -> String {
|
||||
self.0.name()
|
||||
}
|
||||
|
||||
pub fn read(&mut self, buffer: &mut [u8]) -> usize {
|
||||
self.0.read(buffer).unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn write(&mut self, data: &[u8]) {
|
||||
self.0.write_all(data).unwrap();
|
||||
}
|
||||
|
||||
pub fn seek(&mut self, offset: i64, whence: i32) {
|
||||
let pos = match whence {
|
||||
0 => SeekFrom::Start(offset as u64),
|
||||
1 => SeekFrom::Current(offset),
|
||||
2 => SeekFrom::End(offset),
|
||||
_ => panic!("Invalid seek whence"),
|
||||
};
|
||||
self.0.seek(pos).unwrap();
|
||||
}
|
||||
|
||||
pub fn truncate(&mut self, length: i64) {
|
||||
self.0.seek(SeekFrom::Start(length as u64)).unwrap();
|
||||
// TODO: Actually implement truncate once we have a better trait bound
|
||||
}
|
||||
|
||||
pub fn tell(&mut self) -> i64 {
|
||||
self.0.seek(SeekFrom::Current(0)).unwrap() as i64
|
||||
}
|
||||
|
||||
pub fn length(&mut self) -> i64 {
|
||||
let current = self.0.seek(SeekFrom::Current(0)).unwrap();
|
||||
let end = self.0.seek(SeekFrom::End(0)).unwrap();
|
||||
self.0.seek(SeekFrom::Start(current)).unwrap();
|
||||
end as i64
|
||||
}
|
||||
|
||||
pub fn is_readonly(&self) -> bool {
|
||||
self.0.is_readonly()
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue