diff --git a/Cargo.lock b/Cargo.lock index 68964f8..fcaefad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,12 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "core2" version = "0.4.0" @@ -23,6 +29,25 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "338089f42c427b86394a5ee60ff321da23a5c89c9d89514c829687b26359fcff" +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "stable_deref_trait", +] + [[package]] name = "memchr" version = "2.6.3" @@ -47,6 +72,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "syn" version = "1.0.109" @@ -85,6 +116,7 @@ dependencies = [ "anyhow", "core2", "crc16", + "heapless", "thiserror-no-std", ] diff --git a/Cargo.toml b/Cargo.toml index 4d628e8..12832a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,13 +14,15 @@ edition = "2021" all-features = true [features] -default = [] +default = ["heapless"] xmodem = [] ymodem = [] zmodem = [] +alloc = [] [dependencies] core2 = { version = "0.4.0", default-features = false } crc16 = "0.4.0" thiserror-no-std = "2.0.2" anyhow = { version = "1.0.75", default-features = false } +heapless = { version = "0.8.0", optional = true } diff --git a/src/common.rs b/src/common.rs index 35da5e2..cab615b 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,9 +1,12 @@ #![allow(dead_code)] +#[cfg(feature = "alloc")] extern crate alloc; -use alloc::boxed::Box; +#[cfg(feature = "alloc")] use alloc::string::String; +#[cfg(not(feature = "alloc"))] +use heapless::String; use anyhow::Result; use core2::io::{Error, Read, Write}; @@ -34,7 +37,7 @@ pub enum ModemError { /// The number of communications errors exceeded `max_errors` in a single /// transmission. #[error("Too many errors, aborting - max errors: {errors}")] - ExhaustedRetries { errors: Box }, + ExhaustedRetries { errors: u32 }, /// The transmission was canceled by the other end of the channel. #[error("Cancelled by the other party.")] @@ -142,14 +145,16 @@ pub trait YModemTrait: ModemTrait { &mut self, dev: &mut D, out: &mut W, - file_name: &mut String, + #[cfg(feature = "alloc")] file_name: &mut String, + #[cfg(not(feature = "alloc"))] file_name: &mut String<128>, file_size: &mut u32, ) -> ModemResult<()>; fn send( &mut self, dev: &mut D, inp: &mut R, - file_name: String, + #[cfg(feature = "alloc")] file_name: String, + #[cfg(not(feature = "alloc"))] file_name: String<128>, file_size: u64, ) -> ModemResult<()>; fn send_stream( @@ -162,7 +167,8 @@ pub trait YModemTrait: ModemTrait { fn send_start_frame( &mut self, dev: &mut D, - file_name: String, + #[cfg(feature = "alloc")] file_name: String, + #[cfg(not(feature = "alloc"))] file_name: String<128>, file_size: u64, ) -> ModemResult<()>; fn send_end_frame( diff --git a/src/lib.rs b/src/lib.rs index 7d07479..6874ef0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,6 +16,7 @@ variant_size_differences )] +#[cfg(feature = "alloc")] extern crate alloc; mod common; diff --git a/src/variants/api/xmodem.rs b/src/variants/api/xmodem.rs index 29f62ad..b057db6 100644 --- a/src/variants/api/xmodem.rs +++ b/src/variants/api/xmodem.rs @@ -1,11 +1,13 @@ -use alloc::{boxed::Box, vec, vec::Vec}; -use core::convert::From; - use crate::common::{ calc_checksum, calc_crc, get_byte, get_byte_timeout, ModemError, ModemResult, ModemTrait, XModemTrait, }; +#[cfg(feature = "alloc")] +use alloc::{vec, vec::Vec}; +use core::convert::From; use core2::io::{Read, Write}; +#[cfg(not(feature = "alloc"))] +use heapless::Vec; use crate::variants::xmodem::{ common::{BlockLengthKind, ChecksumKind}, @@ -101,8 +103,14 @@ impl XModemTrait for XModem { // We'll respond with cancel later if the packet number is wrong let cancel_packet = packet_num != pnum || (255 - pnum) != pnum_1c; + #[cfg(feature = "alloc")] let mut data: Vec = Vec::new(); + #[cfg(not(feature = "alloc"))] + let mut data: Vec = Vec::new(); + #[cfg(feature = "alloc")] data.resize(packet_size, 0); + #[cfg(not(feature = "alloc"))] + data.resize(packet_size, 0).unwrap_or_default(); dev.read_exact(&mut data)?; let success = match self.checksum_mode { ChecksumKind::Standard => { @@ -144,7 +152,7 @@ impl XModemTrait for XModem { if self.errors >= self.max_errors { dev.write_all(&[Consts::CAN.into()])?; return Err(ModemError::ExhaustedRetries { - errors: Box::from(self.errors), + errors: self.errors, }); } } @@ -183,7 +191,7 @@ impl XModemTrait for XModem { if self.errors >= self.max_errors { // FIXME: Removed a unused 'if let' here. To be re-added? return Err(ModemError::ExhaustedRetries { - errors: Box::from(self.errors), + errors: self.errors, }); } } @@ -208,7 +216,7 @@ impl XModemTrait for XModem { if self.errors >= self.max_errors { return Err(ModemError::ExhaustedRetries { - errors: Box::from(self.errors), + errors: self.errors, }); } } @@ -221,7 +229,16 @@ impl XModemTrait for XModem { { let mut block_num = 0u32; loop { + #[cfg(feature = "alloc")] let mut buff = vec![self.pad_byte; self.block_length as usize + 3]; + #[cfg(not(feature = "alloc"))] + let mut buff: Vec = Vec::new(); + #[cfg(not(feature = "alloc"))] + buff.resize(self.block_length as usize + 3, self.pad_byte) + .unwrap_or_default(); + + #[cfg(feature = "alloc")] + buff.resize(self.block_length as usize + 3, self.pad_byte); let n = inp.read(&mut buff[3..])?; if n == 0 { return Ok(()); @@ -238,12 +255,21 @@ impl XModemTrait for XModem { match self.checksum_mode { ChecksumKind::Standard => { let checksum = calc_checksum(&buff[3..]); + #[cfg(feature = "alloc")] buff.push(checksum); + #[cfg(not(feature = "alloc"))] + buff.push(checksum).unwrap_or_default(); } ChecksumKind::Crc16 => { let crc = calc_crc(&buff[3..]); + #[cfg(feature = "alloc")] buff.push(((crc >> 8) & 0xFF) as u8); + #[cfg(feature = "alloc")] buff.push((&crc & 0xFF) as u8); + #[cfg(not(feature = "alloc"))] + buff.push(((crc >> 8) & 0xFF) as u8).unwrap_or_default(); + #[cfg(not(feature = "alloc"))] + buff.push((&crc & 0xFF) as u8).unwrap_or_default(); } } @@ -260,7 +286,7 @@ impl XModemTrait for XModem { if self.errors >= self.max_errors { return Err(ModemError::ExhaustedRetries { - errors: Box::from(self.errors), + errors: self.errors, }); } }