use std::{
io::{Read, Write},
net::TcpStream,
};
use super::common::TransportLayer;
use crate::{
constants::MAX_RESPONSE_SIZE,
error::{EtpError, EtpResult},
};
pub type IpAddress = String;
pub type IpPort = u32;
pub struct TcpIpTransport {
pub ip_address: IpAddress,
pub port: IpPort,
stream: TcpStream,
}
impl TcpIpTransport {
pub fn new(ip_address: IpAddress, port: IpPort) -> EtpResult<TcpIpTransport> {
let stream = TcpStream::connect(format!("{}:{}", ip_address, port))
.map_err(|e| EtpError::TcpIp(format!("{:?}", e)))?;
Ok(TcpIpTransport {
ip_address,
port,
stream,
})
}
}
impl TransportLayer for TcpIpTransport {
fn send(&mut self, command: Vec<u8>) -> EtpResult<()> {
self.stream
.write_all(&command)
.map_err(|e| EtpError::TcpIp(format!("{:?}", e)))?;
Ok(())
}
fn receive(&mut self, expected_number_of_bytes: usize) -> EtpResult<Vec<u8>> {
let mut buffer: Vec<u8> = Vec::new();
while buffer.len() < expected_number_of_bytes as usize {
let mut temp_buffer = vec![0; MAX_RESPONSE_SIZE];
let bytes_read = self
.stream
.read(&mut temp_buffer)
.map_err(|e| EtpError::TcpIp(format!("{:?}", e)))?;
if bytes_read == 0 {
break;
}
buffer.extend_from_slice(&temp_buffer[..bytes_read]);
}
Ok(buffer)
}
}