use crate::{pg_sys, PgBox};
#[inline(always)]
pub unsafe fn set_varsize_4b(ptr: *mut pg_sys::varlena, len: i32) {
(*ptr.cast::<pg_sys::varattrib_4b>()).va_4byte.as_mut().va_header = (len as u32) << 2;
}
#[inline(always)]
pub unsafe fn set_varsize(ptr: *mut pg_sys::varlena, len: i32) {
set_varsize_4b(ptr, len)
}
#[inline(always)]
pub unsafe fn set_varsize_1b(ptr: *mut pg_sys::varlena, len: i32) {
(*ptr.cast::<pg_sys::varattrib_1b>()).va_header = ((len as u8) << 1) | 0x01
}
#[inline(always)]
pub unsafe fn set_varsize_short(ptr: *mut pg_sys::varlena, len: i32) {
set_varsize_1b(ptr, len)
}
#[inline]
pub unsafe fn varsize_external(ptr: *const pg_sys::varlena) -> usize {
pg_sys::VARHDRSZ_EXTERNAL() + vartag_size(vartag_external(ptr) as pg_sys::vartag_external)
}
#[inline]
pub unsafe fn vartag_external(ptr: *const pg_sys::varlena) -> u8 {
vartag_1b_e(ptr)
}
#[inline]
pub unsafe fn vartag_is_expanded(tag: pg_sys::vartag_external) -> bool {
(tag & !1) == pg_sys::vartag_external_VARTAG_EXPANDED_RO
}
#[inline]
pub unsafe fn vartag_size(tag: pg_sys::vartag_external) -> usize {
if tag == pg_sys::vartag_external_VARTAG_INDIRECT {
std::mem::size_of::<pg_sys::varatt_indirect>()
} else if vartag_is_expanded(tag) {
std::mem::size_of::<pg_sys::varatt_expanded>()
} else if tag == pg_sys::vartag_external_VARTAG_ONDISK {
std::mem::size_of::<pg_sys::varatt_external>()
} else {
panic!("unrecognized TOAST vartag")
}
}
#[allow(clippy::cast_ptr_alignment)]
#[inline]
pub unsafe fn varsize_4b(ptr: *const pg_sys::varlena) -> usize {
let va4b = ptr as *const pg_sys::varattrib_4b__bindgen_ty_1; (((*va4b).va_header >> 2) & 0x3FFF_FFFF) as usize
}
#[inline]
pub unsafe fn varsize_1b(ptr: *const pg_sys::varlena) -> usize {
let va1b = ptr as *const pg_sys::varattrib_1b;
(((*va1b).va_header >> 1) & 0x7F) as usize
}
#[inline]
pub unsafe fn vartag_1b_e(ptr: *const pg_sys::varlena) -> u8 {
let va1be = ptr as *const pg_sys::varattrib_1b_e;
(*va1be).va_tag
}
#[inline]
pub unsafe fn varsize(ptr: *const pg_sys::varlena) -> usize {
varsize_4b(ptr)
}
#[inline]
pub unsafe fn varatt_is_4b(ptr: *const pg_sys::varlena) -> bool {
let va1b = ptr as *const pg_sys::varattrib_1b;
(*va1b).va_header & 0x01 == 0x00
}
#[allow(clippy::verbose_bit_mask)]
#[inline]
pub unsafe fn varatt_is_4b_u(ptr: *const pg_sys::varlena) -> bool {
let va1b = ptr as *const pg_sys::varattrib_1b;
(*va1b).va_header & 0x03 == 0x00
}
#[inline]
pub unsafe fn varatt_is_b8_c(ptr: *const pg_sys::varlena) -> bool {
let va1b = ptr as *const pg_sys::varattrib_1b;
(*va1b).va_header & 0x03 == 0x02
}
#[inline]
pub unsafe fn varatt_is_1b(ptr: *const pg_sys::varlena) -> bool {
let va1b = ptr as *const pg_sys::varattrib_1b;
(*va1b).va_header & 0x01 == 0x01
}
#[inline]
pub unsafe fn varatt_is_1b_e(ptr: *const pg_sys::varlena) -> bool {
let va1b = ptr as *const pg_sys::varattrib_1b;
(*va1b).va_header == 0x01
}
#[inline]
pub unsafe fn varatt_not_pad_byte(ptr: *const pg_sys::varlena) -> bool {
!ptr.is_null()
}
#[inline]
pub unsafe fn varsize_any(ptr: *const pg_sys::varlena) -> usize {
if varatt_is_1b_e(ptr) {
varsize_external(ptr)
} else if varatt_is_1b(ptr) {
varsize_1b(ptr)
} else {
varsize_4b(ptr)
}
}
#[inline]
pub unsafe fn varsize_any_exhdr(ptr: *const pg_sys::varlena) -> usize {
if varatt_is_1b_e(ptr) {
varsize_external(ptr) - pg_sys::VARHDRSZ_EXTERNAL()
} else if varatt_is_1b(ptr) {
varsize_1b(ptr) - pg_sys::VARHDRSZ_SHORT()
} else {
varsize_4b(ptr) - pg_sys::VARHDRSZ
}
}
#[inline]
pub unsafe fn vardata_1b(ptr: *const pg_sys::varlena) -> *const std::os::raw::c_char {
let va1b = ptr as *const pg_sys::varattrib_1b;
(*va1b).va_data.as_slice(varsize_1b(ptr as *const pg_sys::varlena) as usize).as_ptr()
as *const std::os::raw::c_char
}
#[allow(clippy::cast_ptr_alignment)]
#[inline]
pub unsafe fn vardata_4b(ptr: *const pg_sys::varlena) -> *const std::os::raw::c_char {
let va1b = ptr as *const pg_sys::varattrib_4b__bindgen_ty_1; (*va1b).va_data.as_slice(varsize_1b(ptr as *const pg_sys::varlena) as usize).as_ptr()
as *const std::os::raw::c_char
}
#[allow(clippy::cast_ptr_alignment)]
#[inline]
pub unsafe fn vardata_4b_c(ptr: *const pg_sys::varlena) -> *const std::os::raw::c_char {
let va1b = ptr as *const pg_sys::varattrib_4b__bindgen_ty_2; (*va1b).va_data.as_slice(varsize_1b(ptr as *const pg_sys::varlena) as usize).as_ptr()
as *const std::os::raw::c_char
}
#[allow(clippy::cast_ptr_alignment)]
#[inline]
pub unsafe fn vardata_1b_e(ptr: *const pg_sys::varlena) -> *const std::os::raw::c_char {
let va1b = ptr as *const pg_sys::varattrib_1b_e;
(*va1b).va_data.as_slice(varsize_1b(ptr as *const pg_sys::varlena) as usize).as_ptr()
as *const std::os::raw::c_char
}
#[inline]
pub unsafe fn vardata_any(ptr: *const pg_sys::varlena) -> *const std::os::raw::c_char {
if varatt_is_1b(ptr) {
vardata_1b(ptr)
} else {
vardata_4b(ptr)
}
}
#[inline]
pub unsafe fn varlena_size(t: *const pg_sys::varlena) -> usize {
std::mem::size_of_val(&(*t).vl_len_) + varsize_any_exhdr(t)
}
#[inline]
pub unsafe fn text_to_rust_str_unchecked<'a>(varlena: *const pg_sys::varlena) -> &'a str {
let len = varsize_any_exhdr(varlena);
let data = vardata_any(varlena);
std::str::from_utf8_unchecked(std::slice::from_raw_parts(data as *mut u8, len))
}
#[inline]
pub unsafe fn varlena_to_byte_slice<'a>(varlena: *const pg_sys::varlena) -> &'a [u8] {
let len = varsize_any_exhdr(varlena);
let data = vardata_any(varlena);
std::slice::from_raw_parts(data as *const u8, len)
}
#[inline]
pub fn rust_str_to_text_p(s: &str) -> PgBox<pg_sys::varlena> {
let bytea = rust_byte_slice_to_bytea(s.as_bytes());
unsafe { PgBox::from_pg(bytea.as_ptr() as *mut pg_sys::varlena) }
}
#[inline]
pub fn rust_byte_slice_to_bytea(slice: &[u8]) -> PgBox<pg_sys::bytea> {
unsafe {
PgBox::from_pg(pg_sys::cstring_to_text_with_len(
slice.as_ptr() as *const std::os::raw::c_char,
slice.len() as i32,
))
}
}