mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 04:12:34 +00:00
Code refactor and numeric support
This commit is contained in:
@@ -121,6 +121,12 @@ pub enum DecodeHintType {
|
|||||||
*/
|
*/
|
||||||
#[cfg(feature = "allow_forced_iso_ied_18004_compliance")]
|
#[cfg(feature = "allow_forced_iso_ied_18004_compliance")]
|
||||||
QR_ASSUME_SPEC_CONFORM_INPUT,
|
QR_ASSUME_SPEC_CONFORM_INPUT,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Will translate the ASCII values parsed by the Telepen reader into the Telepen Numeric form.
|
||||||
|
*/
|
||||||
|
TELEPEN_AS_NUMERIC,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Data type the hint is expecting.
|
* Data type the hint is expecting.
|
||||||
* Among the possible values the {@link Void} stands out as being used for
|
* Among the possible values the {@link Void} stands out as being used for
|
||||||
@@ -231,4 +237,9 @@ pub enum DecodeHintValue {
|
|||||||
*/
|
*/
|
||||||
#[cfg(feature = "allow_forced_iso_ied_18004_compliance")]
|
#[cfg(feature = "allow_forced_iso_ied_18004_compliance")]
|
||||||
QrAssumeSpecConformInput(bool),
|
QrAssumeSpecConformInput(bool),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate the ASCII values parsed by the Telepen reader into the Telepen Numeric form; use {@link Boolean#TRUE}.
|
||||||
|
*/
|
||||||
|
TelepenAsNumeric(bool),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
pub struct TelepenCommon;
|
pub mod TelepenCommon {
|
||||||
|
use crate::Exceptions;
|
||||||
|
use crate::common::Result;
|
||||||
|
|
||||||
impl TelepenCommon {
|
|
||||||
pub fn calculate_checksum(contents: &str) -> char {
|
pub fn calculate_checksum(contents: &str) -> char {
|
||||||
let mut sum = 0;
|
let mut sum = 0;
|
||||||
|
|
||||||
@@ -17,4 +18,49 @@ impl TelepenCommon {
|
|||||||
0 as char
|
0 as char
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ascii_to_numeric(contents: &str) -> String {
|
||||||
|
let mut number = String::new();
|
||||||
|
|
||||||
|
for i in 0 .. contents.len() {
|
||||||
|
let temp = contents.chars().nth(i).unwrap() as u32;
|
||||||
|
|
||||||
|
if temp >= 27 {
|
||||||
|
number.push_str(&(temp - 27).to_string());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
number.push_str(&(temp - 17).to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn numeric_to_ascii(contents: &str) -> Result<String> {
|
||||||
|
if contents.len() % 2 != 0 {
|
||||||
|
return Err(Exceptions::illegal_argument_with("Input must contain an even number of characters."));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut ascii = String::new();
|
||||||
|
let mut i = 0;
|
||||||
|
|
||||||
|
while i < contents.len() {
|
||||||
|
let first = contents.chars().nth(i).unwrap() as u8;
|
||||||
|
let second = contents.chars().nth(i + 1).unwrap() as u8;
|
||||||
|
|
||||||
|
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())));
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(ascii);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -19,8 +19,9 @@ use rxing_one_d_proc_derive::OneDReader;
|
|||||||
use crate::common::{BitArray, Result};
|
use crate::common::{BitArray, Result};
|
||||||
use crate::Exceptions;
|
use crate::Exceptions;
|
||||||
use crate::RXingResult;
|
use crate::RXingResult;
|
||||||
|
use crate::DecodeHintValue;
|
||||||
use crate::{point_f, BarcodeFormat};
|
use crate::{point_f, BarcodeFormat};
|
||||||
use crate::oned::telepen_common::TelepenCommon;
|
use crate::oned::TelepenCommon;
|
||||||
use bit_reverse::ParallelReverse;
|
use bit_reverse::ParallelReverse;
|
||||||
|
|
||||||
use super::OneDReader;
|
use super::OneDReader;
|
||||||
@@ -51,7 +52,7 @@ impl OneDReader for TelepenReader {
|
|||||||
&mut self,
|
&mut self,
|
||||||
rowNumber: u32,
|
rowNumber: u32,
|
||||||
row: &crate::common::BitArray,
|
row: &crate::common::BitArray,
|
||||||
_hints: &crate::DecodingHintDictionary,
|
hints: &crate::DecodingHintDictionary,
|
||||||
) -> Result<crate::RXingResult> {
|
) -> Result<crate::RXingResult> {
|
||||||
self.counters.fill(0);
|
self.counters.fill(0);
|
||||||
self.setCounters(row, (row.get_size() as f32 * 0.001) as u32)?;
|
self.setCounters(row, (row.get_size() as f32 * 0.001) as u32)?;
|
||||||
@@ -214,7 +215,7 @@ impl OneDReader for TelepenReader {
|
|||||||
|
|
||||||
// Content bytes
|
// Content bytes
|
||||||
let contentBytes = bytes[1 .. byteLength - 2].to_vec();
|
let contentBytes = bytes[1 .. byteLength - 2].to_vec();
|
||||||
let contentString = String::from_utf8_lossy(&contentBytes);
|
let mut contentString = String::from_utf8_lossy(&contentBytes).to_string();
|
||||||
|
|
||||||
// Penultimate byte is a block check character.
|
// Penultimate byte is a block check character.
|
||||||
let check = bytes[byteLength - 2];
|
let check = bytes[byteLength - 2];
|
||||||
@@ -226,6 +227,13 @@ impl OneDReader for TelepenReader {
|
|||||||
return Err(Exceptions::NOT_FOUND);
|
return Err(Exceptions::NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if matches!(
|
||||||
|
hints.get(&DecodeHintType::TELEPEN_AS_NUMERIC),
|
||||||
|
Some(DecodeHintValue::TelepenAsNumeric(true))
|
||||||
|
) {
|
||||||
|
contentString = TelepenCommon::ascii_to_numeric(&contentString);
|
||||||
|
}
|
||||||
|
|
||||||
let mut runningCount = 0;
|
let mut runningCount = 0;
|
||||||
runningCount += self.counters.iter().take(startOffset).sum::<u32>();
|
runningCount += self.counters.iter().take(startOffset).sum::<u32>();
|
||||||
let left: f32 = runningCount as f32;
|
let left: f32 = runningCount as f32;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use rxing_one_d_proc_derive::OneDWriter;
|
|||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use crate::common::Result;
|
use crate::common::Result;
|
||||||
use crate::BarcodeFormat;
|
use crate::BarcodeFormat;
|
||||||
use crate::oned::telepen_common::TelepenCommon;
|
use crate::oned::TelepenCommon;
|
||||||
|
|
||||||
use super::OneDimensionalCodeWriter;
|
use super::OneDimensionalCodeWriter;
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ impl OneDimensionalCodeWriter for TelepenWriter {
|
|||||||
|
|
||||||
// Content
|
// Content
|
||||||
for c in contents.chars() {
|
for c in contents.chars() {
|
||||||
if c as u8 > 127 {
|
if c as u32 > 127 {
|
||||||
return Err(Exceptions::illegal_argument_with(format!(
|
return Err(Exceptions::illegal_argument_with(format!(
|
||||||
"Telepen only supports ASCII characters."
|
"Telepen only supports ASCII characters."
|
||||||
)));
|
)));
|
||||||
@@ -198,6 +198,12 @@ mod TelepenWriterTestCase {
|
|||||||
|
|
||||||
use super::TelepenWriter;
|
use super::TelepenWriter;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn testAsciiOnly() {
|
||||||
|
encode("АБВГДЕЁЖ");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn testEncode() {
|
fn testEncode() {
|
||||||
doTest(
|
doTest(
|
||||||
|
|||||||
BIN
test_resources/blackbox/telepen-2/01.png
Normal file
BIN
test_resources/blackbox/telepen-2/01.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.9 KiB |
1
test_resources/blackbox/telepen-2/01.txt
Normal file
1
test_resources/blackbox/telepen-2/01.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1234567890
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use rxing::{oned::TelepenReader, BarcodeFormat};
|
use rxing::{oned::TelepenReader, BarcodeFormat, oned::TelepenCommon};
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ mod common;
|
|||||||
* @author Chris Wood
|
* @author Chris Wood
|
||||||
*/
|
*/
|
||||||
#[test]
|
#[test]
|
||||||
fn telepen_black_box1_test_case() {
|
fn telepen_alpha_test_case() {
|
||||||
const NUMTESTS: u32 = 5;
|
const NUMTESTS: u32 = 5;
|
||||||
|
|
||||||
let mut tester = common::AbstractBlackBoxTestCase::new(
|
let mut tester = common::AbstractBlackBoxTestCase::new(
|
||||||
@@ -36,3 +36,46 @@ fn telepen_black_box1_test_case() {
|
|||||||
|
|
||||||
tester.test_black_box();
|
tester.test_black_box();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn telepen_numeric_test_case() {
|
||||||
|
let mut tester = common::AbstractBlackBoxTestCase::new(
|
||||||
|
"test_resources/blackbox/telepen-2",
|
||||||
|
TelepenReader::new(),
|
||||||
|
BarcodeFormat::TELEPEN,
|
||||||
|
);
|
||||||
|
|
||||||
|
tester.add_test_complex(1, 1, 0, 0, 0.0);
|
||||||
|
tester.add_hint(rxing::DecodeHintType::TELEPEN_AS_NUMERIC, rxing::DecodeHintValue::TelepenAsNumeric(true));
|
||||||
|
tester.ignore_pure = true;
|
||||||
|
|
||||||
|
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 ascii = "'=Siu";
|
||||||
|
let result = TelepenCommon::ascii_to_numeric(ascii);
|
||||||
|
assert_eq!("1234567890", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn telepen_numeric_to_ascii_test() {
|
||||||
|
let numeric = "1234567890";
|
||||||
|
let result = TelepenCommon::numeric_to_ascii(numeric).unwrap();
|
||||||
|
assert_eq!("'=Siu", result);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user