reorg cuttle lib, add filename to txconfig

This commit is contained in:
Joe Ardent 2023-08-19 11:16:01 -07:00
parent 7c06c663d5
commit 0086fb1774
3 changed files with 51 additions and 44 deletions

View file

@ -3,6 +3,8 @@ use std::{
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use rand::seq::SliceRandom;
use raptorq::{Encoder, ObjectTransmissionInformation};
use rkyv::{Archive, Deserialize, Serialize}; use rkyv::{Archive, Deserialize, Serialize};
#[cfg(feature = "desktop")] #[cfg(feature = "desktop")]
@ -11,10 +13,11 @@ mod desktop;
mod qr_utils; mod qr_utils;
#[cfg(feature = "desktop")] #[cfg(feature = "desktop")]
pub use qr_utils::{get_content, mk_qr_bytes, stream_bytes}; pub use qr_utils::{get_content, mk_qr_bytes};
pub type CuttleSender = std::sync::mpsc::SyncSender<Vec<u8>>; pub type CuttleSender = std::sync::mpsc::SyncSender<Vec<u8>>;
pub type CuttleReceiver = std::sync::mpsc::Receiver<Vec<u8>>; pub type CuttleReceiver = std::sync::mpsc::Receiver<Vec<u8>>;
pub const STREAMING_MTU: u16 = 2326;
/// The application state /// The application state
#[derive(Debug)] #[derive(Debug)]
@ -75,4 +78,42 @@ pub struct TxConfig {
pub len: u64, pub len: u64,
pub mtu: u16, pub mtu: u16,
pub description: String, pub description: String,
pub filename: Option<String>,
}
pub fn stream_bytes(
bytes: Vec<u8>,
tx: CuttleSender,
desc: &str,
filename: Option<&str>,
) -> Vec<u8> {
let len = bytes.len() as u64;
let txconfig = TxConfig {
len,
mtu: STREAMING_MTU,
description: desc.to_string(),
filename: filename.map(|f| f.to_string()),
};
let txconfig = rkyv::to_bytes::<_, 256>(&txconfig)
.expect("tried to serialize the txconfig")
.to_vec();
std::thread::spawn(move || {
let rng = &mut rand::thread_rng();
let config = ObjectTransmissionInformation::with_defaults(len, STREAMING_MTU);
let encoder = Encoder::new(&bytes, config);
let mut packets = encoder
.get_encoded_packets(10)
.iter()
.map(|p| p.serialize())
.collect::<Vec<_>>();
packets.shuffle(rng);
for packet in packets.iter().cycle() {
tx.send(packet.clone()).unwrap_or_default();
}
});
txconfig
} }

View file

@ -30,16 +30,17 @@ fn main() -> Result<(), eframe::Error> {
let cli = Cli::parse(); let cli = Cli::parse();
let description = if let Some(ref file) = cli.file { let (description, filename) = if let Some(ref file) = cli.file {
let text = cli.text().join(" "); let text = cli.text().join(" ");
let sep = if text.is_empty() { "" } else { ": " }; let sep = if text.is_empty() { "" } else { ": " };
let file = std::path::Path::new(&file) let file = std::path::Path::new(&file)
.file_name() .file_name()
.unwrap_or_default() .unwrap_or_default()
.to_string_lossy(); .to_string_lossy()
format!("{file}{sep}{text}") .to_string();
(format!("{file}{sep}{text}"), Some(file))
} else { } else {
"text message".to_string() ("text message".to_string(), None)
}; };
let bytes = if let Some(ref file) = cli.file { let bytes = if let Some(ref file) = cli.file {
@ -48,7 +49,7 @@ fn main() -> Result<(), eframe::Error> {
cli.text().join(" ").bytes().collect() cli.text().join(" ").bytes().collect()
}; };
let content = get_content(bytes, &description); let content = get_content(bytes, &description, filename.as_deref());
let flasher = Flasher::new(description, content, cli.fps); let flasher = Flasher::new(description, content, cli.fps);

View file

@ -1,41 +1,6 @@
use fast_qr::convert::image::ImageBuilder; use fast_qr::convert::image::ImageBuilder;
use rand::seq::SliceRandom;
use raptorq::{Encoder, ObjectTransmissionInformation};
use crate::{Content, CuttleSender, StreamedContent, TxConfig}; use crate::{stream_bytes, Content, StreamedContent};
pub const STREAMING_MTU: u16 = 2326;
pub fn stream_bytes(bytes: Vec<u8>, tx: CuttleSender, desc: String) -> Vec<u8> {
let len = bytes.len() as u64;
let txconfig = TxConfig {
len,
mtu: STREAMING_MTU,
description: desc.to_string(),
};
let txconfig = rkyv::to_bytes::<_, 256>(&txconfig)
.expect("tried to serialize the txconfig")
.to_vec();
std::thread::spawn(move || {
let rng = &mut rand::thread_rng();
let config = ObjectTransmissionInformation::with_defaults(len, STREAMING_MTU);
let encoder = Encoder::new(&bytes, config);
let mut packets = encoder
.get_encoded_packets(10)
.iter()
.map(|p| p.serialize())
.collect::<Vec<_>>();
packets.shuffle(rng);
for packet in packets.iter().cycle() {
tx.send(packet.clone()).unwrap_or_default();
}
});
txconfig
}
/// Makes a PNG of a QR code for the given bytes, returns the bytes of the PNG. /// Makes a PNG of a QR code for the given bytes, returns the bytes of the PNG.
pub fn mk_qr_bytes(bytes: &[u8], height: f32) -> Vec<u8> { pub fn mk_qr_bytes(bytes: &[u8], height: f32) -> Vec<u8> {
@ -53,13 +18,13 @@ pub fn mk_qr_bytes(bytes: &[u8], height: f32) -> Vec<u8> {
/// Turns bytes and a description into either a single QR code, or a stream of /// Turns bytes and a description into either a single QR code, or a stream of
/// them, depending on the size of the input. /// them, depending on the size of the input.
pub fn get_content(bytes: Vec<u8>, desc: &str) -> Content { pub fn get_content(bytes: Vec<u8>, desc: &str, filename: Option<&str>) -> Content {
if bytes.len() < 2000 && fast_qr::QRBuilder::new(bytes.clone()).build().is_ok() { if bytes.len() < 2000 && fast_qr::QRBuilder::new(bytes.clone()).build().is_ok() {
let bytes = bytes.leak(); let bytes = bytes.leak();
Content::Static(bytes) Content::Static(bytes)
} else { } else {
let (tx, rx) = std::sync::mpsc::sync_channel(2); let (tx, rx) = std::sync::mpsc::sync_channel(2);
let txconfig = stream_bytes(bytes, tx, desc.to_string()).leak(); let txconfig = stream_bytes(bytes, tx, desc, filename).leak();
let stream = StreamedContent::new(txconfig, rx); let stream = StreamedContent::new(txconfig, rx);
Content::Streamed(stream) Content::Streamed(stream)
} }