diff --git a/src/oned/mod.rs b/src/oned/mod.rs index c91142d..d024ce7 100644 --- a/src/oned/mod.rs +++ b/src/oned/mod.rs @@ -92,5 +92,4 @@ pub use ean_8_writer::*; mod upc_e_writer; pub use upc_e_writer::*; -mod telepen_common; -pub use telepen_common::*; \ No newline at end of file +mod telepen_common; \ No newline at end of file diff --git a/src/oned/telepen_common.rs b/src/oned/telepen_common.rs index 79c5541..b487811 100644 --- a/src/oned/telepen_common.rs +++ b/src/oned/telepen_common.rs @@ -1,66 +1,98 @@ -pub mod TelepenCommon { - use crate::Exceptions; - use crate::common::Result; +use crate::Exceptions; +use crate::common::Result; - pub fn calculate_checksum(contents: &str) -> char { - let mut sum = 0; +pub fn calculate_checksum(contents: &str) -> char { + let mut sum = 0; - for c in contents.chars() { - sum += c as u32; - } + for c in contents.chars() { + sum += c as u32; + } - let remainder = sum % 127; - let diff = 127 - remainder; - return if diff != 127 { - diff as u8 as char + let remainder = sum % 127; + let diff = 127 - remainder; + return if diff != 127 { + diff as u8 as char + } + else { + 0 as char + }; +} + +pub fn ascii_to_numeric(contents: &str) -> String { + let mut number = String::new(); + + for c in contents.chars().map(|x| x as u32) { + if c >= 27 { + number.push_str(&format!("{:0>2}", (c - 27))); } else { - 0 as char - }; + number.push_str(&format!("{:0>2}", (c - 17))); + } + } + + return number; +} + +pub fn numeric_to_ascii(contents: &str) -> Result { + if contents.len() % 2 != 0 { + return Err(Exceptions::illegal_argument_with("Input must contain an even number of characters.")); } - pub fn ascii_to_numeric(contents: &str) -> String { - let mut number = String::new(); + let mut ascii = String::new(); + let mut i = 0; - for i in 0 .. contents.len() { - let temp = contents.chars().nth(i).unwrap() as u32; + while i < contents.len() { + let first = contents.chars().nth(i).unwrap() as u8; + let second = contents.chars().nth(i + 1).unwrap() as u8; - if temp >= 27 { - number.push_str(&format!("{:0>2}", (temp - 27))); - } - else { - number.push_str(&format!("{:0>2}", (temp - 17))); - } + if second == 88 && first >= 48 && first <= 57 { + ascii.push((17 + first - 48) as char); } - - return number; + else if second >= 48 && second <= 57 && first >= 48 && first <= 57 { + ascii.push((27 + (first - 48) * 10 + (second - 48)) as char); + } + else { + return Err(Exceptions::illegal_argument_with(format!("Input contains an invalid character around position {}.", i.to_string()))); + } + + i += 2; } - pub fn numeric_to_ascii(contents: &str) -> Result { - if contents.len() % 2 != 0 { - return Err(Exceptions::illegal_argument_with("Input must contain an even number of characters.")); - } + return Ok(ascii); +} - let mut ascii = String::new(); - let mut i = 0; +#[test] +fn telepen_checksum_test1() { + let contents = "Hello world!"; + let checksum = calculate_checksum(contents); + assert_eq!('\u{1a}', checksum); +} - while i < contents.len() { - let first = contents.chars().nth(i).unwrap() as u8; - let second = contents.chars().nth(i + 1).unwrap() as u8; +#[test] +fn telepen_checksum_test2() { + let contents = "ABC123456"; + let checksum = calculate_checksum(contents); + assert_eq!('\u{1}', checksum); +} - if second == 88 && first >= 48 && first <= 57 { - ascii.push((17 + first - 48) as char); - } - else if second >= 48 && second <= 57 && first >= 48 && first <= 57 { - ascii.push((27 + (first - 48) * 10 + (second - 48)) as char); - } - else { - return Err(Exceptions::illegal_argument_with(format!("Input contains an invalid character around position {}.", i.to_string()))); - } +#[test] +fn telepen_alpha_to_numeric_test() { + let mut ascii = "'=Siu"; + let mut result = ascii_to_numeric(ascii); + assert_eq!("1234567890", result); - i += 2; - } + ascii = "& oe"; + result = ascii_to_numeric(ascii); + assert_eq!("11058474", result); +} - return Ok(ascii); - } +#[test] +fn telepen_numeric_to_ascii_test() { + let mut numeric = "1234567890"; + let mut result = numeric_to_ascii(numeric).unwrap(); + assert_eq!("'=Siu", result); + + numeric = "11058474"; + result = numeric_to_ascii(numeric).unwrap(); + assert_eq!("& oe", result); } \ No newline at end of file diff --git a/src/oned/telepen_reader.rs b/src/oned/telepen_reader.rs index c3a04ba..968aefd 100644 --- a/src/oned/telepen_reader.rs +++ b/src/oned/telepen_reader.rs @@ -20,8 +20,8 @@ use crate::common::{BitArray, Result}; use crate::Exceptions; use crate::RXingResult; use crate::DecodeHintValue; +use crate::oned::telepen_common; use crate::{point_f, BarcodeFormat}; -use crate::oned::TelepenCommon; use bit_reverse::ParallelReverse; use super::OneDReader; @@ -180,6 +180,12 @@ impl OneDReader for TelepenReader { } let byteLength = bits.getSizeInBytes(); + + // Any Telepen barcode will be longer than two bytes. + if byteLength < 3 { + return Err(Exceptions::NOT_FOUND); + } + let mut bytes: Vec = vec![0; byteLength]; bits.toBytes(0, bytes.as_mut_slice(), 0, byteLength); @@ -220,7 +226,7 @@ impl OneDReader for TelepenReader { // Penultimate byte is a block check character. let check = bytes[byteLength - 2]; - let checksum = TelepenCommon::calculate_checksum(&contentString); + let checksum = telepen_common::calculate_checksum(&contentString); // Validate checksum if check != checksum as u8 { @@ -231,7 +237,7 @@ impl OneDReader for TelepenReader { hints.get(&DecodeHintType::TELEPEN_AS_NUMERIC), Some(DecodeHintValue::TelepenAsNumeric(true)) ) { - contentString = TelepenCommon::ascii_to_numeric(&contentString); + contentString = telepen_common::ascii_to_numeric(&contentString); } let mut runningCount = 0; @@ -427,8 +433,4 @@ impl TelepenReader { } return Ok((self.counterLength - 1) as u32); } - - pub fn arrayContains(array: &[char], key: char) -> bool { - array.contains(&key) - } } diff --git a/src/oned/telepen_writer.rs b/src/oned/telepen_writer.rs index 04f8797..08346e5 100644 --- a/src/oned/telepen_writer.rs +++ b/src/oned/telepen_writer.rs @@ -18,7 +18,7 @@ use rxing_one_d_proc_derive::OneDWriter; use regex::Regex; use crate::common::Result; use crate::BarcodeFormat; -use crate::oned::TelepenCommon; +use crate::oned::telepen_common; use super::OneDimensionalCodeWriter; @@ -44,11 +44,11 @@ impl OneDimensionalCodeWriter for TelepenWriter { hints.get(&EncodeHintType::TELEPEN_AS_NUMERIC), Some(EncodeHintValue::TelepenAsNumeric(true)) ) { - decodedContents = TelepenCommon::numeric_to_ascii(&contents).unwrap(); + decodedContents = telepen_common::numeric_to_ascii(&contents)?; } // Calculate the checksum character - let checksum = TelepenCommon::calculate_checksum(&decodedContents); + let checksum = telepen_common::calculate_checksum(&decodedContents); // Build binary string let mut binary = String::new(); @@ -80,78 +80,80 @@ impl OneDimensionalCodeWriter for TelepenWriter { let mut resultPosition = 0; for b in matches { - if b == "010" { - // BBB... - result[resultPosition] = true; - result[resultPosition + 1] = true; - result[resultPosition + 2] = true; - result[resultPosition + 3] = false; - result[resultPosition + 4] = false; - result[resultPosition + 5] = false; + match b { + "010" => { + // BBB... + result[resultPosition] = true; + result[resultPosition + 1] = true; + result[resultPosition + 2] = true; + result[resultPosition + 3] = false; + result[resultPosition + 4] = false; + result[resultPosition + 5] = false; - resultPosition += 6; - } - else if b == "00" { - // BBB. - result[resultPosition] = true; - result[resultPosition + 1] = true; - result[resultPosition + 2] = true; - result[resultPosition + 3] = false; + resultPosition += 6; + }, + "00" => { + // BBB. + result[resultPosition] = true; + result[resultPosition + 1] = true; + result[resultPosition + 2] = true; + result[resultPosition + 3] = false; - resultPosition += 4; - } - else if b == "1" { - // B. - result[resultPosition] = true; - result[resultPosition + 1] = false; - - resultPosition += 2; - } - else if b == "01" { - // B... - result[resultPosition] = true; - result[resultPosition + 1] = false; - result[resultPosition + 2] = false; - result[resultPosition + 3] = false; - - resultPosition += 4; - } - else if b == "10" { - // B... - result[resultPosition] = true; - result[resultPosition + 1] = false; - result[resultPosition + 2] = false; - result[resultPosition + 3] = false; - - resultPosition += 4; - } - else if b == "0" { - return Err(Exceptions::illegal_argument_with(format!( - "Invalid bit combination!" - ))); - } - else { - // B... (B.)* B... - result[resultPosition] = true; - result[resultPosition + 1] = false; - result[resultPosition + 2] = false; - result[resultPosition + 3] = false; - - resultPosition += 4; - - for _j in 2 .. b.len() - 2 { + resultPosition += 4; + }, + "1" => { + // B. result[resultPosition] = true; result[resultPosition + 1] = false; resultPosition += 2; + }, + "01" => { + // B... + result[resultPosition] = true; + result[resultPosition + 1] = false; + result[resultPosition + 2] = false; + result[resultPosition + 3] = false; + + resultPosition += 4; + }, + "10" => { + // B... + result[resultPosition] = true; + result[resultPosition + 1] = false; + result[resultPosition + 2] = false; + result[resultPosition + 3] = false; + + resultPosition += 4; + }, + "0" => { + return Err(Exceptions::illegal_argument_with(format!( + "Invalid bit combination!" + ))); + }, + _ => { + // B... (B.)* B... + result[resultPosition] = true; + result[resultPosition + 1] = false; + result[resultPosition + 2] = false; + result[resultPosition + 3] = false; + + resultPosition += 4; + + for _j in 2 .. b.len() - 2 { + result[resultPosition] = true; + result[resultPosition + 1] = false; + + resultPosition += 2; + } + + result[resultPosition] = true; + result[resultPosition + 1] = false; + result[resultPosition + 2] = false; + result[resultPosition + 3] = false; + + resultPosition += 4; } - - result[resultPosition] = true; - result[resultPosition + 1] = false; - result[resultPosition + 2] = false; - result[resultPosition + 3] = false; - - resultPosition += 4; } } diff --git a/tests/telepen_blackbox_1_test_case.rs b/tests/telepen_blackbox_1_test_case.rs index 1866f38..4d7b7f4 100644 --- a/tests/telepen_blackbox_1_test_case.rs +++ b/tests/telepen_blackbox_1_test_case.rs @@ -14,7 +14,7 @@ * limitations under the License. */ -use rxing::{oned::TelepenReader, BarcodeFormat, oned::TelepenCommon}; +use rxing::{oned::TelepenReader, BarcodeFormat}; mod common; @@ -51,39 +51,3 @@ fn telepen_numeric_test_case() { tester.test_black_box(); } - -#[test] -fn telepen_checksum_test1() { - let contents = "Hello world!"; - let checksum = TelepenCommon::calculate_checksum(contents); - assert_eq!('\u{1a}', checksum); -} - -#[test] -fn telepen_checksum_test2() { - let contents = "ABC123456"; - let checksum = TelepenCommon::calculate_checksum(contents); - assert_eq!('\u{1}', checksum); -} - -#[test] -fn telepen_alpha_to_numeric_test() { - let mut ascii = "'=Siu"; - let mut result = TelepenCommon::ascii_to_numeric(ascii); - assert_eq!("1234567890", result); - - ascii = "& oe"; - result = TelepenCommon::ascii_to_numeric(ascii); - assert_eq!("11058474", result); -} - -#[test] -fn telepen_numeric_to_ascii_test() { - let mut numeric = "1234567890"; - let mut result = TelepenCommon::numeric_to_ascii(numeric).unwrap(); - assert_eq!("'=Siu", result); - - numeric = "11058474"; - result = TelepenCommon::numeric_to_ascii(numeric).unwrap(); - assert_eq!("& oe", result); -}