diff --git a/src/oned/Code39Writer.java b/src/oned/Code39Writer.java deleted file mode 100644 index e46fc7c..0000000 --- a/src/oned/Code39Writer.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2010 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.zxing.oned; - -import com.google.zxing.BarcodeFormat; -import com.google.zxing.common.BitMatrix; - -import java.util.Collection; -import java.util.Collections; - -/** - * This object renders a CODE39 code as a {@link BitMatrix}. - * - * @author erik.barbara@gmail.com (Erik Barbara) - */ -public final class Code39Writer extends OneDimensionalCodeWriter { - - @Override - protected Collection getSupportedWriteFormats() { - return Collections.singleton(BarcodeFormat.CODE_39); - } - - @Override - public boolean[] encode(String contents) { - int length = contents.length(); - if (length > 80) { - throw new IllegalArgumentException( - "Requested contents should be less than 80 digits long, but got " + length); - } - - for (int i = 0; i < length; i++) { - int indexInString = Code39Reader.ALPHABET_STRING.indexOf(contents.charAt(i)); - if (indexInString < 0) { - contents = tryToConvertToExtendedMode(contents); - length = contents.length(); - if (length > 80) { - throw new IllegalArgumentException("Requested contents should be less than 80 digits long, but got " + - length + " (extended full ASCII mode)"); - } - break; - } - } - - int[] widths = new int[9]; - int codeWidth = 24 + 1 + (13 * length); - boolean[] result = new boolean[codeWidth]; - toIntArray(Code39Reader.ASTERISK_ENCODING, widths); - int pos = appendPattern(result, 0, widths, true); - int[] narrowWhite = {1}; - pos += appendPattern(result, pos, narrowWhite, false); - //append next character to byte matrix - for (int i = 0; i < length; i++) { - int indexInString = Code39Reader.ALPHABET_STRING.indexOf(contents.charAt(i)); - toIntArray(Code39Reader.CHARACTER_ENCODINGS[indexInString], widths); - pos += appendPattern(result, pos, widths, true); - pos += appendPattern(result, pos, narrowWhite, false); - } - toIntArray(Code39Reader.ASTERISK_ENCODING, widths); - appendPattern(result, pos, widths, true); - return result; - } - - private static void toIntArray(int a, int[] toReturn) { - for (int i = 0; i < 9; i++) { - int temp = a & (1 << (8 - i)); - toReturn[i] = temp == 0 ? 1 : 2; - } - } - - private static String tryToConvertToExtendedMode(String contents) { - int length = contents.length(); - StringBuilder extendedContent = new StringBuilder(); - for (int i = 0; i < length; i++) { - char character = contents.charAt(i); - switch (character) { - case '\u0000': - extendedContent.append("%U"); - break; - case ' ': - case '-': - case '.': - extendedContent.append(character); - break; - case '@': - extendedContent.append("%V"); - break; - case '`': - extendedContent.append("%W"); - break; - default: - if (character <= 26) { - extendedContent.append('$'); - extendedContent.append((char) ('A' + (character - 1))); - } else if (character < ' ') { - extendedContent.append('%'); - extendedContent.append((char) ('A' + (character - 27))); - } else if (character <= ',' || character == '/' || character == ':') { - extendedContent.append('/'); - extendedContent.append((char) ('A' + (character - 33))); - } else if (character <= '9') { - extendedContent.append((char) ('0' + (character - 48))); - } else if (character <= '?') { - extendedContent.append('%'); - extendedContent.append((char) ('F' + (character - 59))); - } else if (character <= 'Z') { - extendedContent.append((char) ('A' + (character - 65))); - } else if (character <= '_') { - extendedContent.append('%'); - extendedContent.append((char) ('K' + (character - 91))); - } else if (character <= 'z') { - extendedContent.append('+'); - extendedContent.append((char) ('A' + (character - 97))); - } else if (character <= 127) { - extendedContent.append('%'); - extendedContent.append((char) ('P' + (character - 123))); - } else { - throw new IllegalArgumentException( - "Requested content contains a non-encodable character: '" + contents.charAt(i) + "'"); - } - break; - } - } - - return extendedContent.toString(); - } - -} diff --git a/src/oned/Code39WriterTestCase.java b/src/oned/Code39WriterTestCase.java deleted file mode 100644 index 669b863..0000000 --- a/src/oned/Code39WriterTestCase.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2016 ZXing authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.zxing.oned; - -import com.google.zxing.BarcodeFormat; -import com.google.zxing.common.BitMatrix; -import com.google.zxing.common.BitMatrixTestCase; -import org.junit.Assert; -import org.junit.Test; - -/** - * Tests {@link Code39Writer}. - */ -public final class Code39WriterTestCase extends Assert { - - @SuppressWarnings("checkstyle:lineLength") - @Test - public void testEncode() { - doTest("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", - "000001001011011010110101001011010110100101101101101001010101011001011011010110010101" + - "011011001010101010011011011010100110101011010011010101011001101011010101001101011010" + - "100110110110101001010101101001101101011010010101101101001010101011001101101010110010" + - "101101011001010101101100101100101010110100110101011011001101010101001011010110110010" + - "110101010011011010101010011011010110100101011010110010101101101100101010101001101011" + - "01101001101010101100110101010100101101101101001011010101100101101010010110110100000"); - - // extended mode blocks - doTest("\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f", - "000001001011011010101001001001011001010101101001001001010110101001011010010010010101" + - "011010010110100100100101011011010010101001001001010101011001011010010010010101101011" + - "001010100100100101010110110010101001001001010101010011011010010010010101101010011010" + - "100100100101010110100110101001001001010101011001101010010010010101101010100110100100" + - "100101010110101001101001001001010110110101001010010010010101010110100110100100100101" + - "011010110100101001001001010101101101001010010010010101010101100110100100100101011010" + - "101100101001001001010101101011001010010010010101010110110010100100100101011001010101" + - "101001001001010100110101011010010010010101100110101010100100100101010010110101101001" + - "001001010110010110101010010010010101001101101010101001001001011010100101101010010010" + - "010101101001011010100100100101101101001010101001001001010101100101101010010010010110" + - "101100101010010110110100000"); - - doTest(" !\"#$%&'()*+,-./0123456789:;<=>?", - "000001001011011010100110101101010010010100101101010010110100100101001010110100101101" + - "001001010010110110100101010010010100101010110010110100100101001011010110010101001001" + - "010010101101100101010010010100101010100110110100100101001011010100110101001001010010" + - "101101001101010010010100101010110011010100100101001011010101001101001001010010101101" + - "010011010010101101101100101011010100100101001011010110100101010011011010110100101011" + - "010110010101101101100101010101001101011011010011010101011001101010101001011011011010" + - "010110101011001011010100100101001010011011010101010010010010101101100101010100100100" + - "101010100110110101001001001011010100110101010010010010101101001101010100100100101010" + - "11001101010010110110100000"); - - doTest("@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_", - "0000010010110110101010010010010100110101011011010100101101011010010110110110100101010" + - "101100101101101011001010101101100101010101001101101101010011010101101001101010101100" + - "110101101010100110101101010011011011010100101010110100110110101101001010110110100101" + - "010101100110110101011001010110101100101010110110010110010101011010011010101101100110" + - "101010100101101011011001011010101001101101010101001001001011010101001101010010010010" + - "101101010011010100100100101101101010010101001001001010101101001101010010010010110101" + - "101001010010110110100000"); - - doTest("`abcdefghijklmnopqrstuvwxyz{|}~", - "000001001011011010101001001001011001101010101001010010010110101001011010010100100101" + - "011010010110100101001001011011010010101001010010010101011001011010010100100101101011" + - "001010100101001001010110110010101001010010010101010011011010010100100101101010011010" + - "100101001001010110100110101001010010010101011001101010010100100101101010100110100101" + - "001001010110101001101001010010010110110101001010010100100101010110100110100101001001" + - "011010110100101001010010010101101101001010010100100101010101100110100101001001011010" + - "101100101001010010010101101011001010010100100101010110110010100101001001011001010101" + - "101001010010010100110101011010010100100101100110101010100101001001010010110101101001" + - "010010010110010110101010010100100101001101101010101001001001010110110100101010010010" + - "010101010110011010100100100101101010110010101001001001010110101100101010010010010101" + - "011011001010010110110100000"); - } - - private static void doTest(String input, CharSequence expected) { - BitMatrix result = new Code39Writer().encode(input, BarcodeFormat.CODE_39, 0, 0); - assertEquals(input, expected, BitMatrixTestCase.matrixToString(result)); - } - -} diff --git a/src/oned/code_39_reader.rs b/src/oned/code_39_reader.rs index 6fc3344..9f8fd06 100644 --- a/src/oned/code_39_reader.rs +++ b/src/oned/code_39_reader.rs @@ -42,7 +42,7 @@ impl OneDReader for Code39Reader { _hints: &DecodingHintDictionary, ) -> Result { // let theCounters = self.counters; - let mut counters = [0_u32;9]; + let mut counters = [0_u32; 9]; // self.counters.fill(0); // let result = self.decodeRowRXingResult; // result.setLength(0); @@ -145,14 +145,14 @@ impl OneDReader for Code39Reader { } } impl Code39Reader { - const ALPHABET_STRING: &str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"; + pub const ALPHABET_STRING: &str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"; /** * These represent the encodings of characters, as patterns of wide and narrow bars. * The 9 least-significant bits of each int correspond to the pattern of wide and narrow, * with 1s representing "wide" and 0s representing narrow. */ - const CHARACTER_ENCODINGS: [u32; 43] = [ + pub const CHARACTER_ENCODINGS: [u32; 43] = [ 0x034, 0x121, 0x061, 0x160, 0x031, 0x130, 0x070, 0x025, 0x124, 0x064, // 0-9 0x109, 0x049, 0x148, 0x019, 0x118, 0x058, 0x00D, 0x10C, 0x04C, 0x01C, // A-J 0x103, 0x043, 0x142, 0x013, 0x112, 0x052, 0x007, 0x106, 0x046, 0x016, // K-T @@ -160,7 +160,7 @@ impl Code39Reader { 0x0A2, 0x08A, 0x02A, // /-% ]; - const ASTERISK_ENCODING: u32 = 0x094; + pub const ASTERISK_ENCODING: u32 = 0x094; /** * Creates a reader that assumes all encoded data is data, and does not treat the final diff --git a/src/oned/code_39_writer.rs b/src/oned/code_39_writer.rs new file mode 100644 index 0000000..cf1e4d7 --- /dev/null +++ b/src/oned/code_39_writer.rs @@ -0,0 +1,256 @@ +/* + * Copyright 2010 ZXing authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use one_d_reader_derive::OneDWriter; + +use crate::BarcodeFormat; + +use super::{Code39Reader, OneDimensionalCodeWriter}; + +/** + * This object renders a CODE39 code as a {@link BitMatrix}. + * + * @author erik.barbara@gmail.com (Erik Barbara) + */ +#[derive(OneDWriter)] +pub struct Code39Writer; + +impl Default for Code39Writer { + fn default() -> Self { + Self {} + } +} + +impl OneDimensionalCodeWriter for Code39Writer { + fn encode_oned(&self, contents: &str) -> Result, Exceptions> { + let mut contents = contents.to_owned(); + let mut length = contents.chars().count(); + if length > 80 { + return Err(Exceptions::IllegalArgumentException(format!( + "Requested contents should be less than 80 digits long, but got {}", + length + ))); + } + + for i in 0..length { + // for (int i = 0; i < length; i++) { + if let None = Code39Reader::ALPHABET_STRING.find(contents.chars().nth(i).unwrap()) { + contents = Self::tryToConvertToExtendedMode(&contents)?; + length = contents.chars().count(); + if length > 80 { + return Err(Exceptions::IllegalArgumentException(format!("Requested contents should be less than 80 digits long, but got {} (extended full ASCII mode)",length))); + } + break; + } + //let indexInString = Code39Reader::ALPHABET_STRING.indexOf(contents.charAt(i)); + // if indexInString < 0 { + // contents = Self::tryToConvertToExtendedMode(&contents); + // length = contents.chars().count(); + // if length > 80 { + // return Err(Exceptions::IllegalArgumentException(format!("Requested contents should be less than 80 digits long, but got {} (extended full ASCII mode)",length))); + // } + // break; + // } + } + + let mut widths = [0_usize; 9]; //new int[9]; + let codeWidth = 24 + 1 + (13 * length); + let mut result = vec![false; codeWidth]; + Self::toIntArray(Code39Reader::ASTERISK_ENCODING, &mut widths); + let mut pos = Self::appendPattern(&mut result, 0, &widths, true); + let narrowWhite = [1_usize]; + pos += Self::appendPattern(&mut result, pos as usize, &narrowWhite, false); + //append next character to byte matrix + for i in 0..length { + // for (int i = 0; i < length; i++) { + let Some(indexInString) = Code39Reader::ALPHABET_STRING.find(contents.chars().nth(i).unwrap()) else { + continue; + }; + // let indexInString = Code39Reader::ALPHABET_STRING.indexOf(contents.charAt(i)); + Self::toIntArray( + Code39Reader::CHARACTER_ENCODINGS[indexInString], + &mut widths, + ); + pos += Self::appendPattern(&mut result, pos as usize, &widths, true); + pos += Self::appendPattern(&mut result, pos as usize, &narrowWhite, false); + } + Self::toIntArray(Code39Reader::ASTERISK_ENCODING, &mut widths); + Self::appendPattern(&mut result, pos as usize, &widths, true); + + Ok(result) + } + + fn getSupportedWriteFormats(&self) -> Option> { + Some(vec![BarcodeFormat::CODE_39]) + } +} +impl Code39Writer { + fn toIntArray(a: u32, toReturn: &mut [usize; 9]) { + for i in 0..9 { + // for (int i = 0; i < 9; i++) { + let temp = a & (1 << (8 - i)); + toReturn[i] = if temp == 0 { 1 } else { 2 }; + } + } + + fn tryToConvertToExtendedMode(contents: &str) -> Result { + // let length = contents.chars().count(); + let mut extendedContent = String::new(); //new StringBuilder(); + for character in contents.chars() { + // for (int i = 0; i < length; i++) { + // char character = contents.charAt(i); + match character { + '\u{0000}' => extendedContent.push_str("%U"), + ' ' | '-' | '.' => extendedContent.push(character), + '@' => extendedContent.push_str("%V"), + + '`' => extendedContent.push_str("%W"), + + _ => { + if (character as u32) <= 26 { + extendedContent.push('$'); + extendedContent + .push(char::from_u32('A' as u32 + (character as u32 - 1)).unwrap()); + } else if character < ' ' { + extendedContent.push('%'); + extendedContent + .push(char::from_u32('A' as u32 + (character as u32 - 27)).unwrap()); + } else if character <= ',' || character == '/' || character == ':' { + extendedContent.push('/'); + extendedContent + .push(char::from_u32('A' as u32 + (character as u32 - 33)).unwrap()); + } else if character <= '9' { + extendedContent + .push(char::from_u32('0' as u32 + (character as u32 - 48)).unwrap()); + } else if character <= '?' { + extendedContent.push('%'); + extendedContent + .push(char::from_u32('F' as u32 + (character as u32 - 59)).unwrap()); + } else if character <= 'Z' { + extendedContent + .push(char::from_u32('A' as u32 + (character as u32 - 65)).unwrap()); + } else if character <= '_' { + extendedContent.push('%'); + extendedContent + .push(char::from_u32('K' as u32 + (character as u32 - 91)).unwrap()); + } else if character <= 'z' { + extendedContent.push('+'); + extendedContent + .push(char::from_u32('A' as u32 + (character as u32 - 97)).unwrap()); + } else if character as u32 <= 127 { + extendedContent.push('%'); + extendedContent + .push(char::from_u32('P' as u32 + (character as u32 - 123)).unwrap()); + } else { + return Err(Exceptions::IllegalArgumentException(format!( + "Requested content contains a non-encodable character: '{}'", + character + ))); + } + } + } + } + + Ok(extendedContent) + } +} + +#[cfg(test)] + +/** + * Tests {@link Code39Writer}. + */ +mod Code39WriterTestCase { + use crate::{common::BitMatrixTestCase, oned::Code39Writer, BarcodeFormat, Writer}; + + #[test] + fn testEncode() { + doTest( + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", + "000001001011011010110101001011010110100101101101101001010101011001011011010110010101\ +011011001010101010011011011010100110101011010011010101011001101011010101001101011010\ +100110110110101001010101101001101101011010010101101101001010101011001101101010110010\ +101101011001010101101100101100101010110100110101011011001101010101001011010110110010\ +110101010011011010101010011011010110100101011010110010101101101100101010101001101011\ +01101001101010101100110101010100101101101101001011010101100101101010010110110100000", + ); + + // extended mode blocks + doTest("\u{0000}\u{0001}\u{0002}\u{0003}\u{0004}\u{0005}\u{0006}\u{0007}\u{008}\t\n\u{000b}\u{000c}\r\u{000e}\u{000f}\u{0010}\u{0011}\u{0012}\u{0013}\u{0014}\u{0015}\u{0016}\u{0017}\u{0018}\u{0019}\u{001a}\u{001b}\u{001c}\u{001d}\u{001e}\u{001f}", + "000001001011011010101001001001011001010101101001001001010110101001011010010010010101\ +011010010110100100100101011011010010101001001001010101011001011010010010010101101011\ +001010100100100101010110110010101001001001010101010011011010010010010101101010011010\ +100100100101010110100110101001001001010101011001101010010010010101101010100110100100\ +100101010110101001101001001001010110110101001010010010010101010110100110100100100101\ +011010110100101001001001010101101101001010010010010101010101100110100100100101011010\ +101100101001001001010101101011001010010010010101010110110010100100100101011001010101\ +101001001001010100110101011010010010010101100110101010100100100101010010110101101001\ +001001010110010110101010010010010101001101101010101001001001011010100101101010010010\ +010101101001011010100100100101101101001010101001001001010101100101101010010010010110\ +101100101010010110110100000"); + + doTest( + " !\"#$%&'()*+,-./0123456789:;<=>?", + "000001001011011010100110101101010010010100101101010010110100100101001010110100101101\ +001001010010110110100101010010010100101010110010110100100101001011010110010101001001\ +010010101101100101010010010100101010100110110100100101001011010100110101001001010010\ +101101001101010010010100101010110011010100100101001011010101001101001001010010101101\ +010011010010101101101100101011010100100101001011010110100101010011011010110100101011\ +010110010101101101100101010101001101011011010011010101011001101010101001011011011010\ +010110101011001011010100100101001010011011010101010010010010101101100101010100100100\ +101010100110110101001001001011010100110101010010010010101101001101010100100100101010\ +11001101010010110110100000", + ); + + doTest( + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_", + "0000010010110110101010010010010100110101011011010100101101011010010110110110100101010\ +101100101101101011001010101101100101010101001101101101010011010101101001101010101100\ +110101101010100110101101010011011011010100101010110100110110101101001010110110100101\ +010101100110110101011001010110101100101010110110010110010101011010011010101101100110\ +101010100101101011011001011010101001101101010101001001001011010101001101010010010010\ +101101010011010100100100101101101010010101001001001010101101001101010010010010110101\ +101001010010110110100000", + ); + + doTest( + "`abcdefghijklmnopqrstuvwxyz{|}~", + "000001001011011010101001001001011001101010101001010010010110101001011010010100100101\ +011010010110100101001001011011010010101001010010010101011001011010010100100101101011\ +001010100101001001010110110010101001010010010101010011011010010100100101101010011010\ +100101001001010110100110101001010010010101011001101010010100100101101010100110100101\ +001001010110101001101001010010010110110101001010010100100101010110100110100101001001\ +011010110100101001010010010101101101001010010100100101010101100110100101001001011010\ +101100101001010010010101101011001010010100100101010110110010100101001001011001010101\ +101001010010010100110101011010010100100101100110101010100101001001010010110101101001\ +010010010110010110101010010100100101001101101010101001001001010110110100101010010010\ +010101010110011010100100100101101010110010101001001001010110101100101010010010010101\ +011011001010010110110100000", + ); + } + + fn doTest(input: &str, expected: &str) { + let result = Code39Writer::default() + .encode(input, &BarcodeFormat::CODE_39, 0, 0) + .expect("must encode"); + assert_eq!( + expected, + BitMatrixTestCase::matrix_to_string(&result), + "{}", + input + ); + } +}