use std::fmt;
use crate::constants;
use crate::error::Error;
use crate::response::Response;
#[derive(Clone, Debug)]
pub struct Rowid {
rba: u32,
partition_id: u16,
block_num: u32,
slot_num: u16,
}
impl Rowid {
pub fn new() -> Rowid {
Rowid {
rba: 0,
partition_id: 0,
block_num: 0,
slot_num: 0,
}
}
pub(crate) fn deserialize(resp: &mut Response) -> Result<Rowid, Error> {
let rba = resp.read_ub4()?;
let partition_id = resp.read_ub2()?;
resp.advance(1)?;
let block_num = resp.read_ub4()?;
let slot_num = resp.read_ub2()?;
Ok(Rowid {
rba,
partition_id,
block_num,
slot_num,
})
}
}
impl fmt::Display for Rowid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut output = [0u8; constants::ORA_TYPE_SIZE_ROWID];
convert_base64(&mut output[0..6], self.rba.try_into().unwrap());
convert_base64(&mut output[6..9], self.partition_id.into());
convert_base64(&mut output[9..15], self.block_num.try_into().unwrap());
convert_base64(&mut output[15..18], self.slot_num.into());
f.write_str(std::str::from_utf8(&output).unwrap())
}
}
const BASE64_CHARS: &[u8] =
b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
fn convert_base64(output: &mut [u8], value: usize) {
let mut value = value;
for i in (0..output.len()).rev() {
let char_index: usize = value & 0x3f_usize;
output[i] = BASE64_CHARS[char_index];
value >>= 6;
}
}