mod tosql;
use crate::{ Result, oci::{self, *} };
use super::Ctx;
pub(crate) fn new(size: u32, env: &OCIEnv, err: &OCIError) -> Result<Ptr<OCIRaw>> {
let mut bin = Ptr::<OCIRaw>::null();
oci::raw_resize(env, err, size, bin.as_mut_ptr())?;
Ok( bin )
}
pub(crate) fn free(raw: &mut Ptr<OCIRaw>, env: &OCIEnv, err: &OCIError) {
unsafe {
OCIRawResize(env, err, 0, raw.as_mut_ptr());
}
}
pub(crate) fn as_ptr(raw: &OCIRaw, env: &OCIEnv) -> *const u8 {
unsafe {
OCIRawPtr(env, raw)
}
}
pub(crate) fn len(raw: &OCIRaw, env: &OCIEnv) -> usize {
unsafe {
OCIRawSize(env, raw) as usize
}
}
pub struct Raw<'a> {
raw: Ptr<OCIRaw>,
ctx: &'a dyn Ctx,
}
impl Drop for Raw<'_> {
fn drop(&mut self) {
free(&mut self.raw, self.ctx.as_ref(), self.ctx.as_ref());
}
}
impl<'a> Raw<'a> {
pub fn from_bytes(data: &[u8], ctx: &'a dyn Ctx) -> Result<Self> {
let mut raw = Ptr::<OCIRaw>::null();
oci::raw_assign_bytes(ctx.as_ref(), ctx.as_ref(), data.as_ptr(), data.len() as u32, raw.as_mut_ptr())?;
Ok( Self { raw, ctx } )
}
pub fn from_raw(other: &Raw<'a>) -> Result<Self> {
let mut raw = Ptr::<OCIRaw>::null();
oci::raw_assign_raw(other.ctx.as_ref(), other.ctx.as_ref(), &other.raw, raw.as_mut_ptr())?;
Ok( Self { raw, ..*other } )
}
pub fn with_capacity(size: usize, ctx: &'a dyn Ctx) -> Result<Self> {
let raw = new(size as u32, ctx.as_ref(), ctx.as_ref())?;
Ok( Self { raw, ctx } )
}
pub fn capacity(&self) -> Result<usize> {
let mut size = 0u32;
oci::raw_alloc_size(self.ctx.as_ref(), self.ctx.as_ref(), self.raw.get(), &mut size)?;
Ok( size as usize )
}
pub fn resize(&mut self, new_size: usize) -> Result<()> {
oci::raw_resize(self.ctx.as_ref(), self.ctx.as_ref(), new_size as u32, self.raw.as_mut_ptr())
}
pub fn len(&self) -> usize {
len(&self.raw, self.ctx.as_ref())
}
pub fn set(&mut self, data: &[u8]) -> Result<()> {
oci::raw_assign_bytes(self.ctx.as_ref(), self.ctx.as_ref(), data.as_ptr(), data.len() as u32, self.raw.as_mut_ptr())
}
pub fn as_bytes(&self) -> &[u8] {
let ptr = as_ptr(&self.raw, self.ctx.as_ref());
let len = len(&self.raw, self.ctx.as_ref());
unsafe {
std::slice::from_raw_parts(ptr, len)
}
}
}
impl std::fmt::Debug for Raw<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
const MAX_LEN : usize = 50;
let data = self.as_bytes();
if data.len() > MAX_LEN {
f.write_fmt(format_args!("RAW {:?}...", &data[..MAX_LEN]))
} else {
f.write_fmt(format_args!("RAW {:?}", data))
}
}
}