From 0465d6179a8f8a7bff79ce9806c04158ac424cb5 Mon Sep 17 00:00:00 2001 From: Eskild Jonatan Krumsvik Aanensen Date: Wed, 20 Nov 2024 12:09:55 +0100 Subject: [PATCH 1/4] Remove Box Breaking change, prepares for no_alloc feature --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/common.rs | 3 +-- src/variants/api/xmodem.rs | 15 ++++++++------- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68964f8..572e448 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,7 +80,7 @@ dependencies = [ [[package]] name = "txmodems" -version = "0.1.3" +version = "0.2.0" dependencies = [ "anyhow", "core2", diff --git a/Cargo.toml b/Cargo.toml index 4d628e8..58c7ebe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ repository = "https://github.com/Cosmo-CoDiOS/txmodems" description = "Rust library for various MODEM file transfer protocols" categories = ["embedded"] keywords = ["data-transfer", "MODEM", "file-transfer", "embedded"] -version = "0.1.3" +version = "0.2.0" authors = ["Dom Rodriguez "] license = "MIT" edition = "2021" diff --git a/src/common.rs b/src/common.rs index 35da5e2..8b1d87f 100644 --- a/src/common.rs +++ b/src/common.rs @@ -2,7 +2,6 @@ extern crate alloc; -use alloc::boxed::Box; use alloc::string::String; use anyhow::Result; @@ -34,7 +33,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.")] diff --git a/src/variants/api/xmodem.rs b/src/variants/api/xmodem.rs index 29f62ad..86788c0 100644 --- a/src/variants/api/xmodem.rs +++ b/src/variants/api/xmodem.rs @@ -1,12 +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, }; + +use alloc::{vec, vec::Vec}; +use core::convert::From; use core2::io::{Read, Write}; + use crate::variants::xmodem::{ common::{BlockLengthKind, ChecksumKind}, Consts, @@ -144,7 +145,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 +184,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 +209,7 @@ impl XModemTrait for XModem { if self.errors >= self.max_errors { return Err(ModemError::ExhaustedRetries { - errors: Box::from(self.errors), + errors: self.errors, }); } } @@ -260,7 +261,7 @@ impl XModemTrait for XModem { if self.errors >= self.max_errors { return Err(ModemError::ExhaustedRetries { - errors: Box::from(self.errors), + errors: self.errors, }); } } From fbc268c5f834ea202c869e761d2ba7cd993d5c66 Mon Sep 17 00:00:00 2001 From: Eskild Jonatan Krumsvik Aanensen Date: Wed, 20 Nov 2024 12:29:10 +0100 Subject: [PATCH 2/4] Add no_alloc feature, heapless dependency Add support for no heap memory allocation, using the heapless crate --- Cargo.lock | 32 ++++++++++++++++++++++++++++++++ Cargo.toml | 2 ++ src/common.rs | 13 ++++++++++--- src/lib.rs | 1 + src/variants/api/xmodem.rs | 29 +++++++++++++++++++++++++++-- 5 files changed, 72 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 572e448..b756afd 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 58c7ebe..80adb0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,9 +18,11 @@ default = [] xmodem = [] ymodem = [] zmodem = [] +no_alloc = ["heapless"] [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 8b1d87f..8d25b48 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,8 +1,12 @@ #![allow(dead_code)] +#[cfg(not(feature = "no_alloc"))] extern crate alloc; +#[cfg(not(feature = "no_alloc"))] use alloc::string::String; +#[cfg(feature = "no_alloc")] +use heapless::String; use anyhow::Result; use core2::io::{Error, Read, Write}; @@ -141,14 +145,16 @@ pub trait YModemTrait: ModemTrait { &mut self, dev: &mut D, out: &mut W, - file_name: &mut String, + #[cfg(not(feature = "no_alloc"))] file_name: &mut String, + #[cfg(feature = "no_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(not(feature = "no_alloc"))] file_name: String, + #[cfg(feature = "no_alloc")] file_name: String<128>, file_size: u64, ) -> ModemResult<()>; fn send_stream( @@ -161,7 +167,8 @@ pub trait YModemTrait: ModemTrait { fn send_start_frame( &mut self, dev: &mut D, - file_name: String, + #[cfg(not(feature = "no_alloc"))] file_name: String, + #[cfg(feature = "no_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..df326c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,6 +16,7 @@ variant_size_differences )] +#[cfg(not(feature = "no_alloc"))] extern crate alloc; mod common; diff --git a/src/variants/api/xmodem.rs b/src/variants/api/xmodem.rs index 86788c0..cd7df8f 100644 --- a/src/variants/api/xmodem.rs +++ b/src/variants/api/xmodem.rs @@ -2,11 +2,12 @@ use crate::common::{ calc_checksum, calc_crc, get_byte, get_byte_timeout, ModemError, ModemResult, ModemTrait, XModemTrait, }; - +#[cfg(not(feature = "no_alloc"))] use alloc::{vec, vec::Vec}; use core::convert::From; use core2::io::{Read, Write}; - +#[cfg(feature = "no_alloc")] +use heapless::Vec; use crate::variants::xmodem::{ common::{BlockLengthKind, ChecksumKind}, @@ -102,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(not(feature = "no_alloc"))] let mut data: Vec = Vec::new(); + #[cfg(feature = "no_alloc")] + let mut data: Vec = Vec::new(); + #[cfg(not(feature = "no_alloc"))] data.resize(packet_size, 0); + #[cfg(feature = "no_alloc")] + data.resize(packet_size, 0).unwrap_or_default(); dev.read_exact(&mut data)?; let success = match self.checksum_mode { ChecksumKind::Standard => { @@ -222,7 +229,16 @@ impl XModemTrait for XModem { { let mut block_num = 0u32; loop { + #[cfg(not(feature = "no_alloc"))] let mut buff = vec![self.pad_byte; self.block_length as usize + 3]; + #[cfg(feature = "no_alloc")] + let mut buff: Vec = Vec::new(); + #[cfg(feature = "no_alloc")] + buff.resize(self.block_length as usize + 3, self.pad_byte) + .unwrap_or_default(); + + #[cfg(not(feature = "no_alloc"))] + buff.resize(self.block_length as usize + 3, self.pad_byte); let n = inp.read(&mut buff[3..])?; if n == 0 { return Ok(()); @@ -239,12 +255,21 @@ impl XModemTrait for XModem { match self.checksum_mode { ChecksumKind::Standard => { let checksum = calc_checksum(&buff[3..]); + #[cfg(not(feature = "no_alloc"))] buff.push(checksum); + #[cfg(feature = "no_alloc")] + buff.push(checksum).unwrap_or_default(); } ChecksumKind::Crc16 => { let crc = calc_crc(&buff[3..]); + #[cfg(not(feature = "no_alloc"))] buff.push(((crc >> 8) & 0xFF) as u8); + #[cfg(not(feature = "no_alloc"))] buff.push((&crc & 0xFF) as u8); + #[cfg(feature = "no_alloc")] + buff.push(((crc >> 8) & 0xFF) as u8).unwrap_or_default(); + #[cfg(feature = "no_alloc")] + buff.push((&crc & 0xFF) as u8).unwrap_or_default(); } } From 76647528dfa8c675819079cb95f32d656163766a Mon Sep 17 00:00:00 2001 From: Eskild Jonatan Krumsvik Aanensen Date: Mon, 9 Dec 2024 13:51:22 +0100 Subject: [PATCH 3/4] Revert "no_alloc-feature" --- Cargo.lock | 34 +------------------------------- Cargo.toml | 4 +--- src/common.rs | 16 +++++---------- src/lib.rs | 1 - src/variants/api/xmodem.rs | 40 +++++++------------------------------- 5 files changed, 14 insertions(+), 81 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b756afd..68964f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,12 +8,6 @@ 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" @@ -29,25 +23,6 @@ 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" @@ -72,12 +47,6 @@ 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" @@ -111,12 +80,11 @@ dependencies = [ [[package]] name = "txmodems" -version = "0.2.0" +version = "0.1.3" dependencies = [ "anyhow", "core2", "crc16", - "heapless", "thiserror-no-std", ] diff --git a/Cargo.toml b/Cargo.toml index 80adb0c..4d628e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ repository = "https://github.com/Cosmo-CoDiOS/txmodems" description = "Rust library for various MODEM file transfer protocols" categories = ["embedded"] keywords = ["data-transfer", "MODEM", "file-transfer", "embedded"] -version = "0.2.0" +version = "0.1.3" authors = ["Dom Rodriguez "] license = "MIT" edition = "2021" @@ -18,11 +18,9 @@ default = [] xmodem = [] ymodem = [] zmodem = [] -no_alloc = ["heapless"] [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 8d25b48..35da5e2 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,12 +1,9 @@ #![allow(dead_code)] -#[cfg(not(feature = "no_alloc"))] extern crate alloc; -#[cfg(not(feature = "no_alloc"))] +use alloc::boxed::Box; use alloc::string::String; -#[cfg(feature = "no_alloc")] -use heapless::String; use anyhow::Result; use core2::io::{Error, Read, Write}; @@ -37,7 +34,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: u32 }, + ExhaustedRetries { errors: Box }, /// The transmission was canceled by the other end of the channel. #[error("Cancelled by the other party.")] @@ -145,16 +142,14 @@ pub trait YModemTrait: ModemTrait { &mut self, dev: &mut D, out: &mut W, - #[cfg(not(feature = "no_alloc"))] file_name: &mut String, - #[cfg(feature = "no_alloc")] file_name: &mut String<128>, + file_name: &mut String, file_size: &mut u32, ) -> ModemResult<()>; fn send( &mut self, dev: &mut D, inp: &mut R, - #[cfg(not(feature = "no_alloc"))] file_name: String, - #[cfg(feature = "no_alloc")] file_name: String<128>, + file_name: String, file_size: u64, ) -> ModemResult<()>; fn send_stream( @@ -167,8 +162,7 @@ pub trait YModemTrait: ModemTrait { fn send_start_frame( &mut self, dev: &mut D, - #[cfg(not(feature = "no_alloc"))] file_name: String, - #[cfg(feature = "no_alloc")] file_name: String<128>, + file_name: String, file_size: u64, ) -> ModemResult<()>; fn send_end_frame( diff --git a/src/lib.rs b/src/lib.rs index df326c8..7d07479 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,7 +16,6 @@ variant_size_differences )] -#[cfg(not(feature = "no_alloc"))] extern crate alloc; mod common; diff --git a/src/variants/api/xmodem.rs b/src/variants/api/xmodem.rs index cd7df8f..29f62ad 100644 --- a/src/variants/api/xmodem.rs +++ b/src/variants/api/xmodem.rs @@ -1,13 +1,11 @@ +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(not(feature = "no_alloc"))] -use alloc::{vec, vec::Vec}; -use core::convert::From; use core2::io::{Read, Write}; -#[cfg(feature = "no_alloc")] -use heapless::Vec; use crate::variants::xmodem::{ common::{BlockLengthKind, ChecksumKind}, @@ -103,14 +101,8 @@ 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(not(feature = "no_alloc"))] let mut data: Vec = Vec::new(); - #[cfg(feature = "no_alloc")] - let mut data: Vec = Vec::new(); - #[cfg(not(feature = "no_alloc"))] data.resize(packet_size, 0); - #[cfg(feature = "no_alloc")] - data.resize(packet_size, 0).unwrap_or_default(); dev.read_exact(&mut data)?; let success = match self.checksum_mode { ChecksumKind::Standard => { @@ -152,7 +144,7 @@ impl XModemTrait for XModem { if self.errors >= self.max_errors { dev.write_all(&[Consts::CAN.into()])?; return Err(ModemError::ExhaustedRetries { - errors: self.errors, + errors: Box::from(self.errors), }); } } @@ -191,7 +183,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: self.errors, + errors: Box::from(self.errors), }); } } @@ -216,7 +208,7 @@ impl XModemTrait for XModem { if self.errors >= self.max_errors { return Err(ModemError::ExhaustedRetries { - errors: self.errors, + errors: Box::from(self.errors), }); } } @@ -229,16 +221,7 @@ impl XModemTrait for XModem { { let mut block_num = 0u32; loop { - #[cfg(not(feature = "no_alloc"))] let mut buff = vec![self.pad_byte; self.block_length as usize + 3]; - #[cfg(feature = "no_alloc")] - let mut buff: Vec = Vec::new(); - #[cfg(feature = "no_alloc")] - buff.resize(self.block_length as usize + 3, self.pad_byte) - .unwrap_or_default(); - - #[cfg(not(feature = "no_alloc"))] - buff.resize(self.block_length as usize + 3, self.pad_byte); let n = inp.read(&mut buff[3..])?; if n == 0 { return Ok(()); @@ -255,21 +238,12 @@ impl XModemTrait for XModem { match self.checksum_mode { ChecksumKind::Standard => { let checksum = calc_checksum(&buff[3..]); - #[cfg(not(feature = "no_alloc"))] buff.push(checksum); - #[cfg(feature = "no_alloc")] - buff.push(checksum).unwrap_or_default(); } ChecksumKind::Crc16 => { let crc = calc_crc(&buff[3..]); - #[cfg(not(feature = "no_alloc"))] buff.push(((crc >> 8) & 0xFF) as u8); - #[cfg(not(feature = "no_alloc"))] buff.push((&crc & 0xFF) as u8); - #[cfg(feature = "no_alloc")] - buff.push(((crc >> 8) & 0xFF) as u8).unwrap_or_default(); - #[cfg(feature = "no_alloc")] - buff.push((&crc & 0xFF) as u8).unwrap_or_default(); } } @@ -286,7 +260,7 @@ impl XModemTrait for XModem { if self.errors >= self.max_errors { return Err(ModemError::ExhaustedRetries { - errors: self.errors, + errors: Box::from(self.errors), }); } } From cfe847bdd10c4f8fdb4cc9b15e5f28e8e813ec86 Mon Sep 17 00:00:00 2001 From: Eskild Jonatan Krumsvik Aanensen Date: Mon, 9 Dec 2024 14:04:37 +0100 Subject: [PATCH 4/4] Change to alloc feature --- Cargo.lock | 32 ++++++++++++++++++++++++++++++ Cargo.toml | 4 +++- src/common.rs | 16 ++++++++++----- src/lib.rs | 1 + src/variants/api/xmodem.rs | 40 +++++++++++++++++++++++++++++++------- 5 files changed, 80 insertions(+), 13 deletions(-) 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, }); } }