use std::ptr;
use crate::{
binding::fixnum,
rubysys::io_buffer::{self, rb_io_buffer_flags, rb_off_t},
types::{c_void, Value},
util,
};
pub fn new(size: usize) -> Value {
unsafe { io_buffer::rb_io_buffer_new(ptr::null_mut(), size, io_buffer::RB_IO_BUFFER_INTERNAL) }
}
pub unsafe fn new_external(base: *mut c_void, size: usize, flags: rb_io_buffer_flags) -> Value {
io_buffer::rb_io_buffer_new(base, size, flags)
}
pub unsafe fn map(io: Value, size: usize, offset: i64, flags: rb_io_buffer_flags) -> Value {
io_buffer::rb_io_buffer_map(io, size, offset as rb_off_t, flags)
}
pub fn lock(buffer: Value) -> Value {
unsafe { io_buffer::rb_io_buffer_lock(buffer) }
}
pub fn unlock(buffer: Value) -> Value {
unsafe { io_buffer::rb_io_buffer_unlock(buffer) }
}
pub fn try_unlock(buffer: Value) -> bool {
util::c_int_to_bool(unsafe { io_buffer::rb_io_buffer_try_unlock(buffer) })
}
pub fn free(buffer: Value) -> Value {
unsafe { io_buffer::rb_io_buffer_free(buffer) }
}
pub fn get_bytes(buffer: Value) -> (*mut u8, usize, rb_io_buffer_flags) {
let mut base = ptr::null_mut();
let mut size = 0;
let flags = unsafe { io_buffer::rb_io_buffer_get_bytes(buffer, &mut base, &mut size) };
(base as *mut u8, size, flags)
}
pub fn get_bytes_for_reading(buffer: Value) -> (*const u8, usize) {
let mut base = ptr::null();
let mut size = 0;
unsafe { io_buffer::rb_io_buffer_get_bytes_for_reading(buffer, &mut base, &mut size) };
(base as *const u8, size)
}
pub fn get_bytes_for_writing(buffer: Value) -> (*mut u8, usize) {
let mut base = ptr::null_mut();
let mut size = 0;
unsafe { io_buffer::rb_io_buffer_get_bytes_for_writing(buffer, &mut base, &mut size) };
(base as *mut u8, size)
}
pub fn transfer(buffer: Value) -> Value {
unsafe { io_buffer::rb_io_buffer_transfer(buffer) }
}
pub fn resize(buffer: Value, size: usize) {
unsafe { io_buffer::rb_io_buffer_resize(buffer, size) }
}
pub fn clear(buffer: Value, value: u8, offset: usize, length: usize) {
unsafe { io_buffer::rb_io_buffer_clear(buffer, value, offset, length) }
}
#[cfg(ruby_3_1)]
fn from_offset(buffer: Value, offset: usize) -> Value {
if offset == 0 {
return buffer;
}
let (_, size, _) = get_bytes(buffer);
let arguments = [
fixnum::usize_to_num(offset),
fixnum::usize_to_num(size - offset),
];
crate::binding::vm::call_method(buffer, "slice", &arguments)
}
#[cfg(ruby_3_1)]
pub fn read(buffer: Value, io: Value, length: usize, offset: usize) -> Value {
unsafe { io_buffer::rb_io_buffer_read(from_offset(buffer, offset), io, length) }
}
#[cfg(ruby_gte_3_2)]
pub fn read(buffer: Value, io: Value, length: usize, offset: usize) -> Value {
unsafe { io_buffer::rb_io_buffer_read(buffer, io, length, offset) }
}
#[cfg(ruby_3_1)]
pub fn pread(buffer: Value, io: Value, from: i64, length: usize, offset: usize) -> Value {
unsafe { io_buffer::rb_io_buffer_pread(from_offset(buffer, offset), io, length, from) }
}
#[cfg(ruby_gte_3_2)]
pub fn pread(buffer: Value, io: Value, from: i64, length: usize, offset: usize) -> Value {
unsafe { io_buffer::rb_io_buffer_pread(buffer, io, from, length, offset) }
}
#[cfg(ruby_3_1)]
pub fn write(buffer: Value, io: Value, length: usize, offset: usize) -> Value {
unsafe { io_buffer::rb_io_buffer_write(from_offset(buffer, offset), io, length) }
}
#[cfg(ruby_gte_3_2)]
pub fn write(buffer: Value, io: Value, length: usize, offset: usize) -> Value {
unsafe { io_buffer::rb_io_buffer_write(buffer, io, length, offset) }
}
#[cfg(ruby_3_1)]
pub fn pwrite(buffer: Value, io: Value, from: i64, length: usize, offset: usize) -> Value {
unsafe { io_buffer::rb_io_buffer_pwrite(from_offset(buffer, offset), io, length, from) }
}
#[cfg(ruby_gte_3_2)]
pub fn pwrite(buffer: Value, io: Value, from: i64, length: usize, offset: usize) -> Value {
unsafe { io_buffer::rb_io_buffer_pwrite(buffer, io, from, length, offset) }
}