Move u16strlcpy to the VST3 wrapper utils module
This commit is contained in:
parent
c917114020
commit
0fd9a68146
|
@ -1,8 +1,6 @@
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
use vst3_sys::vst::TChar;
|
|
||||||
use widestring::U16CString;
|
|
||||||
|
|
||||||
#[cfg(all(debug_assertions, feature = "assert_process_allocs"))]
|
#[cfg(all(debug_assertions, feature = "assert_process_allocs"))]
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
|
@ -41,29 +39,6 @@ pub fn strlcpy(dest: &mut [c_char], src: &str) {
|
||||||
dest[copy_len] = 0;
|
dest[copy_len] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The same as [`strlcpy()`], but for VST3's fun UTF-16 strings instead.
|
|
||||||
pub fn u16strlcpy(dest: &mut [TChar], src: &str) {
|
|
||||||
if dest.is_empty() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let src_utf16 = match U16CString::from_str(src) {
|
|
||||||
Ok(s) => s,
|
|
||||||
Err(err) => {
|
|
||||||
nih_debug_assert_failure!("Invalid UTF-16 string: {}", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let src_utf16_chars = src_utf16.as_slice();
|
|
||||||
let src_utf16_chars_signed: &[TChar] =
|
|
||||||
unsafe { &*(src_utf16_chars as *const [u16] as *const [TChar]) };
|
|
||||||
|
|
||||||
// Make sure there's always room for a null terminator
|
|
||||||
let copy_len = cmp::min(dest.len() - 1, src_utf16_chars_signed.len());
|
|
||||||
dest[..copy_len].copy_from_slice(&src_utf16_chars_signed[..copy_len]);
|
|
||||||
dest[copy_len] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A wrapper around the entire process function, including the plugin wrapper parts. This sets up
|
/// A wrapper around the entire process function, including the plugin wrapper parts. This sets up
|
||||||
/// `assert_no_alloc` if needed, while also making sure that things like FTZ are set up correctly if
|
/// `assert_no_alloc` if needed, while also making sure that things like FTZ are set up correctly if
|
||||||
/// the host has not already done so.
|
/// the host has not already done so.
|
||||||
|
@ -135,7 +110,6 @@ impl Drop for ScopedFtz {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod miri {
|
mod miri {
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use widestring::U16CStr;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -160,30 +134,4 @@ mod miri {
|
||||||
Ok("Hello")
|
Ok("Hello")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn u16strlcpy_normal() {
|
|
||||||
let mut dest = [0; 256];
|
|
||||||
u16strlcpy(&mut dest, "Hello, world!");
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { U16CStr::from_ptr_str(dest.as_ptr() as *const u16) }
|
|
||||||
.to_string()
|
|
||||||
.unwrap(),
|
|
||||||
"Hello, world!"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn u16strlcpy_overflow() {
|
|
||||||
let mut dest = [0; 6];
|
|
||||||
u16strlcpy(&mut dest, "Hello, world!");
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { U16CStr::from_ptr_str(dest.as_ptr() as *const u16) }
|
|
||||||
.to_string()
|
|
||||||
.unwrap(),
|
|
||||||
"Hello"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,10 @@ use vst3_sys::VST3;
|
||||||
// Alias needed for the VST3 attribute macro
|
// Alias needed for the VST3 attribute macro
|
||||||
use vst3_sys as vst3_com;
|
use vst3_sys as vst3_com;
|
||||||
|
|
||||||
|
use super::util::u16strlcpy;
|
||||||
use super::wrapper::Wrapper;
|
use super::wrapper::Wrapper;
|
||||||
use crate::plugin::Vst3Plugin;
|
use crate::plugin::Vst3Plugin;
|
||||||
use crate::wrapper::util::{strlcpy, u16strlcpy};
|
use crate::wrapper::util::strlcpy;
|
||||||
|
|
||||||
/// The VST3 SDK version this is roughtly based on.
|
/// The VST3 SDK version this is roughtly based on.
|
||||||
const VST3_SDK_VERSION: &str = "VST 3.6.14";
|
const VST3_SDK_VERSION: &str = "VST 3.6.14";
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
|
use std::cmp;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use vst3_sys::{interfaces::IUnknown, ComInterface};
|
use vst3_sys::interfaces::IUnknown;
|
||||||
|
use vst3_sys::vst::TChar;
|
||||||
|
use vst3_sys::ComInterface;
|
||||||
|
use widestring::U16CString;
|
||||||
|
|
||||||
/// When `Plugin::MIDI_INPUT` is set to `MidiConfig::MidiCCs` or higher then we'll register 130*16
|
/// When `Plugin::MIDI_INPUT` is set to `MidiConfig::MidiCCs` or higher then we'll register 130*16
|
||||||
/// additional parameters to handle MIDI CCs, channel pressure, and pitch bend, in that order.
|
/// additional parameters to handle MIDI CCs, channel pressure, and pitch bend, in that order.
|
||||||
|
@ -32,6 +36,29 @@ macro_rules! check_null_ptr_msg {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The same as [`strlcpy()`], but for VST3's fun UTF-16 strings instead.
|
||||||
|
pub fn u16strlcpy(dest: &mut [TChar], src: &str) {
|
||||||
|
if dest.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let src_utf16 = match U16CString::from_str(src) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(err) => {
|
||||||
|
nih_debug_assert_failure!("Invalid UTF-16 string: {}", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let src_utf16_chars = src_utf16.as_slice();
|
||||||
|
let src_utf16_chars_signed: &[TChar] =
|
||||||
|
unsafe { &*(src_utf16_chars as *const [u16] as *const [TChar]) };
|
||||||
|
|
||||||
|
// Make sure there's always room for a null terminator
|
||||||
|
let copy_len = cmp::min(dest.len() - 1, src_utf16_chars_signed.len());
|
||||||
|
dest[..copy_len].copy_from_slice(&src_utf16_chars_signed[..copy_len]);
|
||||||
|
dest[copy_len] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// Send+Sync wrapper for these interface pointers.
|
/// Send+Sync wrapper for these interface pointers.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct VstPtr<T: vst3_sys::ComInterface + ?Sized> {
|
pub struct VstPtr<T: vst3_sys::ComInterface + ?Sized> {
|
||||||
|
@ -88,3 +115,36 @@ unsafe impl<T: ComInterface + ?Sized> Sync for VstPtr<T> {}
|
||||||
|
|
||||||
unsafe impl<T: IUnknown> Send for ObjectPtr<T> {}
|
unsafe impl<T: IUnknown> Send for ObjectPtr<T> {}
|
||||||
unsafe impl<T: IUnknown> Sync for ObjectPtr<T> {}
|
unsafe impl<T: IUnknown> Sync for ObjectPtr<T> {}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod miri {
|
||||||
|
use widestring::U16CStr;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn u16strlcpy_normal() {
|
||||||
|
let mut dest = [0; 256];
|
||||||
|
u16strlcpy(&mut dest, "Hello, world!");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { U16CStr::from_ptr_str(dest.as_ptr() as *const u16) }
|
||||||
|
.to_string()
|
||||||
|
.unwrap(),
|
||||||
|
"Hello, world!"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn u16strlcpy_overflow() {
|
||||||
|
let mut dest = [0; 6];
|
||||||
|
u16strlcpy(&mut dest, "Hello, world!");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { U16CStr::from_ptr_str(dest.as_ptr() as *const u16) }
|
||||||
|
.to_string()
|
||||||
|
.unwrap(),
|
||||||
|
"Hello"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,7 +16,9 @@ use vst3_sys::VST3;
|
||||||
use widestring::U16CStr;
|
use widestring::U16CStr;
|
||||||
|
|
||||||
use super::inner::WrapperInner;
|
use super::inner::WrapperInner;
|
||||||
use super::util::{VstPtr, VST3_MIDI_CCS, VST3_MIDI_NUM_PARAMS, VST3_MIDI_PARAMS_START};
|
use super::util::{
|
||||||
|
u16strlcpy, VstPtr, VST3_MIDI_CCS, VST3_MIDI_NUM_PARAMS, VST3_MIDI_PARAMS_START,
|
||||||
|
};
|
||||||
use super::view::WrapperView;
|
use super::view::WrapperView;
|
||||||
use crate::context::Transport;
|
use crate::context::Transport;
|
||||||
use crate::midi::{MidiConfig, NoteEvent};
|
use crate::midi::{MidiConfig, NoteEvent};
|
||||||
|
@ -24,7 +26,7 @@ use crate::param::ParamFlags;
|
||||||
use crate::plugin::{BufferConfig, BusConfig, ProcessStatus, Vst3Plugin};
|
use crate::plugin::{BufferConfig, BusConfig, ProcessStatus, Vst3Plugin};
|
||||||
use crate::util::permit_alloc;
|
use crate::util::permit_alloc;
|
||||||
use crate::wrapper::state;
|
use crate::wrapper::state;
|
||||||
use crate::wrapper::util::{process_wrapper, u16strlcpy};
|
use crate::wrapper::util::process_wrapper;
|
||||||
use crate::wrapper::vst3::inner::ProcessEvent;
|
use crate::wrapper::vst3::inner::ProcessEvent;
|
||||||
use crate::wrapper::vst3::note_expressions::NoteExpressionController;
|
use crate::wrapper::vst3::note_expressions::NoteExpressionController;
|
||||||
use crate::wrapper::vst3::util::{VST3_MIDI_CHANNELS, VST3_MIDI_PARAMS_END};
|
use crate::wrapper::vst3::util::{VST3_MIDI_CHANNELS, VST3_MIDI_PARAMS_END};
|
||||||
|
|
Loading…
Reference in a new issue