const DATA_LEN_POS: u16 = 0;
const VERSION_POS: u16 = 4;
const API_ID_POS: u16 = VERSION_POS + 2;
const REQ_ID_POS: u16 = API_ID_POS + 2; const CHANNEL_ID_POS: u16 = REQ_ID_POS + 8; const FIX_LEN_POS: u16 = CHANNEL_ID_POS + 8;
pub mod xport {
pub const SEND_MESSAGE_API_ID: u16 = 1001;
pub const GET_ALL_CONN_ID_API_ID: u16 = 1002;
pub const GET_CHANNEL_ID_BY_CONN_API_ID: u16 = 1003;
pub const GEN_ID: u16 = 1004;
pub const RESP_MESSAGE_API_ID: u16 = 1005;
pub const GET_CONFIG_API_ID: u16 = 1006;
pub const NOTICE_READY_API_ID: u16 = 1007;
pub const NOTICE_FINIALIZE_API_ID: u16 = 1008;
}
pub mod log {
pub const OUTPUT_API_ID: u16 = 5001;
}
pub struct ProtocolIPCReader<'a> {
msg_buffer: &'a [u8],
}
impl<'a> ProtocolIPCReader<'a> {
pub fn new(msg_buffer: &'a [u8]) -> ProtocolIPCReader<'a> {
ProtocolIPCReader { msg_buffer }
}
pub fn api_id(&self) -> u16 {
unsafe {
let ptr = self.msg_buffer.as_ptr().offset(API_ID_POS as isize);
let bytes = *(ptr as *const [u8; 2]);
u16::from_le_bytes(bytes)
}
}
pub fn request_id(&self) -> i64 {
unsafe {
let ptr = self.msg_buffer.as_ptr().offset(REQ_ID_POS as isize);
let bytes = *(ptr as *const [u8; 8]);
i64::from_le_bytes(bytes)
}
}
pub fn channel_id(&self) -> i64 {
unsafe {
let ptr = self.msg_buffer.as_ptr().offset(CHANNEL_ID_POS as isize);
let bytes = *(ptr as *const [u8; 8]);
i64::from_le_bytes(bytes)
}
}
pub fn version(&self) -> u16 {
unsafe {
let ptr = self.msg_buffer.as_ptr().offset(VERSION_POS as isize);
let bytes = *(ptr as *const [u8; 2]);
u16::from_le_bytes(bytes)
}
}
pub fn msg_size(&self) -> u32 {
self.msg_buffer.len() as u32
}
pub fn msg_body(&self) -> &[u8] {
&self.msg_buffer[FIX_LEN_POS as usize..]
}
}
pub struct ProtocolIPCWriter {
pub msg_buffer: Vec<u8>,
pub msg_body_size: u32,
}
impl ProtocolIPCWriter {
pub fn new(msg_size: u32, api_id: u16, request_id: i64) -> ProtocolIPCWriter {
let msg_len = (FIX_LEN_POS as u32 + msg_size) as usize;
let mut msg_buffer: Vec<u8> = Vec::with_capacity(msg_len);
unsafe {
msg_buffer.set_len(msg_len);
}
let mut writer = ProtocolIPCWriter {
msg_buffer,
msg_body_size: msg_size,
};
writer.write_api_id(api_id);
writer.write_request_id(request_id);
writer.write_version();
writer.write_data_len(msg_len as u32);
writer
}
pub fn write_api_id(&mut self, api_id: u16) {
unsafe {
let bytes = api_id.to_le_bytes();
let ptr = self.msg_buffer.as_mut_ptr().offset(API_ID_POS as isize);
std::ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, 2);
}
}
pub fn write_request_id(&mut self, request_id: i64) {
unsafe {
let bytes = request_id.to_le_bytes();
let ptr = self.msg_buffer.as_mut_ptr().offset(REQ_ID_POS as isize);
std::ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, 8);
}
}
pub fn write_channel_id(&mut self, channel_id: i64) {
unsafe {
let bytes = channel_id.to_le_bytes();
let ptr = self.msg_buffer.as_mut_ptr().offset(CHANNEL_ID_POS as isize);
std::ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, 8);
}
}
pub fn msg_body_buffer(&mut self) -> &mut [u8] {
let msg_body_pos = self.msg_buffer.len() - self.msg_body_size as usize;
&mut self.msg_buffer[msg_body_pos as usize..]
}
fn write_version(&mut self) {
unsafe {
let bytes = (1 as u16).to_le_bytes();
let ptr = self.msg_buffer.as_mut_ptr().offset(VERSION_POS as isize);
std::ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, 2);
}
}
pub fn write_msg_body(&mut self, message: &Vec<u8>) {
unsafe {
let msg_body_pos = self.msg_buffer.len() - self.msg_body_size as usize;
println!(
"msg_body_pos = {} FIX_LEN_POS = {}",
msg_body_pos, FIX_LEN_POS
);
let dst_ptr = self.msg_buffer.as_mut_ptr().offset(msg_body_pos as isize);
std::ptr::copy_nonoverlapping(message.as_ptr(), dst_ptr, message.len());
}
}
pub fn write_u8_msg_body(&mut self, message: &[u8]) {
unsafe {
let msg_body_pos = self.msg_buffer.len() - self.msg_body_size as usize;
let dst_ptr = self.msg_buffer.as_mut_ptr().offset(msg_body_pos as isize);
std::ptr::copy_nonoverlapping(message.as_ptr(), dst_ptr, message.len());
}
}
fn write_data_len(&mut self, data_len: u32) {
unsafe {
let bytes = data_len.to_le_bytes();
let ptr = self.msg_buffer.as_mut_ptr().offset(DATA_LEN_POS as isize);
std::ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, 4);
}
}
}