From fb6dfac670cbfab352175d7e497359a79b12b815 Mon Sep 17 00:00:00 2001 From: Henry Schimke Date: Thu, 27 Oct 2022 17:35:47 -0500 Subject: [PATCH] port highlevel, borrow checker not done --- src/datamatrix/encoder/Base256Encoder.java | 75 -------- src/datamatrix/encoder/EdifactEncoder.java | 143 --------------- src/datamatrix/encoder/base256_encoder.rs | 97 ++++++++++ src/datamatrix/encoder/c40_encoder.rs | 6 +- src/datamatrix/encoder/edifact_encoder.rs | 176 +++++++++++++++++++ src/datamatrix/encoder/encoder_context.rs | 6 +- src/datamatrix/encoder/high_level_encoder.rs | 123 ++++++------- src/datamatrix/encoder/mod.rs | 8 +- 8 files changed, 345 insertions(+), 289 deletions(-) delete mode 100644 src/datamatrix/encoder/Base256Encoder.java delete mode 100644 src/datamatrix/encoder/EdifactEncoder.java create mode 100644 src/datamatrix/encoder/base256_encoder.rs create mode 100644 src/datamatrix/encoder/edifact_encoder.rs diff --git a/src/datamatrix/encoder/Base256Encoder.java b/src/datamatrix/encoder/Base256Encoder.java deleted file mode 100644 index a0f91de..0000000 --- a/src/datamatrix/encoder/Base256Encoder.java +++ /dev/null @@ -1,75 +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 Base256Encoder implements Encoder { - - @Override - public int getEncodingMode() { - return HighLevelEncoder.BASE256_ENCODATION; - } - - @Override - public void encode(EncoderContext context) { - StringBuilder buffer = new StringBuilder(); - buffer.append('\0'); //Initialize length field - while (context.hasMoreCharacters()) { - char c = context.getCurrentChar(); - buffer.append(c); - - context.pos++; - - 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; - } - } - int dataCount = buffer.length() - 1; - int lengthFieldSize = 1; - int currentSize = context.getCodewordCount() + dataCount + lengthFieldSize; - context.updateSymbolInfo(currentSize); - boolean mustPad = (context.getSymbolInfo().getDataCapacity() - currentSize) > 0; - if (context.hasMoreCharacters() || mustPad) { - if (dataCount <= 249) { - buffer.setCharAt(0, (char) dataCount); - } else if (dataCount <= 1555) { - buffer.setCharAt(0, (char) ((dataCount / 250) + 249)); - buffer.insert(1, (char) (dataCount % 250)); - } else { - throw new IllegalStateException( - "Message length not in valid ranges: " + dataCount); - } - } - for (int i = 0, c = buffer.length(); i < c; i++) { - context.writeCodeword(randomize255State( - buffer.charAt(i), context.getCodewordCount() + 1)); - } - } - - private static char randomize255State(char ch, int codewordPosition) { - int pseudoRandom = ((149 * codewordPosition) % 255) + 1; - int tempVariable = ch + pseudoRandom; - if (tempVariable <= 255) { - return (char) tempVariable; - } else { - return (char) (tempVariable - 256); - } - } - -} diff --git a/src/datamatrix/encoder/EdifactEncoder.java b/src/datamatrix/encoder/EdifactEncoder.java deleted file mode 100644 index 3eca332..0000000 --- a/src/datamatrix/encoder/EdifactEncoder.java +++ /dev/null @@ -1,143 +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 EdifactEncoder implements Encoder { - - @Override - public int getEncodingMode() { - return HighLevelEncoder.EDIFACT_ENCODATION; - } - - @Override - public void encode(EncoderContext context) { - //step F - StringBuilder buffer = new StringBuilder(); - while (context.hasMoreCharacters()) { - char c = context.getCurrentChar(); - encodeChar(c, buffer); - context.pos++; - - int count = buffer.length(); - if (count >= 4) { - context.writeCodewords(encodeToCodewords(buffer)); - buffer.delete(0, 4); - - 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; - } - } - } - buffer.append((char) 31); //Unlatch - handleEOD(context, buffer); - } - - /** - * Handle "end of data" situations - * - * @param context the encoder context - * @param buffer the buffer with the remaining encoded characters - */ - private static void handleEOD(EncoderContext context, CharSequence buffer) { - try { - int count = buffer.length(); - if (count == 0) { - return; //Already finished - } - if (count == 1) { - //Only an unlatch at the end - context.updateSymbolInfo(); - int available = context.getSymbolInfo().getDataCapacity() - context.getCodewordCount(); - int remaining = context.getRemainingCharacters(); - // The following two lines are a hack inspired by the 'fix' from https://sourceforge.net/p/barcode4j/svn/221/ - if (remaining > available) { - context.updateSymbolInfo(context.getCodewordCount() + 1); - available = context.getSymbolInfo().getDataCapacity() - context.getCodewordCount(); - } - if (remaining <= available && available <= 2) { - return; //No unlatch - } - } - - if (count > 4) { - throw new IllegalStateException("Count must not exceed 4"); - } - int restChars = count - 1; - String encoded = encodeToCodewords(buffer); - boolean endOfSymbolReached = !context.hasMoreCharacters(); - boolean restInAscii = endOfSymbolReached && restChars <= 2; - - if (restChars <= 2) { - context.updateSymbolInfo(context.getCodewordCount() + restChars); - int available = context.getSymbolInfo().getDataCapacity() - context.getCodewordCount(); - if (available >= 3) { - restInAscii = false; - context.updateSymbolInfo(context.getCodewordCount() + encoded.length()); - //available = context.symbolInfo.dataCapacity - context.getCodewordCount(); - } - } - - if (restInAscii) { - context.resetSymbolInfo(); - context.pos -= restChars; - } else { - context.writeCodewords(encoded); - } - } finally { - context.signalEncoderChange(HighLevelEncoder.ASCII_ENCODATION); - } - } - - private static void encodeChar(char c, StringBuilder sb) { - if (c >= ' ' && c <= '?') { - sb.append(c); - } else if (c >= '@' && c <= '^') { - sb.append((char) (c - 64)); - } else { - HighLevelEncoder.illegalCharacter(c); - } - } - - private static String encodeToCodewords(CharSequence sb) { - int len = sb.length(); - if (len == 0) { - throw new IllegalStateException("StringBuilder must not be empty"); - } - char c1 = sb.charAt(0); - char c2 = len >= 2 ? sb.charAt(1) : 0; - char c3 = len >= 3 ? sb.charAt(2) : 0; - char c4 = len >= 4 ? sb.charAt(3) : 0; - - int v = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4; - char cw1 = (char) ((v >> 16) & 255); - char cw2 = (char) ((v >> 8) & 255); - char cw3 = (char) (v & 255); - StringBuilder res = new StringBuilder(3); - res.append(cw1); - if (len >= 2) { - res.append(cw2); - } - if (len >= 3) { - res.append(cw3); - } - return res.toString(); - } - -} diff --git a/src/datamatrix/encoder/base256_encoder.rs b/src/datamatrix/encoder/base256_encoder.rs new file mode 100644 index 0000000..773bd1a --- /dev/null +++ b/src/datamatrix/encoder/base256_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::{self, ASCII_ENCODATION, BASE256_ENCODATION}, + Encoder, +}; + +pub struct Base256Encoder; +impl Encoder for Base256Encoder { + fn getEncodingMode(&self) -> usize { + BASE256_ENCODATION + } + + fn encode(&self, context: &mut super::EncoderContext) -> Result<(), crate::Exceptions> { + let buffer = String::new(); + buffer.push('\0'); //Initialize length field + while context.hasMoreCharacters() { + let c = context.getCurrentChar(); + buffer.push(c); + + context.pos += 1; + + 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(ASCII_ENCODATION); + break; + } + } + let dataCount = buffer.len() - 1; + let lengthFieldSize = 1; + let currentSize = context.getCodewordCount() + dataCount + lengthFieldSize; + context.updateSymbolInfoWithLength(currentSize); + let mustPad = (context.getSymbolInfo().unwrap().getDataCapacity() - currentSize as u32) > 0; + if context.hasMoreCharacters() || mustPad { + if dataCount <= 249 { + buffer.replace_range(0..1, &char::from_u32(dataCount as u32).unwrap().to_string()); + } else if dataCount as u8 <= 1555 { + buffer.replace_range( + 0..1, + &char::from_u32(((dataCount as u32 / 250) + 249)) + .unwrap() + .to_string(), + ); + buffer.insert(1, char::from_u32((dataCount as u32 % 250)).unwrap()); + } else { + return Err(Exceptions::IllegalStateException(format!( + "Message length not in valid ranges: {}", + dataCount + ))); + } + } + let c = buffer.len(); + for i in 0..c { + // for (int i = 0, c = buffer.length(); i < c; i++) { + context.writeCodeword(Self::randomize255State( + buffer.chars().nth(i).unwrap(), + context.getCodewordCount() as u32 + 1, + ) as u8); + } + Ok(()) + } +} +impl Base256Encoder { + pub fn new() -> Self { + Self + } + fn randomize255State(ch: char, codewordPosition: u32) -> char { + let pseudoRandom = ((149 * codewordPosition) % 255) + 1; + let tempVariable = ch as u32 + pseudoRandom; + if tempVariable as u8 <= 255 { + char::from_u32(tempVariable).unwrap() + } else { + char::from_u32((tempVariable - 256)).unwrap() + } + } +} diff --git a/src/datamatrix/encoder/c40_encoder.rs b/src/datamatrix/encoder/c40_encoder.rs index edc6d0c..2a91353 100644 --- a/src/datamatrix/encoder/c40_encoder.rs +++ b/src/datamatrix/encoder/c40_encoder.rs @@ -102,7 +102,11 @@ impl C40Encoder { Ok(()) } - pub fn encodeMaximal( + pub fn encodeMaximalC40(&self, context: &EncoderContext,) { + self.encodeMaximal(context, &Self::encodeChar_c40, &Self::handleEOD_c40) + } + + fn encodeMaximal( &self, context: &EncoderContext, encodeChar: &dyn Fn(char, &mut String) -> u32, diff --git a/src/datamatrix/encoder/edifact_encoder.rs b/src/datamatrix/encoder/edifact_encoder.rs new file mode 100644 index 0000000..4993d88 --- /dev/null +++ b/src/datamatrix/encoder/edifact_encoder.rs @@ -0,0 +1,176 @@ +/* + * 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, Encoder, EncoderContext}; + +pub struct EdifactEncoder; +impl Encoder for EdifactEncoder { + fn getEncodingMode(&self) -> usize { + high_level_encoder::EDIFACT_ENCODATION + } + + fn encode(&self, context: &mut super::EncoderContext) -> Result<(), crate::Exceptions> { + //step F + let buffer = String::new(); + while context.hasMoreCharacters() { + let c = context.getCurrentChar(); + Self::encodeChar(c, &mut buffer); + context.pos += 1; + + let count = buffer.len(); + if count >= 4 { + context.writeCodewords(&Self::encodeToCodewords(&buffer)?); + // buffer.delete(0, 4); + buffer.replace_range(0..4, ""); + + 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; + } + } + } + buffer.push(31 as char); //Unlatch + Self::handleEOD(context, &mut buffer)?; + Ok(()) + } +} +impl EdifactEncoder { + pub fn new() -> Self { + Self + } + /** + * Handle "end of data" situations + * + * @param context the encoder context + * @param buffer the buffer with the remaining encoded characters + */ + fn handleEOD(context: &EncoderContext, buffer: &mut String) -> Result<(), Exceptions> { + let runner = || -> Result<(), Exceptions> { + let count = buffer.len(); + if count == 0 { + return Ok(()); //Already finished + } + if count == 1 { + //Only an unlatch at the end + context.updateSymbolInfo(); + let available = context.getSymbolInfo().unwrap().getDataCapacity() + - context.getCodewordCount() as u32; + let remaining = context.getRemainingCharacters(); + // The following two lines are a hack inspired by the 'fix' from https://sourceforge.net/p/barcode4j/svn/221/ + if remaining > available { + context.updateSymbolInfoWithLength(context.getCodewordCount() + 1); + available = context.getSymbolInfo().unwrap().getDataCapacity() + - context.getCodewordCount() as u32; + } + if remaining <= available && available <= 2 { + return Ok(()); //No unlatch + } + } + + if count > 4 { + return Err(Exceptions::IllegalStateException( + "Count must not exceed 4".to_owned(), + )); + } + let restChars = count - 1; + let encoded = Self::encodeToCodewords(buffer)?; + let endOfSymbolReached = !context.hasMoreCharacters(); + let restInAscii = endOfSymbolReached && restChars <= 2; + + if restChars <= 2 { + context.updateSymbolInfoWithLength(context.getCodewordCount() + restChars); + let available = context.getSymbolInfo().unwrap().getDataCapacity() + - context.getCodewordCount() as u32; + if available >= 3 { + restInAscii = false; + context.updateSymbolInfoWithLength(context.getCodewordCount() + encoded.len()); + //available = context.symbolInfo.dataCapacity - context.getCodewordCount(); + } + } + + if restInAscii { + context.resetSymbolInfo(); + context.pos -= restChars as u32; + } else { + context.writeCodewords(&encoded); + } + Ok(()) + }; + + let res = runner(); + context.signalEncoderChange(high_level_encoder::ASCII_ENCODATION); + + res + } + + fn encodeChar(c: char, sb: &mut String) { + if c >= ' ' && c <= '?' { + sb.push(c); + } else if c >= '@' && c <= '^' { + sb.push((c as u8 - 64) as char); + } else { + high_level_encoder::illegalCharacter(c); + } + } + + fn encodeToCodewords(sb: &str) -> Result { + let len = sb.len(); + if len == 0 { + return Err(Exceptions::IllegalStateException( + "StringBuilder must not be empty".to_owned(), + )); + } + let c1 = sb.chars().nth(0).unwrap(); + let c2 = if len >= 2 { + sb.chars().nth(1).unwrap() + } else { + 0 as char + }; + let c3 = if len >= 3 { + sb.chars().nth(2).unwrap() + } else { + 0 as char + }; + let c4 = if len >= 4 { + sb.chars().nth(3).unwrap() + } else { + 0 as char + }; + + let v: u32 = ((c1 as u32) << 18) + ((c2 as u32) << 12) + ((c3 as u32) << 6) + c4 as u32; + let cw1 = (v as u32 >> 16) & 255; + let cw2 = (v as u32 >> 8) & 255; + let cw3 = v as u32 & 255; + let res = String::with_capacity(3); + res.push(char::from_u32(cw1).unwrap()); + if len >= 2 { + res.push(char::from_u32(cw2).unwrap()); + } + if len >= 3 { + res.push(char::from_u32(cw3).unwrap()); + } + + Ok(res) + } +} diff --git a/src/datamatrix/encoder/encoder_context.rs b/src/datamatrix/encoder/encoder_context.rs index fc9a537..12d42b9 100644 --- a/src/datamatrix/encoder/encoder_context.rs +++ b/src/datamatrix/encoder/encoder_context.rs @@ -78,9 +78,9 @@ impl EncoderContext<'_> { self.shape = shape; } - pub fn setSizeConstraints(&mut self, minSize: Dimension, maxSize: Dimension) { - self.minSize = Some(minSize); - self.maxSize = Some(maxSize); + pub fn setSizeConstraints(&mut self, minSize: Option, maxSize: Option) { + self.minSize = minSize; + self.maxSize = maxSize; } pub fn getMessage(&self) -> &str { diff --git a/src/datamatrix/encoder/high_level_encoder.rs b/src/datamatrix/encoder/high_level_encoder.rs index 9f01832..3165d57 100644 --- a/src/datamatrix/encoder/high_level_encoder.rs +++ b/src/datamatrix/encoder/high_level_encoder.rs @@ -20,7 +20,10 @@ use encoding::{self, EncodingRef}; use crate::{Dimension, Exceptions}; -use super::{EncoderContext, SymbolShapeHint, C40Encoder, ASCIIEncoder, Encoder, TextEncoder, X12Encoder}; +use super::{ + ASCIIEncoder, Base256Encoder, C40Encoder, EdifactEncoder, Encoder, EncoderContext, + SymbolShapeHint, TextEncoder, X12Encoder, +}; const DEFAULT_ENCODING: EncodingRef = encoding::all::ISO_8859_1; use unicode_segmentation::UnicodeSegmentation; @@ -175,83 +178,86 @@ pub fn encodeHighLevelWithDimensionForceC40( ) -> Result { //the codewords 0..255 are encoded as Unicode characters let c40Encoder = Rc::new(C40Encoder::new()); - let encoders:[Rc;6] = [ + let encoders: [Rc; 6] = [ Rc::new(ASCIIEncoder::new()), c40Encoder.clone(), Rc::new(TextEncoder::new()), Rc::new(X12Encoder::new()), - EdifactEncoder::new(), - Base256Encoder::new(), + Rc::new(EdifactEncoder::new()), + Rc::new(Base256Encoder::new()), ]; - let context = EncoderContext::new(msg)?; + let mut context = EncoderContext::new(msg)?; context.setSymbolShape(shape); context.setSizeConstraints(minSize, maxSize); if msg.starts_with(MACRO_05_HEADER) && msg.ends_with(MACRO_TRAILER) { context.writeCodeword(MACRO_05); context.setSkipAtEnd(2); - context.pos += MACRO_05_HEADER.len(); - } else if (msg.starts_with(MACRO_06_HEADER) && msg.ends_with(MACRO_TRAILER)) { + context.pos += MACRO_05_HEADER.len() as u32; + } else if msg.starts_with(MACRO_06_HEADER) && msg.ends_with(MACRO_TRAILER) { context.writeCodeword(MACRO_06); context.setSkipAtEnd(2); - context.pos += MACRO_06_HEADER.len(); + context.pos += MACRO_06_HEADER.len() as u32; } let encodingMode = ASCII_ENCODATION; //Default mode if forceC40 { - c40Encoder.encodeMaximal(context); - encodingMode = context.getNewEncoding(); + c40Encoder.encodeMaximalC40(&mut context); + encodingMode = context.getNewEncoding().unwrap(); context.resetEncoderSignal(); } while context.hasMoreCharacters() { - encoders[encodingMode].encode(context); - if context.getNewEncoding() >= 0 { - encodingMode = context.getNewEncoding(); + encoders[encodingMode].encode(&mut context); + if context.getNewEncoding().is_some() { + encodingMode = context.getNewEncoding().unwrap(); context.resetEncoderSignal(); } } let len = context.getCodewordCount(); context.updateSymbolInfo(); - let capacity = context.getSymbolInfo().getDataCapacity(); - if len < capacity + let capacity = context.getSymbolInfo().unwrap().getDataCapacity(); + if len < capacity as usize && encodingMode != ASCII_ENCODATION && encodingMode != BASE256_ENCODATION && encodingMode != EDIFACT_ENCODATION { - context.writeCodeword("\u{00fe}"); //Unlatch (254) + context.writeCodeword(0xfe); //Unlatch (254) + // context.writeCodeword("\u{00fe}"); //Unlatch (254) } //Padding let codewords = context.getCodewords(); - if codewords.len() < capacity { - codewords.append(PAD); + if codewords.len() < capacity as usize{ + // codewords.push(PAD as char); + context.writeCodeword(PAD) } - while codewords.len() < capacity { - codewords.append(randomize253State(codewords.length() + 1)); + while codewords.len() < capacity as usize { + // codewords.append(randomize253State(codewords.len() + 1)); + context.writeCodewords(&randomize253State(codewords.len() as u32 + 1)) } - return context.getCodewords().toString(); + Ok(context.getCodewords().to_owned()) } pub fn lookAheadTest(msg: &str, startpos: u32, currentMode: u32) -> usize { let newMode = lookAheadTestIntern(msg, startpos, currentMode); if currentMode as usize == X12_ENCODATION && newMode as usize == X12_ENCODATION { - let msg_graphemes = msg.graphemes(true); - let endpos = (startpos + 3).min(msg_graphemes.count() as u32); + // let msg_graphemes = msg.graphemes(true); + let endpos = (startpos + 3).min(msg.chars().count() as u32); for i in startpos..endpos { // for (int i = startpos; i < endpos; i++) { - if !isNativeX12(msg_graphemes.nth(i as usize).unwrap()) { + if !isNativeX12(msg.chars().nth(i as usize).unwrap()) { return ASCII_ENCODATION; } } } else if currentMode as usize == EDIFACT_ENCODATION && newMode == EDIFACT_ENCODATION { - let msg_graphemes = msg.graphemes(true); - let endpos = (startpos + 4).min(msg_graphemes.count() as u32); + // let msg_graphemes = msg.graphemes(true); + let endpos = (startpos + 4).min(msg.chars().count() as u32); for i in startpos..endpos { // for (int i = startpos; i < endpos; i++) { - if !isNativeEDIFACT(msg_graphemes.nth(i as usize).unwrap()) { + if !isNativeEDIFACT(msg.chars().nth(i as usize).unwrap()) { return ASCII_ENCODATION; } } @@ -305,11 +311,12 @@ fn lookAheadTestIntern(msg: &str, startpos: u32, currentMode: u32) -> usize { return C40_ENCODATION; } - let c = msg - .graphemes(true) - .nth((startpos + charsProcessed) as usize) - .unwrap(); + // let c = msg + // .graphemes(true) + // .nth((startpos + charsProcessed) as usize) + // .unwrap(); // let c = msg.charAt(startpos + charsProcessed); + let c = msg.chars().nth((startpos + charsProcessed) as usize).unwrap(); charsProcessed += 1; //step L @@ -442,7 +449,7 @@ fn lookAheadTestIntern(msg: &str, startpos: u32, currentMode: u32) -> usize { } if intCharCounts[C40_ENCODATION] == intCharCounts[X12_ENCODATION] { let p = startpos + charsProcessed + 1; - for tc in msg.graphemes(true) { + for tc in msg.chars() { // while (p as usize) < msg.len() { // let tc = msg.charAt(p); if isX12TermSep(tc) { @@ -503,48 +510,32 @@ pub fn isExtendedASCII(ch: char) -> bool { (ch as u8) >= 128 && (ch as u8) <= 255 } -fn isNativeC40(ch: &str) -> bool { - if ch.len() > 1 { - return false; - } - let cha = ch.chars().nth(0).unwrap(); - (cha == ' ') || (cha >= '0' && cha <= '9') || (cha >= 'A' && cha <= 'Z') +fn isNativeC40(ch: char) -> bool { + (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') } -fn isNativeText(ch: &str) -> bool { - if ch.len() > 1 { - return false; - } - let cha = ch.chars().nth(0).unwrap(); - (cha == ' ') || (cha >= '0' && cha <= '9') || (cha >= 'a' && cha <= 'z') +fn isNativeText(ch: char) -> bool { + (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') } -fn isNativeX12(ch: &str) -> bool { - if ch.len() > 1 { - return false; - } - let cha = ch.chars().nth(0).unwrap(); +fn isNativeX12(ch: char) -> bool { return isX12TermSep(ch) - || (cha == ' ') - || (cha >= '0' && cha <= '9') - || (cha >= 'A' && cha <= 'Z'); + || (ch == ' ') + || (ch >= '0' && ch <= '9') + || (ch >= 'A' && ch <= 'Z'); } -fn isX12TermSep(ch: &str) -> bool { - (ch == "\r") //CR - || (ch == "*") - || (ch == ">") +fn isX12TermSep(ch: char) -> bool { + (ch == '\r') //CR + || (ch == '*') + || (ch == '>') } -fn isNativeEDIFACT(ch: &str) -> bool { - if ch.len() > 1 { - return false; - } - let cha = ch.chars().nth(0).unwrap(); - cha >= ' ' && cha <= '^' +fn isNativeEDIFACT(ch: char) -> bool { + ch >= ' ' && ch <= '^' } -fn isSpecialB256(ch: &str) -> bool { +fn isSpecialB256(ch: char) -> bool { unimplemented!(); return false; //TODO NOT IMPLEMENTED YET!!! } @@ -557,10 +548,10 @@ fn isSpecialB256(ch: &str) -> bool { * @return the requested character count */ pub fn determineConsecutiveDigitCount(msg: &str, startpos: u32) -> u32 { - // let len = msg.len(); + let len = msg.chars().count();//len(); let idx = startpos; - let graphemes = msg.graphemes(true); - while (idx as usize) < graphemes.count() && isDigit(graphemes.nth(idx as usize).unwrap()) { + // let graphemes = msg.graphemes(true); + while (idx as usize) < len && isDigit(msg.chars().nth(idx as usize).unwrap()) { idx += 1; } idx - startpos diff --git a/src/datamatrix/encoder/mod.rs b/src/datamatrix/encoder/mod.rs index 7b27035..7c3465a 100644 --- a/src/datamatrix/encoder/mod.rs +++ b/src/datamatrix/encoder/mod.rs @@ -19,4 +19,10 @@ mod text_encoder; pub use text_encoder::*; mod x12_encoder; -pub use x12_encoder::*; \ No newline at end of file +pub use x12_encoder::*; + +mod edifact_encoder; +pub use edifact_encoder::*; + +mod base256_encoder; +pub use base256_encoder::*; \ No newline at end of file