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},
};
use rand::seq::SliceRandom;
use raptorq::{Encoder, ObjectTransmissionInformation};
use rkyv::{Archive, Deserialize, Serialize};
#[cfg(feature = "desktop")]
@ -11,10 +13,11 @@ mod desktop;
mod qr_utils;
#[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 CuttleReceiver = std::sync::mpsc::Receiver<Vec<u8>>;
pub const STREAMING_MTU: u16 = 2326;
/// The application state
#[derive(Debug)]
@ -75,4 +78,42 @@ pub struct TxConfig {
pub len: u64,
pub mtu: u16,
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 description = if let Some(ref file) = cli.file {
let (description, filename) = if let Some(ref file) = cli.file {
let text = cli.text().join(" ");
let sep = if text.is_empty() { "" } else { ": " };
let file = std::path::Path::new(&file)
.file_name()
.unwrap_or_default()
.to_string_lossy();
format!("{file}{sep}{text}")
.to_string_lossy()
.to_string();
(format!("{file}{sep}{text}"), Some(file))
} else {
"text message".to_string()
("text message".to_string(), None)
};
let bytes = if let Some(ref file) = cli.file {
@ -48,7 +49,7 @@ fn main() -> Result<(), eframe::Error> {
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);

View file

@ -1,41 +1,6 @@
use fast_qr::convert::image::ImageBuilder;
use rand::seq::SliceRandom;
use raptorq::{Encoder, ObjectTransmissionInformation};
use crate::{Content, CuttleSender, StreamedContent, TxConfig};
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
}
use crate::{stream_bytes, Content, StreamedContent};
/// 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> {
@ -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
/// 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() {
let bytes = bytes.leak();
Content::Static(bytes)
} else {
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);
Content::Streamed(stream)
}