use crate::client::Client;
use crate::constants;
use crate::error::Error;
use crate::messages::Message;
use crate::response::Response;
use crate::write_buffer::WriteBuffer;
pub struct ProtocolMessage {
charset_id: u16,
ncharset_id: u16,
server_compile_caps: Vec<u8>,
server_runtime_caps: Vec<u8>,
}
impl ProtocolMessage {
pub fn new() -> ProtocolMessage {
ProtocolMessage {
charset_id: 0,
ncharset_id: 0,
server_compile_caps: Vec::<u8>::new(),
server_runtime_caps: Vec::<u8>::new(),
}
}
fn skip_array(&mut self, resp: &mut Response) -> Result<(), Error> {
loop {
let byte = resp.read_u8()?;
if byte == 0 {
break;
}
}
Ok(())
}
}
impl Message for ProtocolMessage {
fn deserialize_ttc_message(
&mut self,
_client: &Client,
resp: &mut Response,
message_type: u8,
) -> Result<(), Error> {
if message_type != constants::TTC_MSG_TYPE_PROTOCOL {
return Err(Error::unknown_ttc_message_type(message_type));
}
self.skip_array(resp)?; self.skip_array(resp)?; self.charset_id = resp.read_u16le()?;
resp.advance(1)?; let num_elem = resp.read_u16le()?;
if num_elem > 0 {
let graph_len: usize = (num_elem * 5).into();
resp.advance(graph_len)?; }
let fdo_len = resp.read_u16be()? as usize;
resp.advance(5)?; let offset1 = resp.read_u8()? as usize;
let offset2 = resp.read_u8()? as usize;
resp.advance(offset1 + offset2)?;
self.ncharset_id = resp.read_u16be()?;
resp.advance(fdo_len - offset1 - offset2 - 9)?;
self.server_compile_caps = resp.read_bytes_with_length()?.into();
self.server_runtime_caps = resp.read_bytes_with_length()?.into();
Ok(())
}
fn is_final_ttc_message_type(
&self,
_client: &Client,
_message_type: u8,
) -> bool {
true
}
fn post_deserialize(
&mut self,
client: &mut Client,
_resp: &mut Response,
) -> Result<(), Error> {
client.set_charset_ids(self.charset_id, self.ncharset_id);
if !self.server_compile_caps.is_empty() {
client.adjust_for_server_compile_caps(&self.server_compile_caps);
}
if !self.server_runtime_caps.is_empty() {
client.adjust_for_server_runtime_caps(&self.server_runtime_caps);
}
Ok(())
}
fn serialize(&self, _client: &Client, buf: &mut WriteBuffer) {
buf.write_u8(constants::TTC_MSG_TYPE_PROTOCOL);
buf.write_u8(6); buf.write_u8(0); buf.write_str(constants::DRIVER_NAME);
buf.write_u8(0); }
}