use fern_proxy_interfaces::SQLMessage;
pub mod backend;
pub mod frontend;
pub trait PostgresMessage: SQLMessage + std::fmt::Debug {}
pub(crate) mod constants {
pub const BYTES_MESSAGE_ID: usize = 1;
pub const BYTES_MESSAGE_SIZE: usize = 4;
pub const BYTES_MESSAGE_HEADER: usize = BYTES_MESSAGE_ID + BYTES_MESSAGE_SIZE;
}
pub(crate) mod utils {
use bytes::{Buf, BufMut, Bytes, BytesMut};
use std::io;
pub(crate) fn get_bytes(
buf: &mut BytesMut,
length_bytes: usize,
error_msg: &str,
) -> io::Result<Bytes> {
if buf.remaining() < length_bytes {
let err = io::Error::new(
io::ErrorKind::UnexpectedEof,
"malformed packet - invalid data size",
);
log::error!("{}", err);
return Err(err);
}
let data_length = buf.get_u32();
log::trace!("bytes data length header: {}", data_length);
let data = if data_length == u32::MAX {
Bytes::new()
} else {
if buf.remaining() < data_length as usize {
log::error!("{}", error_msg);
return Err(io::Error::new(io::ErrorKind::UnexpectedEof, error_msg));
}
buf.copy_to_bytes(data_length as usize)
};
Ok(data)
}
pub(crate) fn put_bytes(data: &Bytes, buf: &mut BytesMut) {
buf.put_u32(data.len() as u32);
buf.put((*data).clone());
}
pub(crate) fn get_cstr(buf: &mut BytesMut) -> io::Result<Bytes> {
let nullchar_offset = buf[..].iter().position(|x| *x == b'\0');
match nullchar_offset {
None => {
let err = io::Error::new(
io::ErrorKind::InvalidData,
"malformed packet - cstr without null char terminator",
);
log::error!("{}", err);
Err(err)
}
Some(offset) => {
let str_bytes = buf.copy_to_bytes(offset);
buf.advance(1); Ok(str_bytes)
}
}
}
pub(crate) fn put_cstr(string: &Bytes, buf: &mut BytesMut) {
buf.put((*string).clone());
buf.put_u8(b'\0');
}
pub(crate) fn get_u32(buf: &mut BytesMut, error_msg: &str) -> io::Result<u32> {
if buf.remaining() < 4 {
log::error!("{}", error_msg);
return Err(io::Error::new(io::ErrorKind::InvalidData, error_msg));
}
let value = buf.get_u32();
Ok(value)
}
pub(crate) fn get_i32(buf: &mut BytesMut, error_msg: &str) -> io::Result<i32> {
if buf.remaining() < 4 {
log::error!("{}", error_msg);
return Err(io::Error::new(io::ErrorKind::InvalidData, error_msg));
}
let value = buf.get_i32();
Ok(value)
}
pub(crate) fn get_u16(buf: &mut BytesMut, error_msg: &str) -> io::Result<u16> {
if buf.remaining() < 2 {
log::error!("{}", error_msg);
return Err(io::Error::new(io::ErrorKind::UnexpectedEof, error_msg));
}
let value = buf.get_u16();
Ok(value)
}
pub(crate) fn get_i16(buf: &mut BytesMut, error_msg: &str) -> io::Result<i16> {
if buf.remaining() < 2 {
log::error!("{}", error_msg);
return Err(io::Error::new(io::ErrorKind::UnexpectedEof, error_msg));
}
let value = buf.get_i16();
Ok(value)
}
pub(crate) fn get_u8(buf: &mut BytesMut, error_msg: &str) -> io::Result<u8> {
if buf.remaining() < 1 {
log::error!("{}", error_msg);
return Err(io::Error::new(io::ErrorKind::UnexpectedEof, error_msg));
}
let value = buf.get_u8();
Ok(value)
}
}