port highlevel, borrow checker not done

This commit is contained in:
Henry Schimke
2022-10-27 17:35:47 -05:00
parent b5d97cf139
commit fb6dfac670
8 changed files with 345 additions and 289 deletions

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}

View File

@@ -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()
}
}
}

View File

@@ -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,

View File

@@ -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<String, Exceptions> {
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)
}
}

View File

@@ -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<Dimension>, maxSize: Option<Dimension>) {
self.minSize = minSize;
self.maxSize = maxSize;
}
pub fn getMessage(&self) -> &str {

View File

@@ -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<String, Exceptions> {
//the codewords 0..255 are encoded as Unicode characters
let c40Encoder = Rc::new(C40Encoder::new());
let encoders:[Rc<dyn Encoder>;6] = [
let encoders: [Rc<dyn Encoder>; 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

View File

@@ -19,4 +19,10 @@ mod text_encoder;
pub use text_encoder::*;
mod x12_encoder;
pub use x12_encoder::*;
pub use x12_encoder::*;
mod edifact_encoder;
pub use edifact_encoder::*;
mod base256_encoder;
pub use base256_encoder::*;