#![allow(dead_code)]
use crate::pg_sys::{self, TYPALIGN_CHAR, TYPALIGN_DOUBLE, TYPALIGN_INT, TYPALIGN_SHORT};
use core::mem;
#[derive(Clone, Copy, Debug)]
pub(crate) struct Layout {
pub align: Align, pub size: Size, pub pass: PassBy, }
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum PassBy {
Ref,
Value,
}
impl Layout {
pub(crate) fn lookup_oid(oid: pg_sys::Oid) -> Layout {
let (mut typalign, mut typlen, mut passbyval) = Default::default();
unsafe { pg_sys::get_typlenbyvalalign(oid, &mut typlen, &mut passbyval, &mut typalign) };
Layout {
align: Align::try_from(typalign).unwrap(),
size: Size::try_from(typlen).unwrap(),
pass: if passbyval { PassBy::Value } else { PassBy::Ref },
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub(crate) enum Align {
Byte,
Short,
Int,
Double,
}
impl TryFrom<libc::c_char> for Align {
type Error = ();
fn try_from(cchar: libc::c_char) -> Result<Align, ()> {
match cchar as u8 {
TYPALIGN_CHAR => Ok(Align::Byte),
TYPALIGN_SHORT => Ok(Align::Short),
TYPALIGN_INT => Ok(Align::Int),
TYPALIGN_DOUBLE => Ok(Align::Double),
_ => Err(()),
}
}
}
impl Align {
pub(crate) fn as_usize(self) -> usize {
match self {
Align::Byte => mem::align_of::<libc::c_char>(),
Align::Short => mem::align_of::<libc::c_short>(),
Align::Int => mem::align_of::<libc::c_int>(),
Align::Double => mem::align_of::<libc::c_double>(),
}
}
pub(crate) fn as_typalign(self) -> libc::c_char {
(match self {
Align::Byte => TYPALIGN_CHAR,
Align::Short => TYPALIGN_SHORT,
Align::Int => TYPALIGN_INT,
Align::Double => TYPALIGN_DOUBLE,
}) as _
}
#[inline]
pub(crate) fn pad(self, size: usize) -> usize {
let align = self.as_usize();
(size + (align - 1)) & !(align - 1)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub(crate) enum Size {
CStr,
Varlena,
Fixed(u16),
}
impl TryFrom<i16> for Size {
type Error = ();
fn try_from(int2: i16) -> Result<Size, ()> {
match int2 {
-2 => Ok(Size::CStr),
-1 => Ok(Size::Varlena),
v @ 0.. => Ok(Size::Fixed(v as u16)),
_ => Err(()),
}
}
}
impl Size {
pub(crate) fn as_typlen(&self) -> i16 {
match self {
Self::CStr => -2,
Self::Varlena => -1,
Self::Fixed(v) => *v as _,
}
}
}