(rust) PathBuf push() behaviour
This commit is contained in:
@@ -7,11 +7,7 @@ edition = "2021"
|
|||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
chrono = "0.4.41"
|
chrono = "0.4.41"
|
||||||
clap = { version = "4.5.0", features = ["derive"] }
|
clap = { version = "4.5.0", features = ["derive"] }
|
||||||
ctrlc = "3.4"
|
|
||||||
dirs = "5.0.1"
|
dirs = "5.0.1"
|
||||||
sqlx = { version = "0.8", features = [ "runtime-tokio", "sqlite", "chrono" ] }
|
|
||||||
thiserror = "2.0.12"
|
thiserror = "2.0.12"
|
||||||
tokio = { version = "1.42.0", features = ["full", "rt"] }
|
tokio = { version = "1.42.0", features = ["full", "rt"] }
|
||||||
prost = "0.13"
|
|
||||||
proto = { path = "proto" }
|
|
||||||
|
|
||||||
|
|||||||
+23
-181
@@ -1,198 +1,40 @@
|
|||||||
#![allow(dead_code, unused)]
|
#![allow(dead_code, unused)]
|
||||||
|
|
||||||
use chrono::{DateTime, Local};
|
use std::{
|
||||||
use prost::{DecodeError, EncodeError, Message};
|
|
||||||
use proto::protest::*;
|
|
||||||
use tokio::{
|
|
||||||
fs,
|
fs,
|
||||||
io::{AsyncReadExt, AsyncWriteExt},
|
path::PathBuf,
|
||||||
net::{TcpListener, TcpStream},
|
|
||||||
time::{sleep, Duration},
|
|
||||||
};
|
};
|
||||||
|
use dirs::config_dir;
|
||||||
|
|
||||||
const BLOCK_SIZE: usize = 1024;
|
const BLOCK_SIZE: usize = 1024;
|
||||||
const TIMEOUT_LIMIT: usize = 32;
|
const TIMEOUT_LIMIT: usize = 32;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
let listener = TcpListener::bind("127.0.0.1:9090").await?;
|
let mut path: PathBuf = match config_dir() {
|
||||||
let mut file = fs::read("../lorem.md").await?;
|
Some(value) => value,
|
||||||
println!("filesize = {}", file.len());
|
None => return Err(anyhow::Error::msg("no configuration directory for you")),
|
||||||
|
};
|
||||||
|
|
||||||
tokio::spawn(async move {
|
check_path(&path);
|
||||||
let mut connection = TcpStream::connect("127.0.0.1:9090").await.unwrap();
|
path.push("navigate");
|
||||||
let blocks = if 0 == file.len() % BLOCK_SIZE {
|
check_path(&path);
|
||||||
file.len() / BLOCK_SIZE
|
path.push("bookmarks");
|
||||||
} else {
|
check_path(&path);
|
||||||
file.len() / BLOCK_SIZE + 1
|
path.push("default.toml");
|
||||||
};
|
check_path(&path);
|
||||||
let mut index = 0;
|
|
||||||
println!("blocks = {blocks}");
|
|
||||||
loop {
|
|
||||||
let mut buffer = vec![0u8; BLOCK_SIZE + 1024];
|
|
||||||
let data: Vec<u8> = if file.len() > BLOCK_SIZE {
|
|
||||||
file.drain(0..BLOCK_SIZE).collect()
|
|
||||||
} else {
|
|
||||||
file.drain(..).collect()
|
|
||||||
};
|
|
||||||
index += 1;
|
|
||||||
if index > blocks {
|
|
||||||
panic!("something went horribly wrong, index ({index}) > blocks ({blocks}), remaining filesize = {}", file.len());
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("sending index = {}", index);
|
|
||||||
let frame = Payload {
|
|
||||||
index: index as u64,
|
|
||||||
blocks: blocks as u64,
|
|
||||||
payload: data,
|
|
||||||
};
|
|
||||||
|
|
||||||
let length = encode_with_length(&frame, &mut buffer).unwrap();
|
|
||||||
_ = connection.write_all(&buffer[0..length]).await;
|
|
||||||
|
|
||||||
if index == blocks {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sleep(Duration::from_millis(1)).await;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
match listener.accept().await {
|
|
||||||
Ok((mut stream, address)) => {
|
|
||||||
let mut output = Vec::<u8>::new();
|
|
||||||
let mut buffer = [0u8; BLOCK_SIZE + 1024];
|
|
||||||
let mut vector: Vec<u8> = Vec::new();
|
|
||||||
let mut timeout_counter: usize = 0;
|
|
||||||
|
|
||||||
'receive: loop {
|
|
||||||
loop {
|
|
||||||
let num = stream.read(&mut buffer[..]).await.unwrap();
|
|
||||||
if num != 0 {
|
|
||||||
vector.extend(buffer[0..num].iter());
|
|
||||||
if timeout_counter > 0 {
|
|
||||||
timeout_counter -= 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
timeout_counter += 1;
|
|
||||||
if timeout_counter > TIMEOUT_LIMIT {
|
|
||||||
println!("\n\n[[ TIMEOUT ]]\n\n");
|
|
||||||
break 'receive;
|
|
||||||
}
|
|
||||||
sleep(Duration::from_millis(100)).await;
|
|
||||||
}
|
|
||||||
let mut delimiter = prost::decode_length_delimiter(&vector[..]).unwrap();
|
|
||||||
delimiter += prost::length_delimiter_len(delimiter);
|
|
||||||
|
|
||||||
let payload = Payload::decode_length_delimited(&vector[0..delimiter]).unwrap();
|
|
||||||
_ = vector.drain(0..delimiter);
|
|
||||||
|
|
||||||
println!("-- receiving index = {}, delimiter = {}", payload.index, delimiter);
|
|
||||||
|
|
||||||
output.extend(payload.payload.iter());
|
|
||||||
|
|
||||||
if payload.index == payload.blocks {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sleep(Duration::from_millis(1)).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = fs::write("./lorem-copy.md", output).await?;
|
|
||||||
}
|
|
||||||
Err(error) => {
|
|
||||||
println!("this is unexpected.. {}", error.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receive_file(stream: &mut TcpStream) -> Result<Vec<u8>, anyhow::Error> {
|
fn check_path(path: &PathBuf) {
|
||||||
const BUFFER_SIZE: usize = 4096;
|
if path.is_dir() {
|
||||||
let mut buffer = [0u8; BUFFER_SIZE];
|
println!("[{:#?}] is a valid `DIRECTORY`", path);
|
||||||
let mut index_counter: usize = 0;
|
} else if path.is_file() {
|
||||||
let mut processing_buffer = Vec::<u8>::new();
|
println!("[{:#?}] is a valid `FILE`", path);
|
||||||
let mut file = Vec::<u8>::new();
|
} else if path.exists() {
|
||||||
let mut size: usize = 0;
|
println!("[{:#?}] is a valid `ENTITY`", path);
|
||||||
|
} else {
|
||||||
loop {
|
println!("[{:#?}] is `NOT` a valid path", path);
|
||||||
let num_bytes = stream.read(&mut buffer[..]).await?;
|
|
||||||
processing_buffer.extend(&buffer[0..num_bytes]);
|
|
||||||
if 0 == index_counter {
|
|
||||||
size = usize::from_be_bytes(
|
|
||||||
processing_buffer
|
|
||||||
.drain(0..8)
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.try_into()
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
_ = processing_buffer.drain(0..8);
|
|
||||||
}
|
|
||||||
let block_size = usize::from_be_bytes(
|
|
||||||
processing_buffer
|
|
||||||
.drain(0..8)
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.try_into()
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
let index = usize::from_be_bytes(
|
|
||||||
processing_buffer
|
|
||||||
.drain(0..8)
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.try_into()
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if index_counter != index {
|
|
||||||
panic!("meh, counter = {index_counter}, index = {index}");
|
|
||||||
}
|
|
||||||
|
|
||||||
file.extend(processing_buffer.drain(0..block_size));
|
|
||||||
|
|
||||||
index_counter += 1;
|
|
||||||
if block_size >= size {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
size -= block_size;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn send_file(stream: &mut TcpStream, mut file: Vec<u8>) -> Result<(), anyhow::Error> {
|
|
||||||
const BLOCK_SIZE: usize = 2048;
|
|
||||||
let size: usize = file.len();
|
|
||||||
let mut remaining = size;
|
|
||||||
let mut index: usize = 0;
|
|
||||||
|
|
||||||
while remaining > 0 {
|
|
||||||
let mut block = Vec::<u8>::new();
|
|
||||||
let len = if remaining >= BLOCK_SIZE {
|
|
||||||
BLOCK_SIZE
|
|
||||||
} else {
|
|
||||||
remaining
|
|
||||||
};
|
|
||||||
|
|
||||||
block.extend(size.to_be_bytes());
|
|
||||||
block.extend(len.to_be_bytes());
|
|
||||||
block.extend(index.to_be_bytes());
|
|
||||||
block.extend(file.drain(0..len));
|
|
||||||
|
|
||||||
stream.write(&block[..]).await?;
|
|
||||||
|
|
||||||
remaining -= len;
|
|
||||||
index += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn encode_with_length(message: &impl Message, buffer: &mut Vec<u8>) -> Result<usize, EncodeError> {
|
|
||||||
let mut length = message.encoded_len();
|
|
||||||
length += prost::length_delimiter_len(length);
|
|
||||||
message.encode_length_delimited(&mut &mut buffer[0..length])?;
|
|
||||||
|
|
||||||
Ok(length)
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user