use crate::{
error::{ArrayError, SizeError},
C_STRING_FAILURE,
};
use std::ffi::CString;
pub fn array_size<T: AsRef<str>>(name: T) -> Result<i32, SizeError> {
unsafe {
let name = CString::new(name.as_ref()).expect(C_STRING_FAILURE);
let result = libpd_sys::libpd_arraysize(name.as_ptr());
if result >= 0 {
return Ok(result);
}
Err(SizeError::CouldNotDetermine)
}
}
pub fn resize_array<T: AsRef<str>>(name: T, size: i32) -> Result<(), SizeError> {
unsafe {
let name = CString::new(name.as_ref()).expect(C_STRING_FAILURE);
#[cfg(target_os = "macos")]
match libpd_sys::libpd_resize_array(name.as_ptr(), i64::from(size)) {
0 => Ok(()),
_ => Err(SizeError::CouldNotDetermine),
}
#[cfg(target_os = "linux")]
match libpd_sys::libpd_resize_array(name.as_ptr(), i64::from(size)) {
0 => Ok(()),
_ => Err(SizeError::CouldNotDetermine),
}
#[cfg(target_os = "windows")]
match libpd_sys::libpd_resize_array(name.as_ptr(), size) {
0 => Ok(()),
_ => Err(SizeError::CouldNotDetermine),
}
}
}
pub fn read_float_array_from<T: AsRef<str>>(
source_name: T,
source_read_offset: i32,
source_read_amount: i32,
destination: &mut [f32],
) -> Result<(), ArrayError> {
unsafe {
let name = CString::new(source_name.as_ref()).expect(C_STRING_FAILURE);
if source_read_offset + source_read_amount
> array_size(source_name.as_ref()).map_err(|_| ArrayError::FailedToFindArray)? as i32
|| source_read_amount < 0
{
return Err(ArrayError::OutOfBounds);
}
match libpd_sys::libpd_read_array(
destination.as_mut_ptr(),
name.as_ptr(),
source_read_offset,
source_read_amount,
) {
0 => Ok(()),
_ => Err(ArrayError::FailedToFindArray),
}
}
}
pub fn write_float_array_to<T: AsRef<str>>(
destination_name: T,
destination_write_offset: i32,
source: &[f32],
source_read_amount: i32,
) -> Result<(), ArrayError> {
unsafe {
let name = CString::new(destination_name.as_ref()).expect(C_STRING_FAILURE);
#[allow(clippy::cast_sign_loss)]
if destination_write_offset + source_read_amount
> array_size(destination_name.as_ref()).map_err(|_| ArrayError::FailedToFindArray)?
as i32
|| source_read_amount < 0
|| source_read_amount as usize > source.len()
{
return Err(ArrayError::OutOfBounds);
}
match libpd_sys::libpd_write_array(
name.as_ptr(),
destination_write_offset,
source.as_ptr(),
source_read_amount,
) {
0 => Ok(()),
_ => Err(ArrayError::FailedToFindArray),
}
}
}
pub fn read_double_array_from<T: AsRef<str>>(
source_name: T,
source_read_offset: i32,
source_read_amount: i32,
destination: &mut [f64],
) -> Result<(), ArrayError> {
unsafe {
let name = CString::new(source_name.as_ref()).expect(C_STRING_FAILURE);
if source_read_offset + source_read_amount
> array_size(source_name.as_ref()).map_err(|_| ArrayError::FailedToFindArray)? as i32
|| source_read_amount < 0
{
return Err(ArrayError::OutOfBounds);
}
match libpd_sys::libpd_read_array_double(
destination.as_mut_ptr(),
name.as_ptr(),
source_read_offset,
source_read_amount,
) {
0 => Ok(()),
_ => Err(ArrayError::FailedToFindArray),
}
}
}
pub fn write_double_array_to<T: AsRef<str>>(
destination_name: T,
destination_write_offset: i32,
source: &[f64],
source_read_amount: i32,
) -> Result<(), ArrayError> {
unsafe {
let name = CString::new(destination_name.as_ref()).expect(C_STRING_FAILURE);
#[allow(clippy::cast_sign_loss)]
if destination_write_offset + source_read_amount
> array_size(destination_name.as_ref()).map_err(|_| ArrayError::FailedToFindArray)?
as i32
|| source_read_amount < 0
|| source_read_amount as usize > source.len()
{
return Err(ArrayError::OutOfBounds);
}
match libpd_sys::libpd_write_array_double(
name.as_ptr(),
destination_write_offset,
source.as_ptr(),
source_read_amount,
) {
0 => Ok(()),
_ => Err(ArrayError::FailedToFindArray),
}
}
}