use std::fs::File;
use std::io::{BufReader, BufWriter, Read, Write};
use std::net::TcpStream;
use std::path::Path;
use crate::bytes::Bytes;
use crate::error::{Error, ErrorKind};
use crate::packet::{Packet, PacketKind};
pub fn send_content(stream: &mut TcpStream, content: Bytes) -> Result<(), Error> {
let content_split = Packet::split_to_max_packet_size(content);
for packet_content in content_split.into_iter() {
let packet = Packet::new(PacketKind::Content, packet_content)?;
packet.send(stream)?;
}
Ok(())
}
pub fn receive_content(stream: &mut TcpStream) -> Result<(Bytes, Packet), Error> {
let mut content = Bytes::empty();
loop {
let mut packet = Packet::receive(stream)?;
match packet.kind() {
PacketKind::Empty => {
return Err(Error::new(
ErrorKind::InvalidPacketKind,
Some("Expected content packet, got empty.".to_string()),
));
}
PacketKind::MetaData | PacketKind::MetaDataEnd => {
return Err(Error::new(
ErrorKind::InvalidPacketKind,
Some("Expected content packet, got metadata.".to_string()),
));
}
PacketKind::Content => {
content.append(packet.content_mut());
}
PacketKind::End => {
let end_data = packet;
return Ok((content, end_data));
}
PacketKind::Unit => {
return Err(Error::new(
ErrorKind::InvalidPacketKind,
Some("Expected content packet, got unit.".to_string()),
));
}
PacketKind::Unknown => return Err(Error::new(ErrorKind::UnknownPacketKind, None)),
}
}
}
pub fn send_file(stream: &mut TcpStream, path: &Path) -> Result<(), Error> {
let file = match File::open(path) {
Ok(file) => file,
Err(e) => {
return Err(Error::new(
ErrorKind::OpeningFileFailed,
Some(format!("{}", e)),
))
}
};
let n_of_content_packets = Packet::number_of_packets(file.metadata().unwrap().len() as usize);
let mut reader = BufReader::new(file);
for part in 1..=n_of_content_packets {
let mut buff: Vec<u8>;
if part == n_of_content_packets {
buff = Vec::new();
if let Err(e) = reader.read_to_end(&mut buff) {
return Err(Error::new(
ErrorKind::ReadingFromFileFailed,
Some(format!(
"Failed to read last content packet from file.\n({})",
e
)),
));
}
} else {
buff = vec![0_u8; Packet::max_content_size() as usize];
if let Err(e) = reader.read_exact(&mut buff) {
return Err(Error::new(
ErrorKind::ReadingFromFileFailed,
Some(format!("Failed to read content packet from file.\n({})", e)),
));
}
}
let packet = Packet::new(PacketKind::Content, buff.into())?;
packet.send(stream)?;
}
Ok(())
}
pub fn receive_file(
stream: &mut TcpStream,
location: &Path,
file_name: String,
) -> Result<(usize, Packet), Error> {
let mut path = location.to_path_buf();
path.push(&file_name);
let file = match File::create(path) {
Ok(file) => file,
Err(e) => {
return Err(Error::new(
ErrorKind::CreatingFileFailed,
Some(format!("Could not create a file: {}.\n({})", file_name, e)),
));
}
};
let mut writer = BufWriter::new(file);
let mut number_of_packets = 0;
loop {
let packet = Packet::receive(stream)?;
match packet.kind() {
PacketKind::Empty => {
return Err(Error::new(
ErrorKind::InvalidPacketKind,
Some("Expected content packet, got empty.".to_string()),
));
}
PacketKind::MetaData | PacketKind::MetaDataEnd => {
return Err(Error::new(
ErrorKind::InvalidPacketKind,
Some("Expected content packet, got metadata.".to_string()),
));
}
PacketKind::Content => {
if let Err(e) = writer.write(&packet.content_move().into_vec()) {
return Err(Error::new(
ErrorKind::WritingToFileFailed,
Some(format!("Could not write to file. ({})", e)),
));
}
}
PacketKind::End => {
writer.flush().unwrap();
let end_data = packet;
return Ok((number_of_packets, end_data));
}
PacketKind::Unit => {
return Err(Error::new(
ErrorKind::InvalidPacketKind,
Some("Expected content packet, got unit.".to_string()),
));
}
PacketKind::Unknown => return Err(Error::new(ErrorKind::UnknownPacketKind, None)),
}
number_of_packets += 1;
}
}