(rust) PathBuf push() behaviour
This commit is contained in:
@@ -7,11 +7,7 @@ edition = "2021"
|
||||
anyhow = "1.0"
|
||||
chrono = "0.4.41"
|
||||
clap = { version = "4.5.0", features = ["derive"] }
|
||||
ctrlc = "3.4"
|
||||
dirs = "5.0.1"
|
||||
sqlx = { version = "0.8", features = [ "runtime-tokio", "sqlite", "chrono" ] }
|
||||
thiserror = "2.0.12"
|
||||
tokio = { version = "1.42.0", features = ["full", "rt"] }
|
||||
prost = "0.13"
|
||||
proto = { path = "proto" }
|
||||
|
||||
|
||||
+21
-179
@@ -1,198 +1,40 @@
|
||||
#![allow(dead_code, unused)]
|
||||
|
||||
use chrono::{DateTime, Local};
|
||||
use prost::{DecodeError, EncodeError, Message};
|
||||
use proto::protest::*;
|
||||
use tokio::{
|
||||
use std::{
|
||||
fs,
|
||||
io::{AsyncReadExt, AsyncWriteExt},
|
||||
net::{TcpListener, TcpStream},
|
||||
time::{sleep, Duration},
|
||||
path::PathBuf,
|
||||
};
|
||||
use dirs::config_dir;
|
||||
|
||||
const BLOCK_SIZE: usize = 1024;
|
||||
const TIMEOUT_LIMIT: usize = 32;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let listener = TcpListener::bind("127.0.0.1:9090").await?;
|
||||
let mut file = fs::read("../lorem.md").await?;
|
||||
println!("filesize = {}", file.len());
|
||||
|
||||
tokio::spawn(async move {
|
||||
let mut connection = TcpStream::connect("127.0.0.1:9090").await.unwrap();
|
||||
let blocks = if 0 == file.len() % BLOCK_SIZE {
|
||||
file.len() / BLOCK_SIZE
|
||||
} else {
|
||||
file.len() / BLOCK_SIZE + 1
|
||||
};
|
||||
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 mut path: PathBuf = match config_dir() {
|
||||
Some(value) => value,
|
||||
None => return Err(anyhow::Error::msg("no configuration directory for you")),
|
||||
};
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
check_path(&path);
|
||||
path.push("navigate");
|
||||
check_path(&path);
|
||||
path.push("bookmarks");
|
||||
check_path(&path);
|
||||
path.push("default.toml");
|
||||
check_path(&path);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn receive_file(stream: &mut TcpStream) -> Result<Vec<u8>, anyhow::Error> {
|
||||
const BUFFER_SIZE: usize = 4096;
|
||||
let mut buffer = [0u8; BUFFER_SIZE];
|
||||
let mut index_counter: usize = 0;
|
||||
let mut processing_buffer = Vec::<u8>::new();
|
||||
let mut file = Vec::<u8>::new();
|
||||
let mut size: usize = 0;
|
||||
|
||||
loop {
|
||||
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(),
|
||||
);
|
||||
fn check_path(path: &PathBuf) {
|
||||
if path.is_dir() {
|
||||
println!("[{:#?}] is a valid `DIRECTORY`", path);
|
||||
} else if path.is_file() {
|
||||
println!("[{:#?}] is a valid `FILE`", path);
|
||||
} else if path.exists() {
|
||||
println!("[{:#?}] is a valid `ENTITY`", path);
|
||||
} else {
|
||||
_ = processing_buffer.drain(0..8);
|
||||
println!("[{:#?}] is `NOT` a valid path", path);
|
||||
}
|
||||
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