From b5d97cf139c6fa708c828dda8ac3f6a5e07d42c8 Mon Sep 17 00:00:00 2001 From: Henry Schimke Date: Thu, 27 Oct 2022 16:06:49 -0500 Subject: [PATCH] x12 port --- src/datamatrix/encoder/X12Encoder.java | 93 ------------------- src/datamatrix/encoder/c40_encoder.rs | 16 ++-- src/datamatrix/encoder/high_level_encoder.rs | 6 +- src/datamatrix/encoder/mod.rs | 5 +- src/datamatrix/encoder/text_encoder.rs | 2 +- src/datamatrix/encoder/x12_encoder.rs | 97 ++++++++++++++++++++ 6 files changed, 114 insertions(+), 105 deletions(-) delete mode 100644 src/datamatrix/encoder/X12Encoder.java create mode 100644 src/datamatrix/encoder/x12_encoder.rs diff --git a/src/datamatrix/encoder/X12Encoder.java b/src/datamatrix/encoder/X12Encoder.java deleted file mode 100644 index 79daf49..0000000 --- a/src/datamatrix/encoder/X12Encoder.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2006-2007 Jeremias Maerki. - * - * 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.datamatrix.encoder; - -final class X12Encoder extends C40Encoder { - - @Override - public int getEncodingMode() { - return HighLevelEncoder.X12_ENCODATION; - } - - @Override - public void encode(EncoderContext context) { - //step C - StringBuilder buffer = new StringBuilder(); - while (context.hasMoreCharacters()) { - char c = context.getCurrentChar(); - context.pos++; - - encodeChar(c, buffer); - - int count = buffer.length(); - if ((count % 3) == 0) { - writeNextTriplet(context, buffer); - - int newMode = HighLevelEncoder.lookAheadTest(context.getMessage(), context.pos, getEncodingMode()); - if (newMode != getEncodingMode()) { - // Return to ASCII encodation, which will actually handle latch to new mode - context.signalEncoderChange(HighLevelEncoder.ASCII_ENCODATION); - break; - } - } - } - handleEOD(context, buffer); - } - - @Override - int encodeChar(char c, StringBuilder sb) { - switch (c) { - case '\r': - sb.append('\0'); - break; - case '*': - sb.append('\1'); - break; - case '>': - sb.append('\2'); - break; - case ' ': - sb.append('\3'); - break; - default: - if (c >= '0' && c <= '9') { - sb.append((char) (c - 48 + 4)); - } else if (c >= 'A' && c <= 'Z') { - sb.append((char) (c - 65 + 14)); - } else { - HighLevelEncoder.illegalCharacter(c); - } - break; - } - return 1; - } - - @Override - void handleEOD(EncoderContext context, StringBuilder buffer) { - context.updateSymbolInfo(); - int available = context.getSymbolInfo().getDataCapacity() - context.getCodewordCount(); - int count = buffer.length(); - context.pos -= count; - if (context.getRemainingCharacters() > 1 || available > 1 || - context.getRemainingCharacters() != available) { - context.writeCodeword(HighLevelEncoder.X12_UNLATCH); - } - if (context.getNewEncoding() < 0) { - context.signalEncoderChange(HighLevelEncoder.ASCII_ENCODATION); - } - } -} diff --git a/src/datamatrix/encoder/c40_encoder.rs b/src/datamatrix/encoder/c40_encoder.rs index 11f8185..edc6d0c 100644 --- a/src/datamatrix/encoder/c40_encoder.rs +++ b/src/datamatrix/encoder/c40_encoder.rs @@ -26,7 +26,7 @@ pub struct C40Encoder; impl Encoder for C40Encoder { fn encode(&self, context: &mut super::EncoderContext) -> Result<(), Exceptions> { - self.encode_with_encode_char_fn(context, &Self::encodeChar_c40) + self.encode_with_encode_char_fn(context, &Self::encodeChar_c40, &Self::handleEOD_c40) } fn getEncodingMode(&self) -> usize { @@ -39,10 +39,11 @@ impl C40Encoder { Self } - pub fn encode_with_encode_char_fn( + pub(super) fn encode_with_encode_char_fn( &self, context: &mut super::EncoderContext, encodeChar: &dyn Fn(char, &mut String) -> u32, + handleEOD : &dyn Fn( &EncoderContext, &mut String) -> Result<(), Exceptions>, ) -> Result<(), Exceptions> { //step C let mut buffer = String::new(); @@ -97,14 +98,15 @@ impl C40Encoder { } } } - self.handleEOD(context, &mut buffer); + handleEOD(context, &mut buffer); Ok(()) } - fn encodeMaximal( + pub fn encodeMaximal( &self, context: &EncoderContext, encodeChar: &dyn Fn(char, &mut String) -> u32, + handleEOD : &dyn Fn( &EncoderContext, &mut String) -> Result<(), Exceptions>, ) { let buffer = String::new(); let lastCharSize = 0; @@ -138,7 +140,7 @@ impl C40Encoder { context.writeCodeword(LATCH_TO_C40); } - self.handleEOD(context, &mut buffer); + handleEOD(context, &mut buffer); } fn backtrackOneCharacter( @@ -159,7 +161,7 @@ impl C40Encoder { return lastCharSize; } - fn writeNextTriplet(context: &EncoderContext, buffer: &mut String) { + pub(super) fn writeNextTriplet(context: &EncoderContext, buffer: &mut String) { context.writeCodewords(&Self::encodeToCodewords(buffer)); buffer.replace_range(0..3, ""); // buffer.delete(0, 3); @@ -171,7 +173,7 @@ impl C40Encoder { * @param context the encoder context * @param buffer the buffer with the remaining encoded characters */ - fn handleEOD(&self, context: &EncoderContext, buffer: &mut String) -> Result<(), Exceptions> { + pub fn handleEOD_c40( context: &EncoderContext, buffer: &mut String) -> Result<(), Exceptions> { let unwritten = (buffer.len() / 3) * 2; let rest = buffer.len() % 3; diff --git a/src/datamatrix/encoder/high_level_encoder.rs b/src/datamatrix/encoder/high_level_encoder.rs index 3586305..9f01832 100644 --- a/src/datamatrix/encoder/high_level_encoder.rs +++ b/src/datamatrix/encoder/high_level_encoder.rs @@ -20,7 +20,7 @@ use encoding::{self, EncodingRef}; use crate::{Dimension, Exceptions}; -use super::{EncoderContext, SymbolShapeHint, C40Encoder, ASCIIEncoder, Encoder, TextEncoder}; +use super::{EncoderContext, SymbolShapeHint, C40Encoder, ASCIIEncoder, Encoder, TextEncoder, X12Encoder}; const DEFAULT_ENCODING: EncodingRef = encoding::all::ISO_8859_1; use unicode_segmentation::UnicodeSegmentation; @@ -179,7 +179,7 @@ pub fn encodeHighLevelWithDimensionForceC40( Rc::new(ASCIIEncoder::new()), c40Encoder.clone(), Rc::new(TextEncoder::new()), - X12Encoder::new(), + Rc::new(X12Encoder::new()), EdifactEncoder::new(), Base256Encoder::new(), ]; @@ -566,7 +566,7 @@ pub fn determineConsecutiveDigitCount(msg: &str, startpos: u32) -> u32 { idx - startpos } -fn illegalCharacter(c: &str) -> Result<(), Exceptions> { +pub fn illegalCharacter(c: char) -> Result<(), Exceptions> { // let hex = Integer.toHexString(c); // hex = "0000".substring(0, 4 - hex.length()) + hex; Err(Exceptions::IllegalArgumentException(format!( diff --git a/src/datamatrix/encoder/mod.rs b/src/datamatrix/encoder/mod.rs index 8316997..7b27035 100644 --- a/src/datamatrix/encoder/mod.rs +++ b/src/datamatrix/encoder/mod.rs @@ -16,4 +16,7 @@ mod ascii_encoder; pub use ascii_encoder::*; mod text_encoder; -pub use text_encoder::*; \ No newline at end of file +pub use text_encoder::*; + +mod x12_encoder; +pub use x12_encoder::*; \ No newline at end of file diff --git a/src/datamatrix/encoder/text_encoder.rs b/src/datamatrix/encoder/text_encoder.rs index 5912a4f..4371f82 100644 --- a/src/datamatrix/encoder/text_encoder.rs +++ b/src/datamatrix/encoder/text_encoder.rs @@ -24,7 +24,7 @@ impl Encoder for TextEncoder { fn encode(&self, context: &mut super::EncoderContext) -> Result<(), crate::Exceptions> { self.0 - .encode_with_encode_char_fn(context, &Self::encodeChar) + .encode_with_encode_char_fn(context, &Self::encodeChar, &C40Encoder::handleEOD_c40) } } impl TextEncoder { diff --git a/src/datamatrix/encoder/x12_encoder.rs b/src/datamatrix/encoder/x12_encoder.rs new file mode 100644 index 0000000..21efbd0 --- /dev/null +++ b/src/datamatrix/encoder/x12_encoder.rs @@ -0,0 +1,97 @@ +/* + * Copyright 2006-2007 Jeremias Maerki. + * + * 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 crate::Exceptions; + +use super::{high_level_encoder, C40Encoder, Encoder, EncoderContext}; + +pub struct X12Encoder(C40Encoder); +impl Encoder for X12Encoder { + fn getEncodingMode(&self) -> usize { + high_level_encoder::X12_ENCODATION + } + + fn encode(&self, context: &mut super::EncoderContext) -> Result<(), crate::Exceptions> { + //step C + let buffer = String::new(); + while context.hasMoreCharacters() { + let c = context.getCurrentChar(); + context.pos += 1; + + Self::encodeChar(c, &mut buffer); + + let count = buffer.len(); + if (count % 3) == 0 { + C40Encoder::writeNextTriplet(context, &mut buffer); + + let newMode = high_level_encoder::lookAheadTest( + context.getMessage(), + context.pos, + self.getEncodingMode() as u32, + ); + if newMode != self.getEncodingMode() { + // Return to ASCII encodation, which will actually handle latch to new mode + context.signalEncoderChange(high_level_encoder::ASCII_ENCODATION); + break; + } + } + } + Self::handleEOD(context, &mut buffer); + Ok(()) + } +} +impl X12Encoder { + pub fn new() -> Self { + Self(C40Encoder::new()) + } + + fn encodeChar(c: char, sb: &mut String) -> u32 { + match c { + '\r' => sb.push('\0'), + '*' => sb.push('\u{1}'), + '>' => sb.push('\u{2}'), + ' ' => sb.push('\u{3}'), + _ => { + if c >= '0' && c <= '9' { + sb.push((c as u8 - 48 + 4) as char); + } else if c >= 'A' && c <= 'Z' { + sb.push((c as u8 - 65 + 14) as char); + } else { + high_level_encoder::illegalCharacter(c); + } + } + } + return 1; + } + + fn handleEOD(context: &EncoderContext, buffer: &mut String) -> Result<(), Exceptions> { + context.updateSymbolInfo(); + let available = + context.getSymbolInfo().unwrap().getDataCapacity() - context.getCodewordCount() as u32; + let count = buffer.len(); + context.pos -= count as u32; + if context.getRemainingCharacters() > 1 + || available > 1 + || context.getRemainingCharacters() != available + { + context.writeCodeword(high_level_encoder::X12_UNLATCH); + } + if context.getNewEncoding().is_none() { + context.signalEncoderChange(high_level_encoder::ASCII_ENCODATION); + } + Ok(()) + } +}