diff --git a/src/oned/code_128_reader.rs b/src/oned/code_128_reader.rs
index ad0f7e6..1035432 100644
--- a/src/oned/code_128_reader.rs
+++ b/src/oned/code_128_reader.rs
@@ -18,7 +18,7 @@ use one_d_reader_derive::OneDReader;
use crate::{common::BitArray, BarcodeFormat, Exceptions, RXingResult};
-use super::{OneDReader, one_d_reader};
+use super::{one_d_reader, OneDReader};
/**
*
Decodes Code 128 barcodes.
@@ -434,7 +434,8 @@ impl Code128Reader {
for d in 0..CODE_PATTERNS.len() {
// for (int d = 0; d < CODE_PATTERNS.len(); d++) {
let pattern = &CODE_PATTERNS[d];
- let variance = one_d_reader::patternMatchVariance(counters, &pattern, MAX_INDIVIDUAL_VARIANCE);
+ let variance =
+ one_d_reader::patternMatchVariance(counters, &pattern, MAX_INDIVIDUAL_VARIANCE);
if variance < bestVariance {
bestVariance = variance;
bestMatch = d as isize;
diff --git a/src/oned/code_39_reader.rs b/src/oned/code_39_reader.rs
index 85f0115..490f8c4 100644
--- a/src/oned/code_39_reader.rs
+++ b/src/oned/code_39_reader.rs
@@ -19,7 +19,7 @@ use one_d_reader_derive::OneDReader;
use crate::common::BitArray;
use crate::{BarcodeFormat, Exceptions, RXingResult};
-use super::{OneDReader, one_d_reader};
+use super::{one_d_reader, OneDReader};
/**
* Decodes Code 39 barcodes. Supports "Full ASCII Code 39" if USE_CODE_39_EXTENDED_MODE is set.
diff --git a/src/oned/code_93_reader.rs b/src/oned/code_93_reader.rs
index fa98390..60fc3e2 100644
--- a/src/oned/code_93_reader.rs
+++ b/src/oned/code_93_reader.rs
@@ -18,7 +18,7 @@ use one_d_reader_derive::OneDReader;
use crate::{common::BitArray, BarcodeFormat, Exceptions, RXingResult};
-use super::{OneDReader, one_d_reader};
+use super::{one_d_reader, OneDReader};
/**
* Decodes Code 93 barcodes.
diff --git a/src/oned/itf_reader.rs b/src/oned/itf_reader.rs
index c505328..7d283ed 100644
--- a/src/oned/itf_reader.rs
+++ b/src/oned/itf_reader.rs
@@ -18,7 +18,7 @@ use one_d_reader_derive::OneDReader;
use crate::{common::BitArray, BarcodeFormat, DecodeHintValue, Exceptions, RXingResult};
-use super::{OneDReader, one_d_reader};
+use super::{one_d_reader, OneDReader};
const MAX_AVG_VARIANCE: f32 = 0.38;
const MAX_INDIVIDUAL_VARIANCE: f32 = 0.5;
@@ -375,8 +375,11 @@ impl ITFReader {
counters[counterPosition] += 1;
} else {
if counterPosition == patternLength - 1 {
- if one_d_reader::patternMatchVariance(&counters, pattern, MAX_INDIVIDUAL_VARIANCE)
- < MAX_AVG_VARIANCE
+ if one_d_reader::patternMatchVariance(
+ &counters,
+ pattern,
+ MAX_INDIVIDUAL_VARIANCE,
+ ) < MAX_AVG_VARIANCE
{
return Ok([patternStart, x]);
}
@@ -412,7 +415,8 @@ impl ITFReader {
for i in 0..max {
// for (int i = 0; i < max; i++) {
let pattern = &PATTERNS[i];
- let variance = one_d_reader::patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);
+ let variance =
+ one_d_reader::patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);
if variance < bestVariance {
bestVariance = variance;
bestMatch = i as isize;
diff --git a/src/oned/one_d_reader.rs b/src/oned/one_d_reader.rs
index 60af80f..80f43c7 100644
--- a/src/oned/one_d_reader.rs
+++ b/src/oned/one_d_reader.rs
@@ -166,7 +166,6 @@ pub trait OneDReader: Reader {
) -> Result;
}
-
/**
* Determines how closely a set of observed counts of runs of black/white values matches a given
* target pattern. This is reported as the ratio of the total variance from the expected pattern
@@ -177,11 +176,7 @@ pub trait OneDReader: Reader {
* @param maxIndividualVariance The most any counter can differ before we give up
* @return ratio of total variance between counters and pattern compared to total pattern size
*/
-pub fn patternMatchVariance(
- counters: &[u32],
- pattern: &[u32],
- maxIndividualVariance: f32,
-) -> f32 {
+pub fn patternMatchVariance(counters: &[u32], pattern: &[u32], maxIndividualVariance: f32) -> f32 {
let mut maxIndividualVariance = maxIndividualVariance;
let numCounters = counters.len();
let mut total = 0.0;
@@ -218,76 +213,72 @@ pub fn patternMatchVariance(
return totalVariance / total;
}
- /**
- * Records the size of successive runs of white and black pixels in a row, starting at a given point.
- * The values are recorded in the given array, and the number of runs recorded is equal to the size
- * of the array. If the row starts on a white pixel at the given start point, then the first count
- * recorded is the run of white pixels starting from that point; likewise it is the count of a run
- * of black pixels if the row begin on a black pixels at that point.
- *
- * @param row row to count from
- * @param start offset into row to start at
- * @param counters array into which to record counts
- * @throws NotFoundException if counters cannot be filled entirely from row before running out
- * of pixels
- */
- pub fn recordPattern(
- row: &BitArray,
- start: usize,
- counters: &mut [u32],
- ) -> Result<(), Exceptions> {
- let numCounters = counters.len();
- // Arrays.fill(counters, 0, numCounters, 0);
- counters.fill(0);
- let end = row.getSize();
- if start >= end {
- return Err(Exceptions::NotFoundException("".to_owned()));
- }
- let mut isWhite = !row.get(start);
- let mut counterPosition = 0;
- let mut i = start;
- while i < end {
- if row.get(i) != isWhite {
- counters[counterPosition] += 1;
- } else {
- counterPosition += 1;
- if counterPosition == numCounters {
- break;
- } else {
- counters[counterPosition] = 1;
- isWhite = !isWhite;
- }
- }
- i += 1;
- }
- // If we read fully the last section of pixels and filled up our counters -- or filled
- // the last counter but ran off the side of the image, OK. Otherwise, a problem.
- if !(counterPosition == numCounters || (counterPosition == numCounters - 1 && i == end)) {
- return Err(Exceptions::NotFoundException("".to_owned()));
- }
- Ok(())
+/**
+ * Records the size of successive runs of white and black pixels in a row, starting at a given point.
+ * The values are recorded in the given array, and the number of runs recorded is equal to the size
+ * of the array. If the row starts on a white pixel at the given start point, then the first count
+ * recorded is the run of white pixels starting from that point; likewise it is the count of a run
+ * of black pixels if the row begin on a black pixels at that point.
+ *
+ * @param row row to count from
+ * @param start offset into row to start at
+ * @param counters array into which to record counts
+ * @throws NotFoundException if counters cannot be filled entirely from row before running out
+ * of pixels
+ */
+pub fn recordPattern(row: &BitArray, start: usize, counters: &mut [u32]) -> Result<(), Exceptions> {
+ let numCounters = counters.len();
+ // Arrays.fill(counters, 0, numCounters, 0);
+ counters.fill(0);
+ let end = row.getSize();
+ if start >= end {
+ return Err(Exceptions::NotFoundException("".to_owned()));
}
-
- pub fn recordPatternInReverse(
- row: &BitArray,
- start: usize,
- counters: &mut [u32],
- ) -> Result<(), Exceptions> {
- let mut start = start;
- // This could be more efficient I guess
- let mut numTransitionsLeft = counters.len() as isize;
- let mut last = row.get(start);
- while start > 0 && numTransitionsLeft >= 0 {
- start -= 1;
- if row.get(start) != last {
- numTransitionsLeft -= 1;
- last = !last;
+ let mut isWhite = !row.get(start);
+ let mut counterPosition = 0;
+ let mut i = start;
+ while i < end {
+ if row.get(i) != isWhite {
+ counters[counterPosition] += 1;
+ } else {
+ counterPosition += 1;
+ if counterPosition == numCounters {
+ break;
+ } else {
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
}
}
- if numTransitionsLeft >= 0 {
- return Err(Exceptions::NotFoundException("".to_owned()));
- }
- recordPattern(row, start + 1, counters)?;
+ i += 1;
+ }
+ // If we read fully the last section of pixels and filled up our counters -- or filled
+ // the last counter but ran off the side of the image, OK. Otherwise, a problem.
+ if !(counterPosition == numCounters || (counterPosition == numCounters - 1 && i == end)) {
+ return Err(Exceptions::NotFoundException("".to_owned()));
+ }
+ Ok(())
+}
- Ok(())
- }
\ No newline at end of file
+pub fn recordPatternInReverse(
+ row: &BitArray,
+ start: usize,
+ counters: &mut [u32],
+) -> Result<(), Exceptions> {
+ let mut start = start;
+ // This could be more efficient I guess
+ let mut numTransitionsLeft = counters.len() as isize;
+ let mut last = row.get(start);
+ while start > 0 && numTransitionsLeft >= 0 {
+ start -= 1;
+ if row.get(start) != last {
+ numTransitionsLeft -= 1;
+ last = !last;
+ }
+ }
+ if numTransitionsLeft >= 0 {
+ return Err(Exceptions::NotFoundException("".to_owned()));
+ }
+ recordPattern(row, start + 1, counters)?;
+
+ Ok(())
+}
diff --git a/src/oned/rss/abstract_rss_reader.rs b/src/oned/rss/abstract_rss_reader.rs
index 729b7e4..7a0727a 100644
--- a/src/oned/rss/abstract_rss_reader.rs
+++ b/src/oned/rss/abstract_rss_reader.rs
@@ -14,7 +14,10 @@
* limitations under the License.
*/
-use crate::{oned::{OneDReader, one_d_reader}, Exceptions};
+use crate::{
+ oned::{one_d_reader, OneDReader},
+ Exceptions,
+};
/**
* Superclass of {@link OneDReader} implementations that read barcodes in the RSS family
@@ -97,7 +100,7 @@ pub trait AbstractRSSReaderTrait: OneDReader {
array[index] -= 1;
}
- fn isFinderPattern( counters: &[u32]) -> bool {
+ fn isFinderPattern(counters: &[u32]) -> bool {
let firstTwoSum = counters[0] + counters[1];
let sum = firstTwoSum + counters[2] + counters[3];
let ratio: f32 = (firstTwoSum as f32) / (sum as f32);
diff --git a/src/oned/rss/data_character.rs b/src/oned/rss/data_character.rs
index 6d333bc..95a188f 100644
--- a/src/oned/rss/data_character.rs
+++ b/src/oned/rss/data_character.rs
@@ -25,7 +25,7 @@ pub(crate) trait DataCharacterTrait: Display + Eq + PartialEq + Hash {
/**
* Encapsulates a since character value in an RSS barcode, including its checksum information.
*/
-#[derive(Hash, PartialEq, Eq)]
+#[derive(Hash, PartialEq, Eq, Debug)]
pub struct DataCharacter {
value: u32,
checksumPortion: u32,
diff --git a/src/oned/rss/expanded/BinaryUtil.java b/src/oned/rss/expanded/BinaryUtil.java
deleted file mode 100644
index 8e84c38..0000000
--- a/src/oned/rss/expanded/BinaryUtil.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-/*
- * These authors would like to acknowledge the Spanish Ministry of Industry,
- * Tourism and Trade, for the support in the project TSI020301-2008-2
- * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
- * Mobile Dynamic Environments", led by Treelogic
- * ( http://www.treelogic.com/ ):
- *
- * http://www.piramidepse.com/
- */
-
-package com.google.zxing.oned.rss.expanded;
-
-import com.google.zxing.common.BitArray;
-
-import java.util.regex.Pattern;
-
-/**
- * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
- */
-public final class BinaryUtil {
-
- private static final Pattern ONE = Pattern.compile("1");
- private static final Pattern ZERO = Pattern.compile("0");
- private static final Pattern SPACE = Pattern.compile(" ");
-
- private BinaryUtil() {
- }
-
- /*
- * Constructs a BitArray from a String like the one returned from BitArray.toString()
- */
- public static BitArray buildBitArrayFromString(CharSequence data) {
- CharSequence dotsAndXs = ZERO.matcher(ONE.matcher(data).replaceAll("X")).replaceAll(".");
- BitArray binary = new BitArray(SPACE.matcher(dotsAndXs).replaceAll("").length());
- int counter = 0;
-
- for (int i = 0; i < dotsAndXs.length(); ++i) {
- if (i % 9 == 0) { // spaces
- if (dotsAndXs.charAt(i) != ' ') {
- throw new IllegalStateException("space expected");
- }
- continue;
- }
-
- char currentChar = dotsAndXs.charAt(i);
- if (currentChar == 'X' || currentChar == 'x') {
- binary.set(counter);
- }
- counter++;
- }
- return binary;
- }
-
- public static BitArray buildBitArrayFromStringWithoutSpaces(CharSequence data) {
- StringBuilder sb = new StringBuilder();
- CharSequence dotsAndXs = ZERO.matcher(ONE.matcher(data).replaceAll("X")).replaceAll(".");
- int current = 0;
- while (current < dotsAndXs.length()) {
- sb.append(' ');
- for (int i = 0; i < 8 && current < dotsAndXs.length(); ++i) {
- sb.append(dotsAndXs.charAt(current));
- current++;
- }
- }
- return buildBitArrayFromString(sb.toString());
- }
-
-}
diff --git a/src/oned/rss/expanded/BinaryUtilTest.java b/src/oned/rss/expanded/BinaryUtilTest.java
deleted file mode 100644
index f7be304..0000000
--- a/src/oned/rss/expanded/BinaryUtilTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-/*
- * These authors would like to acknowledge the Spanish Ministry of Industry,
- * Tourism and Trade, for the support in the project TSI020301-2008-2
- * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
- * Mobile Dynamic Environments", led by Treelogic
- * ( http://www.treelogic.com/ ):
- *
- * http://www.piramidepse.com/
- */
-
-package com.google.zxing.oned.rss.expanded;
-
-import com.google.zxing.common.BitArray;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.regex.Pattern;
-
-/**
- * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
- */
-public final class BinaryUtilTest extends Assert {
-
- private static final Pattern SPACE = Pattern.compile(" ");
-
- @Test
- public void testBuildBitArrayFromString() {
-
- CharSequence data = " ..X..X.. ..XXX... XXXXXXXX ........";
- check(data);
-
- data = " XXX..X..";
- check(data);
-
- data = " XX";
- check(data);
-
- data = " ....XX.. ..XX";
- check(data);
-
- data = " ....XX.. ..XX..XX ....X.X. ........";
- check(data);
- }
-
- private static void check(CharSequence data) {
- BitArray binary = BinaryUtil.buildBitArrayFromString(data);
- assertEquals(data, binary.toString());
- }
-
- @Test
- public void testBuildBitArrayFromStringWithoutSpaces() {
- CharSequence data = " ..X..X.. ..XXX... XXXXXXXX ........";
- checkWithoutSpaces(data);
-
- data = " XXX..X..";
- checkWithoutSpaces(data);
-
- data = " XX";
- checkWithoutSpaces(data);
-
- data = " ....XX.. ..XX";
- checkWithoutSpaces(data);
-
- data = " ....XX.. ..XX..XX ....X.X. ........";
- checkWithoutSpaces(data);
- }
-
- private static void checkWithoutSpaces(CharSequence data) {
- CharSequence dataWithoutSpaces = SPACE.matcher(data).replaceAll("");
- BitArray binary = BinaryUtil.buildBitArrayFromStringWithoutSpaces(dataWithoutSpaces);
- assertEquals(data, binary.toString());
- }
-}
diff --git a/src/oned/rss/expanded/BitArrayBuilder.java b/src/oned/rss/expanded/BitArrayBuilder.java
deleted file mode 100644
index 293af30..0000000
--- a/src/oned/rss/expanded/BitArrayBuilder.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-/*
- * These authors would like to acknowledge the Spanish Ministry of Industry,
- * Tourism and Trade, for the support in the project TSI020301-2008-2
- * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
- * Mobile Dynamic Environments", led by Treelogic
- * ( http://www.treelogic.com/ ):
- *
- * http://www.piramidepse.com/
- */
-
-package com.google.zxing.oned.rss.expanded;
-
-import com.google.zxing.common.BitArray;
-
-import java.util.List;
-
-/**
- * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
- * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
- */
-final class BitArrayBuilder {
-
- private BitArrayBuilder() {
- }
-
- static BitArray buildBitArray(List pairs) {
- int charNumber = (pairs.size() * 2) - 1;
- if (pairs.get(pairs.size() - 1).getRightChar() == null) {
- charNumber -= 1;
- }
-
- int size = 12 * charNumber;
-
- BitArray binary = new BitArray(size);
- int accPos = 0;
-
- ExpandedPair firstPair = pairs.get(0);
- int firstValue = firstPair.getRightChar().getValue();
- for (int i = 11; i >= 0; --i) {
- if ((firstValue & (1 << i)) != 0) {
- binary.set(accPos);
- }
- accPos++;
- }
-
- for (int i = 1; i < pairs.size(); ++i) {
- ExpandedPair currentPair = pairs.get(i);
-
- int leftValue = currentPair.getLeftChar().getValue();
- for (int j = 11; j >= 0; --j) {
- if ((leftValue & (1 << j)) != 0) {
- binary.set(accPos);
- }
- accPos++;
- }
-
- if (currentPair.getRightChar() != null) {
- int rightValue = currentPair.getRightChar().getValue();
- for (int j = 11; j >= 0; --j) {
- if ((rightValue & (1 << j)) != 0) {
- binary.set(accPos);
- }
- accPos++;
- }
- }
- }
- return binary;
- }
-}
diff --git a/src/oned/rss/expanded/BitArrayBuilderTest.java b/src/oned/rss/expanded/BitArrayBuilderTest.java
deleted file mode 100644
index 609c911..0000000
--- a/src/oned/rss/expanded/BitArrayBuilderTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-/*
- * These authors would like to acknowledge the Spanish Ministry of Industry,
- * Tourism and Trade, for the support in the project TSI020301-2008-2
- * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
- * Mobile Dynamic Environments", led by Treelogic
- * ( http://www.treelogic.com/ ):
- *
- * http://www.piramidepse.com/
- */
-
-package com.google.zxing.oned.rss.expanded;
-
-import com.google.zxing.common.BitArray;
-import com.google.zxing.oned.rss.DataCharacter;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
- * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
- */
-public final class BitArrayBuilderTest extends Assert {
-
- @Test
- public void testBuildBitArray1() {
- int[][] pairValues = {{19}, {673, 16}};
-
- String expected = " .......X ..XX..X. X.X....X .......X ....";
-
- checkBinary(pairValues, expected);
- }
-
- private static void checkBinary(int[][] pairValues, String expected) {
- BitArray binary = buildBitArray(pairValues);
- assertEquals(expected, binary.toString());
- }
-
- private static BitArray buildBitArray(int[][] pairValues) {
- List pairs = new ArrayList<>();
- for (int i = 0; i < pairValues.length; ++i) {
- int [] pair = pairValues[i];
-
- DataCharacter leftChar;
- if (i == 0) {
- leftChar = null;
- } else {
- leftChar = new DataCharacter(pair[0], 0);
- }
-
- DataCharacter rightChar;
- if (i == 0) {
- rightChar = new DataCharacter(pair[0], 0);
- } else if (pair.length == 2) {
- rightChar = new DataCharacter(pair[1], 0);
- } else {
- rightChar = null;
- }
-
- ExpandedPair expandedPair = new ExpandedPair(leftChar, rightChar, null);
- pairs.add(expandedPair);
- }
-
- return BitArrayBuilder.buildBitArray(pairs);
- }
-}
diff --git a/src/oned/rss/expanded/ExpandedPair.java b/src/oned/rss/expanded/ExpandedPair.java
deleted file mode 100644
index e22b5e3..0000000
--- a/src/oned/rss/expanded/ExpandedPair.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-/*
- * These authors would like to acknowledge the Spanish Ministry of Industry,
- * Tourism and Trade, for the support in the project TSI020301-2008-2
- * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
- * Mobile Dynamic Environments", led by Treelogic
- * ( http://www.treelogic.com/ ):
- *
- * http://www.piramidepse.com/
- */
-
-package com.google.zxing.oned.rss.expanded;
-
-import com.google.zxing.oned.rss.DataCharacter;
-import com.google.zxing.oned.rss.FinderPattern;
-
-import java.util.Objects;
-
-/**
- * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
- */
-final class ExpandedPair {
-
- private final DataCharacter leftChar;
- private final DataCharacter rightChar;
- private final FinderPattern finderPattern;
-
- ExpandedPair(DataCharacter leftChar,
- DataCharacter rightChar,
- FinderPattern finderPattern) {
- this.leftChar = leftChar;
- this.rightChar = rightChar;
- this.finderPattern = finderPattern;
- }
-
- DataCharacter getLeftChar() {
- return this.leftChar;
- }
-
- DataCharacter getRightChar() {
- return this.rightChar;
- }
-
- FinderPattern getFinderPattern() {
- return this.finderPattern;
- }
-
- boolean mustBeLast() {
- return this.rightChar == null;
- }
-
- @Override
- public String toString() {
- return
- "[ " + leftChar + " , " + rightChar + " : " +
- (finderPattern == null ? "null" : finderPattern.getValue()) + " ]";
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof ExpandedPair)) {
- return false;
- }
- ExpandedPair that = (ExpandedPair) o;
- return Objects.equals(leftChar, that.leftChar) &&
- Objects.equals(rightChar, that.rightChar) &&
- Objects.equals(finderPattern, that.finderPattern);
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(leftChar) ^ Objects.hashCode(rightChar) ^ Objects.hashCode(finderPattern);
- }
-
-}
diff --git a/src/oned/rss/expanded/binary_util.rs b/src/oned/rss/expanded/binary_util.rs
new file mode 100644
index 0000000..22b49ff
--- /dev/null
+++ b/src/oned/rss/expanded/binary_util.rs
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
+ */
+use lazy_static::lazy_static;
+use regex::Regex;
+
+use crate::{common::BitArray, Exceptions};
+
+lazy_static! {
+ static ref ONE: Regex = Regex::new("1").unwrap();
+ static ref ZERO: Regex = Regex::new("0").unwrap();
+ static ref SPACE: Regex = Regex::new(" ").unwrap();
+}
+
+/*
+ * Constructs a BitArray from a String like the one returned from BitArray.toString()
+ */
+pub fn buildBitArrayFromString(data: &str) -> Result {
+ let dotsAndXs = ZERO
+ .replace_all(&ONE.replace_all(data, "X"), ".")
+ .to_string();
+ let mut binary = BitArray::with_size(SPACE.replace_all(&dotsAndXs, "").chars().count());
+ let mut counter = 0;
+
+ for i in 0..dotsAndXs.chars().count() {
+ // for (int i = 0; i < dotsAndXs.length(); ++i) {
+ if i % 9 == 0 {
+ // spaces
+ if dotsAndXs.chars().nth(i).unwrap() != ' ' {
+ return Err(Exceptions::IllegalStateException(
+ "space expected".to_owned(),
+ ));
+ }
+ continue;
+ }
+
+ let currentChar = dotsAndXs.chars().nth(i).unwrap();
+ if currentChar == 'X' || currentChar == 'x' {
+ binary.set(counter);
+ }
+ counter += 1;
+ }
+ Ok(binary)
+}
+
+pub fn buildBitArrayFromStringWithoutSpaces(data: &str) -> Result {
+ let mut sb = String::new();
+
+ // let dotsAndXs = ZERO.matcher(ONE.matcher(data).replaceAll("X")).replaceAll(".");
+ let dotsAndXs = ZERO
+ .replace_all(&ONE.replace_all(data, "X"), ".")
+ .to_string();
+ let mut current = 0;
+ while current < dotsAndXs.chars().count() {
+ sb.push(' ');
+ let mut i = 0;
+ while i < 8 && current < dotsAndXs.chars().count() {
+ // for (int i = 0; i < 8 && current < dotsAndXs.length(); ++i) {
+ sb.push(dotsAndXs.chars().nth(current).unwrap());
+ current += 1;
+
+ i += 1;
+ }
+ }
+
+ buildBitArrayFromString(&sb)
+}
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
+ */
+#[cfg(test)]
+mod BinaryUtilTest {
+
+ #[test]
+ fn testBuildBitArrayFromString() {
+ let data = " ..X..X.. ..XXX... XXXXXXXX ........";
+ check(data);
+
+ let data = " XXX..X..";
+ check(data);
+
+ let data = " XX";
+ check(data);
+
+ let data = " ....XX.. ..XX";
+ check(data);
+
+ let data = " ....XX.. ..XX..XX ....X.X. ........";
+ check(data);
+ }
+
+ fn check(data: &str) {
+ let binary = super::buildBitArrayFromString(data).expect("check");
+ assert_eq!(data, binary.to_string());
+ }
+
+ #[test]
+ fn testBuildBitArrayFromStringWithoutSpaces() {
+ let data = " ..X..X.. ..XXX... XXXXXXXX ........";
+ checkWithoutSpaces(data);
+
+ let data = " XXX..X..";
+ checkWithoutSpaces(data);
+
+ let data = " XX";
+ checkWithoutSpaces(data);
+
+ let data = " ....XX.. ..XX";
+ checkWithoutSpaces(data);
+
+ let data = " ....XX.. ..XX..XX ....X.X. ........";
+ checkWithoutSpaces(data);
+ }
+
+ fn checkWithoutSpaces(data: &str) {
+ let dataWithoutSpaces = super::SPACE.replace_all(data, "");
+ let binary =
+ super::buildBitArrayFromStringWithoutSpaces(&dataWithoutSpaces).expect("success");
+ assert_eq!(data, binary.to_string());
+ }
+}
diff --git a/src/oned/rss/expanded/bit_array_builder.rs b/src/oned/rss/expanded/bit_array_builder.rs
new file mode 100644
index 0000000..b9a658a
--- /dev/null
+++ b/src/oned/rss/expanded/bit_array_builder.rs
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+use crate::{common::BitArray, oned::rss::DataCharacterTrait};
+
+use super::ExpandedPair;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
+ */
+
+pub fn buildBitArray(pairs: &Vec) -> BitArray {
+ let mut charNumber = (pairs.len() * 2) - 1;
+ if pairs.get(pairs.len() - 1).unwrap().getRightChar().is_none() {
+ charNumber -= 1;
+ }
+
+ let size = 12 * charNumber;
+
+ let mut binary = BitArray::with_size(size);
+ let mut accPos = 0;
+
+ let firstPair = pairs.get(0).unwrap();
+ let Some(rp) = firstPair.getRightChar() else { panic!("first char must exist");};
+ let firstValue = rp.getValue();
+ let mut i = 11;
+ while i >= 0 {
+ // for (int i = 11; i >= 0; --i) {
+ if (firstValue & (1 << i)) != 0 {
+ binary.set(accPos);
+ }
+ accPos += 1;
+
+ i -= 1;
+ }
+
+ for i in 1..pairs.len() {
+ // for (int i = 1; i < pairs.size(); ++i) {
+ let currentPair = pairs.get(i).unwrap();
+ let Some(lv) = currentPair.getLeftChar() else { panic!("I'm not sure how we get here ");};
+ let leftValue = lv.getValue();
+ let mut j = 11;
+ while j >= 0 {
+ // for (int j = 11; j >= 0; --j) {
+ if (leftValue & (1 << j)) != 0 {
+ binary.set(accPos);
+ }
+ accPos += 1;
+
+ j -= 1;
+ }
+
+ if let Some(rc) = currentPair.getRightChar() {
+ let rightValue = rc.getValue(); //currentPair.getRightChar().getValue();
+ let mut j = 11;
+ while j >= 0 {
+ // for (int j = 11; j >= 0; --j) {
+ if (rightValue & (1 << j)) != 0 {
+ binary.set(accPos);
+ }
+ accPos += 1;
+
+ j -= 1;
+ }
+ }
+ }
+ return binary;
+}
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
+ */
+#[cfg(test)]
+mod BitArrayBuilderTest {
+ use crate::{
+ common::BitArray,
+ oned::rss::{expanded::ExpandedPair, DataCharacter},
+ };
+
+ #[test]
+ fn testBuildBitArray1() {
+ let pairValues = vec![vec![19], vec![673, 16]];
+
+ let expected = " .......X ..XX..X. X.X....X .......X ....";
+
+ checkBinary(&pairValues, expected);
+ }
+
+ fn checkBinary(pairValues: &Vec>, expected: &str) {
+ let binary = buildBitArray(pairValues);
+ assert_eq!(expected, binary.to_string());
+ }
+
+ fn buildBitArray(pairValues: &Vec>) -> BitArray {
+ let mut pairs = Vec::new(); //new ArrayList<>();
+ for i in 0..pairValues.len() {
+ // for (int i = 0; i < pairValues.length; ++i) {
+ let pair = &pairValues[i];
+
+ let leftChar = if i == 0 {
+ None
+ } else {
+ Some(DataCharacter::new(pair[0], 0))
+ };
+
+ let rightChar = if i == 0 {
+ Some(DataCharacter::new(pair[0], 0))
+ } else if pair.len() == 2 {
+ Some(DataCharacter::new(pair[1], 0))
+ } else {
+ None
+ };
+
+ let expandedPair = ExpandedPair::new(leftChar, rightChar, None);
+ pairs.push(expandedPair);
+ }
+
+ super::buildBitArray(&pairs)
+ }
+}
diff --git a/src/oned/rss/expanded/decoders/AbstractExpandedDecoder.java b/src/oned/rss/expanded/decoders/AbstractExpandedDecoder.java
deleted file mode 100644
index 771b42b..0000000
--- a/src/oned/rss/expanded/decoders/AbstractExpandedDecoder.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-/*
- * These authors would like to acknowledge the Spanish Ministry of Industry,
- * Tourism and Trade, for the support in the project TSI020301-2008-2
- * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
- * Mobile Dynamic Environments", led by Treelogic
- * ( http://www.treelogic.com/ ):
- *
- * http://www.piramidepse.com/
- */
-
-package com.google.zxing.oned.rss.expanded.decoders;
-
-import com.google.zxing.FormatException;
-import com.google.zxing.NotFoundException;
-import com.google.zxing.common.BitArray;
-
-/**
- * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
- * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
- */
-public abstract class AbstractExpandedDecoder {
-
- private final BitArray information;
- private final GeneralAppIdDecoder generalDecoder;
-
- AbstractExpandedDecoder(BitArray information) {
- this.information = information;
- this.generalDecoder = new GeneralAppIdDecoder(information);
- }
-
- protected final BitArray getInformation() {
- return information;
- }
-
- protected final GeneralAppIdDecoder getGeneralDecoder() {
- return generalDecoder;
- }
-
- public abstract String parseInformation() throws NotFoundException, FormatException;
-
- public static AbstractExpandedDecoder createDecoder(BitArray information) {
- if (information.get(1)) {
- return new AI01AndOtherAIs(information);
- }
- if (!information.get(2)) {
- return new AnyAIDecoder(information);
- }
-
- int fourBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 4);
-
- switch (fourBitEncodationMethod) {
- case 4: return new AI013103decoder(information);
- case 5: return new AI01320xDecoder(information);
- }
-
- int fiveBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 5);
- switch (fiveBitEncodationMethod) {
- case 12: return new AI01392xDecoder(information);
- case 13: return new AI01393xDecoder(information);
- }
-
- int sevenBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 7);
- switch (sevenBitEncodationMethod) {
- case 56: return new AI013x0x1xDecoder(information, "310", "11");
- case 57: return new AI013x0x1xDecoder(information, "320", "11");
- case 58: return new AI013x0x1xDecoder(information, "310", "13");
- case 59: return new AI013x0x1xDecoder(information, "320", "13");
- case 60: return new AI013x0x1xDecoder(information, "310", "15");
- case 61: return new AI013x0x1xDecoder(information, "320", "15");
- case 62: return new AI013x0x1xDecoder(information, "310", "17");
- case 63: return new AI013x0x1xDecoder(information, "320", "17");
- }
-
- throw new IllegalStateException("unknown decoder: " + information);
- }
-
-}
diff --git a/src/oned/rss/expanded/decoders/DecodedInformation.java b/src/oned/rss/expanded/decoders/DecodedInformation.java
deleted file mode 100644
index 0ed90fd..0000000
--- a/src/oned/rss/expanded/decoders/DecodedInformation.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-/*
- * These authors would like to acknowledge the Spanish Ministry of Industry,
- * Tourism and Trade, for the support in the project TSI020301-2008-2
- * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
- * Mobile Dynamic Environments", led by Treelogic
- * ( http://www.treelogic.com/ ):
- *
- * http://www.piramidepse.com/
- */
-
-package com.google.zxing.oned.rss.expanded.decoders;
-
-/**
- * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
- * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
- */
-final class DecodedInformation extends DecodedObject {
-
- private final String newString;
- private final int remainingValue;
- private final boolean remaining;
-
- DecodedInformation(int newPosition, String newString) {
- super(newPosition);
- this.newString = newString;
- this.remaining = false;
- this.remainingValue = 0;
- }
-
- DecodedInformation(int newPosition, String newString, int remainingValue) {
- super(newPosition);
- this.remaining = true;
- this.remainingValue = remainingValue;
- this.newString = newString;
- }
-
- String getNewString() {
- return this.newString;
- }
-
- boolean isRemaining() {
- return this.remaining;
- }
-
- int getRemainingValue() {
- return this.remainingValue;
- }
-}
diff --git a/src/oned/rss/expanded/decoders/FieldParser.java b/src/oned/rss/expanded/decoders/FieldParser.java
deleted file mode 100644
index 13206bc..0000000
--- a/src/oned/rss/expanded/decoders/FieldParser.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-/*
- * These authors would like to acknowledge the Spanish Ministry of Industry,
- * Tourism and Trade, for the support in the project TSI020301-2008-2
- * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
- * Mobile Dynamic Environments", led by Treelogic
- * ( http://www.treelogic.com/ ):
- *
- * http://www.piramidepse.com/
- */
-
-package com.google.zxing.oned.rss.expanded.decoders;
-
-import com.google.zxing.NotFoundException;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
- * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
- */
-final class FieldParser {
-
- private static final Map TWO_DIGIT_DATA_LENGTH = new HashMap<>();
- static {
- TWO_DIGIT_DATA_LENGTH.put("00", DataLength.fixed(18));
- TWO_DIGIT_DATA_LENGTH.put("01", DataLength.fixed(14));
- TWO_DIGIT_DATA_LENGTH.put("02", DataLength.fixed(14));
- TWO_DIGIT_DATA_LENGTH.put("10", DataLength.variable(20));
- TWO_DIGIT_DATA_LENGTH.put("11", DataLength.fixed(6));
- TWO_DIGIT_DATA_LENGTH.put("12", DataLength.fixed(6));
- TWO_DIGIT_DATA_LENGTH.put("13", DataLength.fixed(6));
- TWO_DIGIT_DATA_LENGTH.put("15", DataLength.fixed(6));
- TWO_DIGIT_DATA_LENGTH.put("17", DataLength.fixed(6));
- TWO_DIGIT_DATA_LENGTH.put("20", DataLength.fixed(2));
- TWO_DIGIT_DATA_LENGTH.put("21", DataLength.variable(20));
- TWO_DIGIT_DATA_LENGTH.put("22", DataLength.variable(29));
- TWO_DIGIT_DATA_LENGTH.put("30", DataLength.variable(8));
- TWO_DIGIT_DATA_LENGTH.put("37", DataLength.variable(8));
- //internal company codes
- for (int i = 90; i <= 99; i++) {
- TWO_DIGIT_DATA_LENGTH.put(String.valueOf(i), DataLength.variable(30));
- }
- }
-
- private static final Map THREE_DIGIT_DATA_LENGTH = new HashMap<>();
- static {
- THREE_DIGIT_DATA_LENGTH.put("240", DataLength.variable(30));
- THREE_DIGIT_DATA_LENGTH.put("241", DataLength.variable(30));
- THREE_DIGIT_DATA_LENGTH.put("242", DataLength.variable(6));
- THREE_DIGIT_DATA_LENGTH.put("250", DataLength.variable(30));
- THREE_DIGIT_DATA_LENGTH.put("251", DataLength.variable(30));
- THREE_DIGIT_DATA_LENGTH.put("253", DataLength.variable(17));
- THREE_DIGIT_DATA_LENGTH.put("254", DataLength.variable(20));
- THREE_DIGIT_DATA_LENGTH.put("400", DataLength.variable(30));
- THREE_DIGIT_DATA_LENGTH.put("401", DataLength.variable(30));
- THREE_DIGIT_DATA_LENGTH.put("402", DataLength.fixed(17));
- THREE_DIGIT_DATA_LENGTH.put("403", DataLength.variable(30));
- THREE_DIGIT_DATA_LENGTH.put("410", DataLength.fixed(13));
- THREE_DIGIT_DATA_LENGTH.put("411", DataLength.fixed(13));
- THREE_DIGIT_DATA_LENGTH.put("412", DataLength.fixed(13));
- THREE_DIGIT_DATA_LENGTH.put("413", DataLength.fixed(13));
- THREE_DIGIT_DATA_LENGTH.put("414", DataLength.fixed(13));
- THREE_DIGIT_DATA_LENGTH.put("420", DataLength.variable(20));
- THREE_DIGIT_DATA_LENGTH.put("421", DataLength.variable(15));
- THREE_DIGIT_DATA_LENGTH.put("422", DataLength.fixed(3));
- THREE_DIGIT_DATA_LENGTH.put("423", DataLength.variable(15));
- THREE_DIGIT_DATA_LENGTH.put("424", DataLength.fixed(3));
- THREE_DIGIT_DATA_LENGTH.put("425", DataLength.fixed(3));
- THREE_DIGIT_DATA_LENGTH.put("426", DataLength.fixed(3));
- }
-
- private static final Map THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH = new HashMap<>();
- static {
- for (int i = 310; i <= 316; i++) {
- THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put(String.valueOf(i), DataLength.fixed(6));
- }
- for (int i = 320; i <= 336; i++) {
- THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put(String.valueOf(i), DataLength.fixed(6));
- }
- for (int i = 340; i <= 357; i++) {
- THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put(String.valueOf(i), DataLength.fixed(6));
- }
- for (int i = 360; i <= 369; i++) {
- THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put(String.valueOf(i), DataLength.fixed(6));
- }
- THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put("390", DataLength.variable(15));
- THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put("391", DataLength.variable(18));
- THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put("392", DataLength.variable(15));
- THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put("393", DataLength.variable(18));
- THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.put("703", DataLength.variable(30));
- }
-
- private static final Map FOUR_DIGIT_DATA_LENGTH = new HashMap<>();
- static {
- FOUR_DIGIT_DATA_LENGTH.put("7001", DataLength.fixed(13));
- FOUR_DIGIT_DATA_LENGTH.put("7002", DataLength.variable(30));
- FOUR_DIGIT_DATA_LENGTH.put("7003", DataLength.fixed(10));
- FOUR_DIGIT_DATA_LENGTH.put("8001", DataLength.fixed(14));
- FOUR_DIGIT_DATA_LENGTH.put("8002", DataLength.variable(20));
- FOUR_DIGIT_DATA_LENGTH.put("8003", DataLength.variable(30));
- FOUR_DIGIT_DATA_LENGTH.put("8004", DataLength.variable(30));
- FOUR_DIGIT_DATA_LENGTH.put("8005", DataLength.fixed(6));
- FOUR_DIGIT_DATA_LENGTH.put("8006", DataLength.fixed(18));
- FOUR_DIGIT_DATA_LENGTH.put("8007", DataLength.variable(30));
- FOUR_DIGIT_DATA_LENGTH.put("8008", DataLength.variable(12));
- FOUR_DIGIT_DATA_LENGTH.put("8018", DataLength.fixed(18));
- FOUR_DIGIT_DATA_LENGTH.put("8020", DataLength.variable(25));
- FOUR_DIGIT_DATA_LENGTH.put("8100", DataLength.fixed(6));
- FOUR_DIGIT_DATA_LENGTH.put("8101", DataLength.fixed(10));
- FOUR_DIGIT_DATA_LENGTH.put("8102", DataLength.fixed(2));
- FOUR_DIGIT_DATA_LENGTH.put("8110", DataLength.variable(70));
- FOUR_DIGIT_DATA_LENGTH.put("8200", DataLength.variable(70));
- }
-
- private FieldParser() {
- }
-
- static String parseFieldsInGeneralPurpose(String rawInformation) throws NotFoundException {
- if (rawInformation.isEmpty()) {
- return null;
- }
-
- // Processing 2-digit AIs
-
- if (rawInformation.length() < 2) {
- throw NotFoundException.getNotFoundInstance();
- }
-
- DataLength twoDigitDataLength = TWO_DIGIT_DATA_LENGTH.get(rawInformation.substring(0, 2));
- if (twoDigitDataLength != null) {
- if (twoDigitDataLength.variable) {
- return processVariableAI(2, twoDigitDataLength.length, rawInformation);
- }
- return processFixedAI(2, twoDigitDataLength.length, rawInformation);
- }
-
- if (rawInformation.length() < 3) {
- throw NotFoundException.getNotFoundInstance();
- }
-
- String firstThreeDigits = rawInformation.substring(0, 3);
- DataLength threeDigitDataLength = THREE_DIGIT_DATA_LENGTH.get(firstThreeDigits);
- if (threeDigitDataLength != null) {
- if (threeDigitDataLength.variable) {
- return processVariableAI(3, threeDigitDataLength.length, rawInformation);
- }
- return processFixedAI(3, threeDigitDataLength.length, rawInformation);
- }
-
- if (rawInformation.length() < 4) {
- throw NotFoundException.getNotFoundInstance();
- }
-
- DataLength threeDigitPlusDigitDataLength = THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.get(firstThreeDigits);
- if (threeDigitPlusDigitDataLength != null) {
- if (threeDigitPlusDigitDataLength.variable) {
- return processVariableAI(4, threeDigitPlusDigitDataLength.length, rawInformation);
- }
- return processFixedAI(4, threeDigitPlusDigitDataLength.length, rawInformation);
- }
-
- DataLength firstFourDigitLength = FOUR_DIGIT_DATA_LENGTH.get(rawInformation.substring(0, 4));
- if (firstFourDigitLength != null) {
- if (firstFourDigitLength.variable) {
- return processVariableAI(4, firstFourDigitLength.length, rawInformation);
- }
- return processFixedAI(4, firstFourDigitLength.length, rawInformation);
- }
-
- throw NotFoundException.getNotFoundInstance();
- }
-
- private static String processFixedAI(int aiSize, int fieldSize, String rawInformation) throws NotFoundException {
- if (rawInformation.length() < aiSize) {
- throw NotFoundException.getNotFoundInstance();
- }
-
- String ai = rawInformation.substring(0, aiSize);
-
- if (rawInformation.length() < aiSize + fieldSize) {
- throw NotFoundException.getNotFoundInstance();
- }
-
- String field = rawInformation.substring(aiSize, aiSize + fieldSize);
- String remaining = rawInformation.substring(aiSize + fieldSize);
- String result = '(' + ai + ')' + field;
- String parsedAI = parseFieldsInGeneralPurpose(remaining);
- return parsedAI == null ? result : result + parsedAI;
- }
-
- private static String processVariableAI(int aiSize, int variableFieldSize, String rawInformation)
- throws NotFoundException {
- String ai = rawInformation.substring(0, aiSize);
- int maxSize = Math.min(rawInformation.length(), aiSize + variableFieldSize);
- String field = rawInformation.substring(aiSize, maxSize);
- String remaining = rawInformation.substring(maxSize);
- String result = '(' + ai + ')' + field;
- String parsedAI = parseFieldsInGeneralPurpose(remaining);
- return parsedAI == null ? result : result + parsedAI;
- }
-
- private static final class DataLength {
-
- final boolean variable;
- final int length;
-
- private DataLength(boolean variable, int length) {
- this.variable = variable;
- this.length = length;
- }
-
- static DataLength fixed(int length) {
- return new DataLength(false, length);
- }
-
- static DataLength variable(int length) {
- return new DataLength(true, length);
- }
-
- }
-
-}
diff --git a/src/oned/rss/expanded/decoders/FieldParserTest.java b/src/oned/rss/expanded/decoders/FieldParserTest.java
deleted file mode 100644
index 9a40ceb..0000000
--- a/src/oned/rss/expanded/decoders/FieldParserTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-/*
- * These authors would like to acknowledge the Spanish Ministry of Industry,
- * Tourism and Trade, for the support in the project TSI020301-2008-2
- * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
- * Mobile Dynamic Environments", led by Treelogic
- * ( http://www.treelogic.com/ ):
- *
- * http://www.piramidepse.com/
- */
-
-package com.google.zxing.oned.rss.expanded.decoders;
-
-import com.google.zxing.NotFoundException;
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
- * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
- */
-public final class FieldParserTest extends Assert {
-
- private static void checkFields(String expected) throws NotFoundException {
- String field = expected.replace("(", "").replace(")","");
- String actual = FieldParser.parseFieldsInGeneralPurpose(field);
- assertEquals(expected, actual);
- }
-
- @Test
- public void testParseField() throws Exception {
- checkFields("(15)991231(3103)001750(10)12A");
- }
-
- @Test
- public void testParseField2() throws Exception {
- checkFields("(15)991231(15)991231(3103)001750(10)12A");
- }
-}
diff --git a/src/oned/rss/expanded/decoders/GeneralAppIdDecoder.java b/src/oned/rss/expanded/decoders/GeneralAppIdDecoder.java
deleted file mode 100644
index 477684b..0000000
--- a/src/oned/rss/expanded/decoders/GeneralAppIdDecoder.java
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-/*
- * These authors would like to acknowledge the Spanish Ministry of Industry,
- * Tourism and Trade, for the support in the project TSI020301-2008-2
- * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
- * Mobile Dynamic Environments", led by Treelogic
- * ( http://www.treelogic.com/ ):
- *
- * http://www.piramidepse.com/
- */
-
-package com.google.zxing.oned.rss.expanded.decoders;
-
-import com.google.zxing.FormatException;
-import com.google.zxing.NotFoundException;
-import com.google.zxing.common.BitArray;
-
-/**
- * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
- * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
- */
-final class GeneralAppIdDecoder {
-
- private final BitArray information;
- private final CurrentParsingState current = new CurrentParsingState();
- private final StringBuilder buffer = new StringBuilder();
-
- GeneralAppIdDecoder(BitArray information) {
- this.information = information;
- }
-
- String decodeAllCodes(StringBuilder buff, int initialPosition) throws NotFoundException, FormatException {
- int currentPosition = initialPosition;
- String remaining = null;
- do {
- DecodedInformation info = this.decodeGeneralPurposeField(currentPosition, remaining);
- String parsedFields = FieldParser.parseFieldsInGeneralPurpose(info.getNewString());
- if (parsedFields != null) {
- buff.append(parsedFields);
- }
- if (info.isRemaining()) {
- remaining = String.valueOf(info.getRemainingValue());
- } else {
- remaining = null;
- }
-
- if (currentPosition == info.getNewPosition()) { // No step forward!
- break;
- }
- currentPosition = info.getNewPosition();
- } while (true);
-
- return buff.toString();
- }
-
- private boolean isStillNumeric(int pos) {
- // It's numeric if it still has 7 positions
- // and one of the first 4 bits is "1".
- if (pos + 7 > this.information.getSize()) {
- return pos + 4 <= this.information.getSize();
- }
-
- for (int i = pos; i < pos + 3; ++i) {
- if (this.information.get(i)) {
- return true;
- }
- }
-
- return this.information.get(pos + 3);
- }
-
- private DecodedNumeric decodeNumeric(int pos) throws FormatException {
- if (pos + 7 > this.information.getSize()) {
- int numeric = extractNumericValueFromBitArray(pos, 4);
- if (numeric == 0) {
- return new DecodedNumeric(this.information.getSize(), DecodedNumeric.FNC1, DecodedNumeric.FNC1);
- }
- return new DecodedNumeric(this.information.getSize(), numeric - 1, DecodedNumeric.FNC1);
- }
- int numeric = extractNumericValueFromBitArray(pos, 7);
-
- int digit1 = (numeric - 8) / 11;
- int digit2 = (numeric - 8) % 11;
-
- return new DecodedNumeric(pos + 7, digit1, digit2);
- }
-
- int extractNumericValueFromBitArray(int pos, int bits) {
- return extractNumericValueFromBitArray(this.information, pos, bits);
- }
-
- static int extractNumericValueFromBitArray(BitArray information, int pos, int bits) {
- int value = 0;
- for (int i = 0; i < bits; ++i) {
- if (information.get(pos + i)) {
- value |= 1 << (bits - i - 1);
- }
- }
-
- return value;
- }
-
- DecodedInformation decodeGeneralPurposeField(int pos, String remaining) throws FormatException {
- this.buffer.setLength(0);
-
- if (remaining != null) {
- this.buffer.append(remaining);
- }
-
- this.current.setPosition(pos);
-
- DecodedInformation lastDecoded = parseBlocks();
- if (lastDecoded != null && lastDecoded.isRemaining()) {
- return new DecodedInformation(this.current.getPosition(),
- this.buffer.toString(), lastDecoded.getRemainingValue());
- }
- return new DecodedInformation(this.current.getPosition(), this.buffer.toString());
- }
-
- private DecodedInformation parseBlocks() throws FormatException {
- boolean isFinished;
- BlockParsedRXingResult result;
- do {
- int initialPosition = current.getPosition();
-
- if (current.isAlpha()) {
- result = parseAlphaBlock();
- isFinished = result.isFinished();
- } else if (current.isIsoIec646()) {
- result = parseIsoIec646Block();
- isFinished = result.isFinished();
- } else { // it must be numeric
- result = parseNumericBlock();
- isFinished = result.isFinished();
- }
-
- boolean positionChanged = initialPosition != current.getPosition();
- if (!positionChanged && !isFinished) {
- break;
- }
- } while (!isFinished);
-
- return result.getDecodedInformation();
- }
-
- private BlockParsedRXingResult parseNumericBlock() throws FormatException {
- while (isStillNumeric(current.getPosition())) {
- DecodedNumeric numeric = decodeNumeric(current.getPosition());
- current.setPosition(numeric.getNewPosition());
-
- if (numeric.isFirstDigitFNC1()) {
- DecodedInformation information;
- if (numeric.isSecondDigitFNC1()) {
- information = new DecodedInformation(current.getPosition(), buffer.toString());
- } else {
- information = new DecodedInformation(current.getPosition(), buffer.toString(), numeric.getSecondDigit());
- }
- return new BlockParsedRXingResult(information, true);
- }
- buffer.append(numeric.getFirstDigit());
-
- if (numeric.isSecondDigitFNC1()) {
- DecodedInformation information = new DecodedInformation(current.getPosition(), buffer.toString());
- return new BlockParsedRXingResult(information, true);
- }
- buffer.append(numeric.getSecondDigit());
- }
-
- if (isNumericToAlphaNumericLatch(current.getPosition())) {
- current.setAlpha();
- current.incrementPosition(4);
- }
- return new BlockParsedRXingResult();
- }
-
- private BlockParsedRXingResult parseIsoIec646Block() throws FormatException {
- while (isStillIsoIec646(current.getPosition())) {
- DecodedChar iso = decodeIsoIec646(current.getPosition());
- current.setPosition(iso.getNewPosition());
-
- if (iso.isFNC1()) {
- DecodedInformation information = new DecodedInformation(current.getPosition(), buffer.toString());
- return new BlockParsedRXingResult(information, true);
- }
- buffer.append(iso.getValue());
- }
-
- if (isAlphaOr646ToNumericLatch(current.getPosition())) {
- current.incrementPosition(3);
- current.setNumeric();
- } else if (isAlphaTo646ToAlphaLatch(current.getPosition())) {
- if (current.getPosition() + 5 < this.information.getSize()) {
- current.incrementPosition(5);
- } else {
- current.setPosition(this.information.getSize());
- }
-
- current.setAlpha();
- }
- return new BlockParsedRXingResult();
- }
-
- private BlockParsedRXingResult parseAlphaBlock() {
- while (isStillAlpha(current.getPosition())) {
- DecodedChar alpha = decodeAlphanumeric(current.getPosition());
- current.setPosition(alpha.getNewPosition());
-
- if (alpha.isFNC1()) {
- DecodedInformation information = new DecodedInformation(current.getPosition(), buffer.toString());
- return new BlockParsedRXingResult(information, true); //end of the char block
- }
-
- buffer.append(alpha.getValue());
- }
-
- if (isAlphaOr646ToNumericLatch(current.getPosition())) {
- current.incrementPosition(3);
- current.setNumeric();
- } else if (isAlphaTo646ToAlphaLatch(current.getPosition())) {
- if (current.getPosition() + 5 < this.information.getSize()) {
- current.incrementPosition(5);
- } else {
- current.setPosition(this.information.getSize());
- }
-
- current.setIsoIec646();
- }
- return new BlockParsedRXingResult();
- }
-
- private boolean isStillIsoIec646(int pos) {
- if (pos + 5 > this.information.getSize()) {
- return false;
- }
-
- int fiveBitValue = extractNumericValueFromBitArray(pos, 5);
- if (fiveBitValue >= 5 && fiveBitValue < 16) {
- return true;
- }
-
- if (pos + 7 > this.information.getSize()) {
- return false;
- }
-
- int sevenBitValue = extractNumericValueFromBitArray(pos, 7);
- if (sevenBitValue >= 64 && sevenBitValue < 116) {
- return true;
- }
-
- if (pos + 8 > this.information.getSize()) {
- return false;
- }
-
- int eightBitValue = extractNumericValueFromBitArray(pos, 8);
- return eightBitValue >= 232 && eightBitValue < 253;
-
- }
-
- private DecodedChar decodeIsoIec646(int pos) throws FormatException {
- int fiveBitValue = extractNumericValueFromBitArray(pos, 5);
- if (fiveBitValue == 15) {
- return new DecodedChar(pos + 5, DecodedChar.FNC1);
- }
-
- if (fiveBitValue >= 5 && fiveBitValue < 15) {
- return new DecodedChar(pos + 5, (char) ('0' + fiveBitValue - 5));
- }
-
- int sevenBitValue = extractNumericValueFromBitArray(pos, 7);
-
- if (sevenBitValue >= 64 && sevenBitValue < 90) {
- return new DecodedChar(pos + 7, (char) (sevenBitValue + 1));
- }
-
- if (sevenBitValue >= 90 && sevenBitValue < 116) {
- return new DecodedChar(pos + 7, (char) (sevenBitValue + 7));
- }
-
- int eightBitValue = extractNumericValueFromBitArray(pos, 8);
- char c;
- switch (eightBitValue) {
- case 232:
- c = '!';
- break;
- case 233:
- c = '"';
- break;
- case 234:
- c = '%';
- break;
- case 235:
- c = '&';
- break;
- case 236:
- c = '\'';
- break;
- case 237:
- c = '(';
- break;
- case 238:
- c = ')';
- break;
- case 239:
- c = '*';
- break;
- case 240:
- c = '+';
- break;
- case 241:
- c = ',';
- break;
- case 242:
- c = '-';
- break;
- case 243:
- c = '.';
- break;
- case 244:
- c = '/';
- break;
- case 245:
- c = ':';
- break;
- case 246:
- c = ';';
- break;
- case 247:
- c = '<';
- break;
- case 248:
- c = '=';
- break;
- case 249:
- c = '>';
- break;
- case 250:
- c = '?';
- break;
- case 251:
- c = '_';
- break;
- case 252:
- c = ' ';
- break;
- default:
- throw FormatException.getFormatInstance();
- }
- return new DecodedChar(pos + 8, c);
- }
-
- private boolean isStillAlpha(int pos) {
- if (pos + 5 > this.information.getSize()) {
- return false;
- }
-
- // We now check if it's a valid 5-bit value (0..9 and FNC1)
- int fiveBitValue = extractNumericValueFromBitArray(pos, 5);
- if (fiveBitValue >= 5 && fiveBitValue < 16) {
- return true;
- }
-
- if (pos + 6 > this.information.getSize()) {
- return false;
- }
-
- int sixBitValue = extractNumericValueFromBitArray(pos, 6);
- return sixBitValue >= 16 && sixBitValue < 63; // 63 not included
- }
-
- private DecodedChar decodeAlphanumeric(int pos) {
- int fiveBitValue = extractNumericValueFromBitArray(pos, 5);
- if (fiveBitValue == 15) {
- return new DecodedChar(pos + 5, DecodedChar.FNC1);
- }
-
- if (fiveBitValue >= 5 && fiveBitValue < 15) {
- return new DecodedChar(pos + 5, (char) ('0' + fiveBitValue - 5));
- }
-
- int sixBitValue = extractNumericValueFromBitArray(pos, 6);
-
- if (sixBitValue >= 32 && sixBitValue < 58) {
- return new DecodedChar(pos + 6, (char) (sixBitValue + 33));
- }
-
- char c;
- switch (sixBitValue) {
- case 58:
- c = '*';
- break;
- case 59:
- c = ',';
- break;
- case 60:
- c = '-';
- break;
- case 61:
- c = '.';
- break;
- case 62:
- c = '/';
- break;
- default:
- throw new IllegalStateException("Decoding invalid alphanumeric value: " + sixBitValue);
- }
- return new DecodedChar(pos + 6, c);
- }
-
- private boolean isAlphaTo646ToAlphaLatch(int pos) {
- if (pos + 1 > this.information.getSize()) {
- return false;
- }
-
- for (int i = 0; i < 5 && i + pos < this.information.getSize(); ++i) {
- if (i == 2) {
- if (!this.information.get(pos + 2)) {
- return false;
- }
- } else if (this.information.get(pos + i)) {
- return false;
- }
- }
-
- return true;
- }
-
- private boolean isAlphaOr646ToNumericLatch(int pos) {
- // Next is alphanumeric if there are 3 positions and they are all zeros
- if (pos + 3 > this.information.getSize()) {
- return false;
- }
-
- for (int i = pos; i < pos + 3; ++i) {
- if (this.information.get(i)) {
- return false;
- }
- }
- return true;
- }
-
- private boolean isNumericToAlphaNumericLatch(int pos) {
- // Next is alphanumeric if there are 4 positions and they are all zeros, or
- // if there is a subset of this just before the end of the symbol
- if (pos + 1 > this.information.getSize()) {
- return false;
- }
-
- for (int i = 0; i < 4 && i + pos < this.information.getSize(); ++i) {
- if (this.information.get(pos + i)) {
- return false;
- }
- }
- return true;
- }
-}
diff --git a/src/oned/rss/expanded/decoders/abstract_expanded_decoder.rs b/src/oned/rss/expanded/decoders/abstract_expanded_decoder.rs
new file mode 100644
index 0000000..d531e27
--- /dev/null
+++ b/src/oned/rss/expanded/decoders/abstract_expanded_decoder.rs
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+use crate::{Exceptions, common::BitArray};
+
+use super::GeneralAppIdDecoder;
+
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
+ */
+
+
+pub trait AbstractExpandedDecoder {
+
+ // private final BitArray information;
+ // private final GeneralAppIdDecoder generalDecoder;
+
+ // AbstractExpandedDecoder(BitArray information) {
+ // this.information = information;
+ // this.generalDecoder = new GeneralAppIdDecoder(information);
+ // }
+
+ // protected final BitArray getInformation() {
+ // return information;
+ // }
+
+ // protected final GeneralAppIdDecoder getGeneralDecoder() {
+ // return generalDecoder;
+ // }
+
+ fn parseInformation(&mut self) -> Result;
+ fn getGeneralDecoder(&self) -> &GeneralAppIdDecoder;
+ // fn new(information:&BitArray) -> Self where Self:Sized;
+}
+
+// pub fn createDecoder( information:&BitArray) -> Box{
+// if information.get(1) {
+// return new AI01AndOtherAIs(information);
+// }
+// if !information.get(2) {
+// return new AnyAIDecoder(information);
+// }
+
+// let fourBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 4);
+
+// switch (fourBitEncodationMethod) {
+// case 4: return new AI013103decoder(information);
+// case 5: return new AI01320xDecoder(information);
+// }
+
+// int fiveBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 5);
+// switch (fiveBitEncodationMethod) {
+// case 12: return new AI01392xDecoder(information);
+// case 13: return new AI01393xDecoder(information);
+// }
+
+// int sevenBitEncodationMethod = GeneralAppIdDecoder.extractNumericValueFromBitArray(information, 1, 7);
+// switch (sevenBitEncodationMethod) {
+// case 56: return new AI013x0x1xDecoder(information, "310", "11");
+// case 57: return new AI013x0x1xDecoder(information, "320", "11");
+// case 58: return new AI013x0x1xDecoder(information, "310", "13");
+// case 59: return new AI013x0x1xDecoder(information, "320", "13");
+// case 60: return new AI013x0x1xDecoder(information, "310", "15");
+// case 61: return new AI013x0x1xDecoder(information, "320", "15");
+// case 62: return new AI013x0x1xDecoder(information, "310", "17");
+// case 63: return new AI013x0x1xDecoder(information, "320", "17");
+// }
+
+// throw new IllegalStateException("unknown decoder: " + information);
+// }
\ No newline at end of file
diff --git a/src/oned/rss/expanded/decoders/AI01AndOtherAIs.java b/src/oned/rss/expanded/decoders/ai_01_and_other_ais.rs
similarity index 50%
rename from src/oned/rss/expanded/decoders/AI01AndOtherAIs.java
rename to src/oned/rss/expanded/decoders/ai_01_and_other_ais.rs
index 27222a3..0648009 100644
--- a/src/oned/rss/expanded/decoders/AI01AndOtherAIs.java
+++ b/src/oned/rss/expanded/decoders/ai_01_and_other_ais.rs
@@ -24,35 +24,42 @@
* http://www.piramidepse.com/
*/
-package com.google.zxing.oned.rss.expanded.decoders;
+use crate::common::BitArray;
-import com.google.zxing.FormatException;
-import com.google.zxing.NotFoundException;
-import com.google.zxing.common.BitArray;
+use super::{AI01decoder, AbstractExpandedDecoder, GeneralAppIdDecoder};
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
-final class AI01AndOtherAIs extends AI01decoder {
+pub struct AI01AndOtherAIs<'a>(&'a BitArray,GeneralAppIdDecoder<'a>);
+impl<'a> AI01decoder for AI01AndOtherAIs<'_> {}
+impl AbstractExpandedDecoder for AI01AndOtherAIs<'_> {
+ fn parseInformation(&mut self) -> Result {
+ let mut buff = String::new();//new StringBuilder();
- private static final int HEADER_SIZE = 1 + 1 + 2; //first bit encodes the linkage flag,
- //the second one is the encodation method, and the other two are for the variable length
- AI01AndOtherAIs(BitArray information) {
- super(information);
- }
+ buff.push_str("(01)");
+ let initialGtinPosition = buff.chars().count();
+ let firstGtinDigit = self.getGeneralDecoder().extractNumericValueFromBitArray(Self::HEADER_SIZE, 4);
+ buff.push_str(&firstGtinDigit.to_string());
+
+ self.encodeCompressedGtinWithoutAI(&mut buff, Self::HEADER_SIZE + 4, initialGtinPosition);
+
+ self.1.decodeAllCodes(buff, Self::HEADER_SIZE + 44)
+ }
- @Override
- public String parseInformation() throws NotFoundException, FormatException {
- StringBuilder buff = new StringBuilder();
-
- buff.append("(01)");
- int initialGtinPosition = buff.length();
- int firstGtinDigit = this.getGeneralDecoder().extractNumericValueFromBitArray(HEADER_SIZE, 4);
- buff.append(firstGtinDigit);
-
- this.encodeCompressedGtinWithoutAI(buff, HEADER_SIZE + 4, initialGtinPosition);
-
- return this.getGeneralDecoder().decodeAllCodes(buff, HEADER_SIZE + 44);
- }
+ fn getGeneralDecoder(&self) -> &super::GeneralAppIdDecoder {
+ &self.1
+ }
+}
+impl<'a> AI01AndOtherAIs<'_> {
+ fn new(information:&'a BitArray) -> AI01AndOtherAIs<'a> {
+ AI01AndOtherAIs( information,GeneralAppIdDecoder::new(information))
+}
+
+ const HEADER_SIZE : usize = 1 + 1 + 2; //first bit encodes the linkage flag,
+ //the second one is the encodation method, and the other two are for the variable length
+ // AI01AndOtherAIs(BitArray information) {
+ // super(information);
+ // }
}
diff --git a/src/oned/rss/expanded/decoders/AI01decoder.java b/src/oned/rss/expanded/decoders/ai_01_decoder.rs
similarity index 50%
rename from src/oned/rss/expanded/decoders/AI01decoder.java
rename to src/oned/rss/expanded/decoders/ai_01_decoder.rs
index 0034500..4e9e52e 100644
--- a/src/oned/rss/expanded/decoders/AI01decoder.java
+++ b/src/oned/rss/expanded/decoders/ai_01_decoder.rs
@@ -24,58 +24,57 @@
* http://www.piramidepse.com/
*/
-package com.google.zxing.oned.rss.expanded.decoders;
+use super::AbstractExpandedDecoder;
-import com.google.zxing.common.BitArray;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
-abstract class AI01decoder extends AbstractExpandedDecoder {
+pub trait AI01decoder : AbstractExpandedDecoder {
- static final int GTIN_SIZE = 40;
+ const GTIN_SIZE : u32 = 40;
- AI01decoder(BitArray information) {
- super(information);
+ fn encodeCompressedGtin(&self, buf:&mut String, currentPos:usize) {
+ buf.push_str("(01)");
+ let initialPosition = buf.chars().count();
+ buf.push('9');
+
+ self.encodeCompressedGtinWithoutAI(buf, currentPos, initialPosition);
}
- final void encodeCompressedGtin(StringBuilder buf, int currentPos) {
- buf.append("(01)");
- int initialPosition = buf.length();
- buf.append('9');
-
- encodeCompressedGtinWithoutAI(buf, currentPos, initialPosition);
- }
-
- final void encodeCompressedGtinWithoutAI(StringBuilder buf, int currentPos, int initialBufferPosition) {
- for (int i = 0; i < 4; ++i) {
- int currentBlock = this.getGeneralDecoder().extractNumericValueFromBitArray(currentPos + 10 * i, 10);
- if (currentBlock / 100 == 0) {
- buf.append('0');
+ fn encodeCompressedGtinWithoutAI(&self, buf:&mut String, currentPos:usize, initialBufferPosition:usize) {
+ for i in 0..4 {
+ // for (int i = 0; i < 4; ++i) {
+ let currentBlock = self.getGeneralDecoder().extractNumericValueFromBitArray(currentPos + 10 * i, 10);
+ if currentBlock / 100 == 0 {
+ buf.push('0');
}
- if (currentBlock / 10 == 0) {
- buf.append('0');
+ if currentBlock / 10 == 0 {
+ buf.push('0');
}
- buf.append(currentBlock);
+ buf.push_str(¤tBlock.to_string());
}
appendCheckDigit(buf, initialBufferPosition);
}
- private static void appendCheckDigit(StringBuilder buf, int currentPos) {
- int checkDigit = 0;
- for (int i = 0; i < 13; i++) {
- int digit = buf.charAt(i + currentPos) - '0';
- checkDigit += (i & 0x01) == 0 ? 3 * digit : digit;
- }
-
- checkDigit = 10 - (checkDigit % 10);
- if (checkDigit == 10) {
- checkDigit = 0;
- }
-
- buf.append(checkDigit);
- }
+
}
+
+pub(super) fn appendCheckDigit( buf:&mut String, currentPos:usize) {
+ let mut checkDigit = 0;
+ for i in 0..13 {
+ // for (int i = 0; i < 13; i++) {
+ let digit = buf.chars().nth(i + currentPos).unwrap() as u32 - '0' as u32;
+ checkDigit += if (i & 0x01) == 0 {3 * digit} else {digit};
+ }
+
+ checkDigit = 10 - (checkDigit % 10);
+ if checkDigit == 10 {
+ checkDigit = 0;
+ }
+
+ buf.push_str(&checkDigit.to_string());
+}
\ No newline at end of file
diff --git a/src/oned/rss/expanded/decoders/BlockParsedResult.java b/src/oned/rss/expanded/decoders/block_parsed_result.rs
similarity index 64%
rename from src/oned/rss/expanded/decoders/BlockParsedResult.java
rename to src/oned/rss/expanded/decoders/block_parsed_result.rs
index c6744ac..f0fd4b9 100644
--- a/src/oned/rss/expanded/decoders/BlockParsedResult.java
+++ b/src/oned/rss/expanded/decoders/block_parsed_result.rs
@@ -24,31 +24,33 @@
* http://www.piramidepse.com/
*/
-package com.google.zxing.oned.rss.expanded.decoders;
+use super::DecodedInformation;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
-final class BlockParsedRXingResult {
-
- private final DecodedInformation decodedInformation;
- private final boolean finished;
-
- BlockParsedRXingResult() {
- this(null, false);
- }
-
- BlockParsedRXingResult(DecodedInformation information, boolean finished) {
- this.finished = finished;
- this.decodedInformation = information;
- }
-
- DecodedInformation getDecodedInformation() {
- return this.decodedInformation;
- }
-
- boolean isFinished() {
- return this.finished;
- }
+pub struct BlockParsedRXingResult {
+ decodedInformation: Option,
+ finished: bool,
+}
+impl BlockParsedRXingResult {
+ pub fn new() -> Self {
+ Self::with_information(None, false)
+ }
+
+ pub fn with_information(information: Option, finished: bool) -> Self {
+ Self {
+ decodedInformation: information,
+ finished,
+ }
+ }
+
+ pub fn getDecodedInformation(&self) -> &Option {
+ &self.decodedInformation
+ }
+
+ pub fn isFinished(&self) -> bool {
+ self.finished
+ }
}
diff --git a/src/oned/rss/expanded/decoders/CurrentParsingState.java b/src/oned/rss/expanded/decoders/current_parsing_state.rs
similarity index 50%
rename from src/oned/rss/expanded/decoders/CurrentParsingState.java
rename to src/oned/rss/expanded/decoders/current_parsing_state.rs
index 34e92e1..9f0e236 100644
--- a/src/oned/rss/expanded/decoders/CurrentParsingState.java
+++ b/src/oned/rss/expanded/decoders/current_parsing_state.rs
@@ -23,61 +23,62 @@
*
* http://www.piramidepse.com/
*/
-
-package com.google.zxing.oned.rss.expanded.decoders;
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+enum State {
+ NUMERIC,
+ ALPHA,
+ ISO_IEC_646,
+}
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
*/
-final class CurrentParsingState {
-
- private int position;
- private State encoding;
-
- private enum State {
- NUMERIC,
- ALPHA,
- ISO_IEC_646
- }
-
- CurrentParsingState() {
- this.position = 0;
- this.encoding = State.NUMERIC;
- }
-
- int getPosition() {
- return position;
- }
-
- void setPosition(int position) {
- this.position = position;
- }
-
- void incrementPosition(int delta) {
- position += delta;
- }
-
- boolean isAlpha() {
- return this.encoding == State.ALPHA;
- }
-
- boolean isNumeric() {
- return this.encoding == State.NUMERIC;
- }
-
- boolean isIsoIec646() {
- return this.encoding == State.ISO_IEC_646;
- }
-
- void setNumeric() {
- this.encoding = State.NUMERIC;
- }
-
- void setAlpha() {
- this.encoding = State.ALPHA;
- }
-
- void setIsoIec646() {
- this.encoding = State.ISO_IEC_646;
- }
+pub struct CurrentParsingState {
+ position: usize,
+ encoding: State,
+}
+
+impl CurrentParsingState {
+ pub fn new() -> Self {
+ Self {
+ position: 0,
+ encoding: State::NUMERIC,
+ }
+ }
+
+ pub fn getPosition(&self) -> usize {
+ self.position
+ }
+
+ pub fn setPosition(&mut self, position: usize) {
+ self.position = position
+ }
+
+ pub fn incrementPosition(&mut self, delta: usize) {
+ self.position += delta;
+ }
+
+ pub fn isAlpha(&self) -> bool {
+ self.encoding == State::ALPHA
+ }
+
+ pub fn isNumeric(&self) -> bool {
+ self.encoding == State::NUMERIC
+ }
+
+ pub fn isIsoIec646(&self) -> bool {
+ self.encoding == State::ISO_IEC_646
+ }
+
+ pub fn setNumeric(&mut self) {
+ self.encoding = State::NUMERIC;
+ }
+
+ pub fn setAlpha(&mut self) {
+ self.encoding = State::ALPHA;
+ }
+
+ pub fn setIsoIec646(&mut self) {
+ self.encoding = State::ISO_IEC_646;
+ }
}
diff --git a/src/oned/rss/expanded/decoders/DecodedChar.java b/src/oned/rss/expanded/decoders/decoded_char.rs
similarity index 68%
rename from src/oned/rss/expanded/decoders/DecodedChar.java
rename to src/oned/rss/expanded/decoders/decoded_char.rs
index 2dd8995..6f730ff 100644
--- a/src/oned/rss/expanded/decoders/DecodedChar.java
+++ b/src/oned/rss/expanded/decoders/decoded_char.rs
@@ -24,29 +24,33 @@
* http://www.piramidepse.com/
*/
-package com.google.zxing.oned.rss.expanded.decoders;
+use super::DecodedObject;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
-final class DecodedChar extends DecodedObject {
-
- private final char value;
-
- static final char FNC1 = '$'; // It's not in Alphanumeric neither in ISO/IEC 646 charset
-
- DecodedChar(int newPosition, char value) {
- super(newPosition);
- this.value = value;
- }
-
- char getValue() {
- return this.value;
- }
-
- boolean isFNC1() {
- return this.value == FNC1;
- }
-
+pub struct DecodedChar {
+ value: char,
+ newPosition: usize,
+}
+impl DecodedObject for DecodedChar {
+ fn getNewPosition(&self) -> usize {
+ self.newPosition
+ }
+}
+impl DecodedChar {
+ pub const FNC1: char = '$'; // It's not in Alphanumeric neither in ISO/IEC 646 charset
+
+ pub fn new(newPosition: usize, value: char) -> Self {
+ Self { value, newPosition }
+ }
+
+ pub fn getValue(&self) -> char {
+ self.value
+ }
+
+ pub fn isFNC1(&self) -> bool {
+ self.value == Self::FNC1
+ }
}
diff --git a/src/oned/rss/expanded/decoders/DecodedNumeric.java b/src/oned/rss/expanded/decoders/decoded_information.rs
similarity index 53%
rename from src/oned/rss/expanded/decoders/DecodedNumeric.java
rename to src/oned/rss/expanded/decoders/decoded_information.rs
index 7b8f25a..5b48dce 100644
--- a/src/oned/rss/expanded/decoders/DecodedNumeric.java
+++ b/src/oned/rss/expanded/decoders/decoded_information.rs
@@ -24,50 +24,57 @@
* http://www.piramidepse.com/
*/
-package com.google.zxing.oned.rss.expanded.decoders;
-
-import com.google.zxing.FormatException;
+use super::DecodedObject;
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
* @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
*/
-final class DecodedNumeric extends DecodedObject {
+#[derive(Clone)]
+pub struct DecodedInformation {
+ newPosition: usize,
+ newString: String,
+ remainingValue: u32,
+ remaining: bool,
+}
- private final int firstDigit;
- private final int secondDigit;
-
- static final int FNC1 = 10;
-
- DecodedNumeric(int newPosition, int firstDigit, int secondDigit) throws FormatException {
- super(newPosition);
-
- if (firstDigit < 0 || firstDigit > 10 || secondDigit < 0 || secondDigit > 10) {
- throw FormatException.getFormatInstance();
+impl DecodedObject for DecodedInformation {
+ fn getNewPosition(&self) -> usize {
+ self.newPosition
+ }
+}
+impl DecodedInformation {
+ pub fn new(newPosition: usize, newString: String) -> Self {
+ Self {
+ newPosition,
+ newString,
+ remainingValue: 0,
+ remaining: false,
+ }
}
- this.firstDigit = firstDigit;
- this.secondDigit = secondDigit;
- }
+ pub fn with_remaining_value(
+ newPosition: usize,
+ newString: String,
+ remainingValue: u32,
+ ) -> Self {
+ Self {
+ newPosition,
+ newString,
+ remainingValue,
+ remaining: true,
+ }
+ }
- int getFirstDigit() {
- return this.firstDigit;
- }
+ pub fn getNewString(&self) -> &str {
+ &self.newString
+ }
- int getSecondDigit() {
- return this.secondDigit;
- }
-
- int getValue() {
- return this.firstDigit * 10 + this.secondDigit;
- }
-
- boolean isFirstDigitFNC1() {
- return this.firstDigit == FNC1;
- }
-
- boolean isSecondDigitFNC1() {
- return this.secondDigit == FNC1;
- }
+ pub fn isRemaining(&self) -> bool {
+ self.remaining
+ }
+ pub fn getRemainingValue(&self) -> u32 {
+ self.remainingValue
+ }
}
diff --git a/src/oned/rss/expanded/decoders/decoded_numeric.rs b/src/oned/rss/expanded/decoders/decoded_numeric.rs
new file mode 100644
index 0000000..1e2e993
--- /dev/null
+++ b/src/oned/rss/expanded/decoders/decoded_numeric.rs
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+use crate::Exceptions;
+
+use super::DecodedObject;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
+ */
+pub struct DecodedNumeric {
+ newPosition: usize,
+ firstDigit: u32,
+ secondDigit: u32,
+}
+impl DecodedObject for DecodedNumeric {
+ fn getNewPosition(&self) -> usize {
+ self.newPosition
+ }
+}
+impl DecodedNumeric {
+ pub const FNC1: u32 = 10;
+
+ pub fn new(newPosition: usize, firstDigit: u32, secondDigit: u32) -> Result {
+ // super(newPosition);
+
+ if firstDigit < 0 || firstDigit > 10 || secondDigit < 0 || secondDigit > 10 {
+ return Err(Exceptions::FormatException(
+ ".getFormatInstance();".to_owned(),
+ ));
+ }
+
+ Ok(Self {
+ newPosition,
+ firstDigit,
+ secondDigit,
+ })
+ }
+
+ pub fn getFirstDigit(&self) -> u32 {
+ self.firstDigit
+ }
+
+ pub fn getSecondDigit(&self) -> u32 {
+ self.secondDigit
+ }
+
+ pub fn getValue(&self) -> u32 {
+ self.firstDigit * 10 + self.secondDigit
+ }
+
+ pub fn isFirstDigitFNC1(&self) -> bool {
+ self.firstDigit == Self::FNC1
+ }
+
+ pub fn isSecondDigitFNC1(&self) -> bool {
+ self.secondDigit == Self::FNC1
+ }
+}
diff --git a/src/oned/rss/expanded/decoders/DecodedObject.java b/src/oned/rss/expanded/decoders/decoded_object.rs
similarity index 80%
rename from src/oned/rss/expanded/decoders/DecodedObject.java
rename to src/oned/rss/expanded/decoders/decoded_object.rs
index cf7d7da..15816f7 100644
--- a/src/oned/rss/expanded/decoders/DecodedObject.java
+++ b/src/oned/rss/expanded/decoders/decoded_object.rs
@@ -24,21 +24,13 @@
* http://www.piramidepse.com/
*/
-package com.google.zxing.oned.rss.expanded.decoders;
+
/**
* @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
*/
-abstract class DecodedObject {
+pub trait DecodedObject {
- private final int newPosition;
-
- DecodedObject(int newPosition) {
- this.newPosition = newPosition;
- }
-
- final int getNewPosition() {
- return this.newPosition;
- }
+ fn getNewPosition(&self) -> usize;
}
diff --git a/src/oned/rss/expanded/decoders/field_parser.rs b/src/oned/rss/expanded/decoders/field_parser.rs
new file mode 100644
index 0000000..ae67977
--- /dev/null
+++ b/src/oned/rss/expanded/decoders/field_parser.rs
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+use std::collections::HashMap;
+
+use crate::Exceptions;
+
+use lazy_static::lazy_static;
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
+ */
+
+lazy_static! {
+
+ static ref TWO_DIGIT_DATA_LENGTH : HashMap = {
+ let mut hm = HashMap::new();
+ hm.insert("00".to_owned(), DataLength::fixed(18));
+ hm.insert("01".to_owned(), DataLength::fixed(14));
+ hm.insert("02".to_owned(), DataLength::fixed(14));
+ hm.insert("10".to_owned(), DataLength::variable(20));
+ hm.insert("11".to_owned(), DataLength::fixed(6));
+ hm.insert("12".to_owned(), DataLength::fixed(6));
+ hm.insert("13".to_owned(), DataLength::fixed(6));
+ hm.insert("15".to_owned(), DataLength::fixed(6));
+ hm.insert("17".to_owned(), DataLength::fixed(6));
+ hm.insert("20".to_owned(), DataLength::fixed(2));
+ hm.insert("21".to_owned(), DataLength::variable(20));
+ hm.insert("22".to_owned(), DataLength::variable(29));
+ hm.insert("30".to_owned(), DataLength::variable(8));
+ hm.insert("37".to_owned(), DataLength::variable(8));
+ //internal company codes
+ for i in 90..=99 {
+ // for (int i = 90; i <= 99; i++) {
+ hm.insert(i.to_string(), DataLength::variable(30));
+ }
+ hm
+ };
+
+ static ref THREE_DIGIT_DATA_LENGTH : HashMap=
+ {
+ let mut hm = HashMap::new();
+ hm.insert("240".to_owned(), DataLength::variable(30));
+ hm.insert("241".to_owned(), DataLength::variable(30));
+ hm.insert("242".to_owned(), DataLength::variable(6));
+ hm.insert("250".to_owned(), DataLength::variable(30));
+ hm.insert("251".to_owned(), DataLength::variable(30));
+ hm.insert("253".to_owned(), DataLength::variable(17));
+ hm.insert("254".to_owned(), DataLength::variable(20));
+ hm.insert("400".to_owned(), DataLength::variable(30));
+ hm.insert("401".to_owned(), DataLength::variable(30));
+ hm.insert("402".to_owned(), DataLength::fixed(17));
+ hm.insert("403".to_owned(), DataLength::variable(30));
+ hm.insert("410".to_owned(), DataLength::fixed(13));
+ hm.insert("411".to_owned(), DataLength::fixed(13));
+ hm.insert("412".to_owned(), DataLength::fixed(13));
+ hm.insert("413".to_owned(), DataLength::fixed(13));
+ hm.insert("414".to_owned(), DataLength::fixed(13));
+ hm.insert("420".to_owned(), DataLength::variable(20));
+ hm.insert("421".to_owned(), DataLength::variable(15));
+ hm.insert("422".to_owned(), DataLength::fixed(3));
+ hm.insert("423".to_owned(), DataLength::variable(15));
+ hm.insert("424".to_owned(), DataLength::fixed(3));
+ hm.insert("425".to_owned(), DataLength::fixed(3));
+ hm.insert("426".to_owned(), DataLength::fixed(3));
+
+ hm
+ };
+
+ static ref THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH:HashMap = {
+ let mut hm = HashMap::new();
+ for i in 310..=316 {
+ // for (int i = 310; i <= 316; i++) {
+ hm.insert(i.to_string(), DataLength::fixed(6));
+ }
+ for i in 320..=336 {
+ // for (int i = 320; i <= 336; i++) {
+ hm.insert(i.to_string(), DataLength::fixed(6));
+ }
+ for i in 340..=357 {
+ // for (int i = 340; i <= 357; i++) {
+ hm.insert(i.to_string(), DataLength::fixed(6));
+ }
+ for i in 360..=369 {
+ // for (int i = 360; i <= 369; i++) {
+ hm.insert(i.to_string(), DataLength::fixed(6));
+ }
+ hm.insert("390".to_owned(), DataLength::variable(15));
+ hm.insert("391".to_owned(), DataLength::variable(18));
+ hm.insert("392".to_owned(), DataLength::variable(15));
+ hm.insert("393".to_owned(), DataLength::variable(18));
+ hm.insert("703".to_owned(), DataLength::variable(30));
+
+ hm
+ };
+
+ static ref FOUR_DIGIT_DATA_LENGTH : HashMap={
+ let mut hm = HashMap::new();
+ hm.insert("7001".to_owned(), DataLength::fixed(13));
+ hm.insert("7002".to_owned(), DataLength::variable(30));
+ hm.insert("7003".to_owned(), DataLength::fixed(10));
+ hm.insert("8001".to_owned(), DataLength::fixed(14));
+ hm.insert("8002".to_owned(), DataLength::variable(20));
+ hm.insert("8003".to_owned(), DataLength::variable(30));
+ hm.insert("8004".to_owned(), DataLength::variable(30));
+ hm.insert("8005".to_owned(), DataLength::fixed(6));
+ hm.insert("8006".to_owned(), DataLength::fixed(18));
+ hm.insert("8007".to_owned(), DataLength::variable(30));
+ hm.insert("8008".to_owned(), DataLength::variable(12));
+ hm.insert("8018".to_owned(), DataLength::fixed(18));
+ hm.insert("8020".to_owned(), DataLength::variable(25));
+ hm.insert("8100".to_owned(), DataLength::fixed(6));
+ hm.insert("8101".to_owned(), DataLength::fixed(10));
+ hm.insert("8102".to_owned(), DataLength::fixed(2));
+ hm.insert("8110".to_owned(), DataLength::variable(70));
+ hm.insert("8200".to_owned(), DataLength::variable(70));
+
+ hm
+ };
+}
+
+pub fn parseFieldsInGeneralPurpose(rawInformation: &str) -> Result {
+ if rawInformation.is_empty() {
+ return Ok("".to_owned());
+ }
+
+ // Processing 2-digit AIs
+
+ if rawInformation.chars().count() < 2 {
+ return Err(Exceptions::NotFoundException("".to_owned()));
+ }
+
+ let lookup: String = rawInformation.chars().take(2).collect();
+ let twoDigitDataLength = TWO_DIGIT_DATA_LENGTH.get(&lookup);
+ if let Some(tddl) = twoDigitDataLength {
+ if tddl.variable {
+ return processVariableAI(2, tddl.length, rawInformation);
+ }
+ return processFixedAI(2, tddl.length, rawInformation);
+ }
+
+ if rawInformation.chars().count() < 3 {
+ return Err(Exceptions::NotFoundException("".to_owned()));
+ }
+
+ let firstThreeDigits: String = rawInformation.chars().take(3).collect(); //rawInformation.substring(0, 3);
+ let threeDigitDataLength = THREE_DIGIT_DATA_LENGTH.get(&firstThreeDigits);
+ if let Some(tddl) = threeDigitDataLength {
+ if tddl.variable {
+ return processVariableAI(3, tddl.length, rawInformation);
+ }
+ return processFixedAI(3, tddl.length, rawInformation);
+ }
+
+ if rawInformation.chars().count() < 4 {
+ return Err(Exceptions::NotFoundException("".to_owned()));
+ }
+
+ let threeDigitPlusDigitDataLength = THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH.get(&firstThreeDigits);
+ if let Some(tdpddl) = threeDigitPlusDigitDataLength {
+ if tdpddl.variable {
+ return processVariableAI(4, tdpddl.length, rawInformation);
+ }
+ return processFixedAI(4, tdpddl.length, rawInformation);
+ }
+
+ let lookup: String = rawInformation.chars().take(4).collect();
+ let firstFourDigitLength = FOUR_DIGIT_DATA_LENGTH.get(&lookup /*(0, 4)*/);
+ if let Some(ffdl) = firstFourDigitLength {
+ if ffdl.variable {
+ return processVariableAI(4, ffdl.length, rawInformation);
+ }
+ return processFixedAI(4, ffdl.length, rawInformation);
+ }
+
+ return Err(Exceptions::NotFoundException("".to_owned()));
+}
+
+fn processFixedAI(
+ aiSize: usize,
+ fieldSize: usize,
+ rawInformation: &str,
+) -> Result {
+ if rawInformation.chars().count() < aiSize {
+ return Err(Exceptions::NotFoundException("".to_owned()));
+ }
+
+ let ai: String = rawInformation.chars().take(aiSize).collect();
+
+ if rawInformation.chars().count() < aiSize + fieldSize {
+ return Err(Exceptions::NotFoundException("".to_owned()));
+ }
+
+ let field: String = rawInformation
+ .chars()
+ .skip(aiSize)
+ .take(fieldSize)
+ .collect(); //rawInformation.substring(aiSize, aiSize + fieldSize);
+ let remaining: String = rawInformation.chars().skip(aiSize + fieldSize).collect(); // rawInformation.substring(aiSize + fieldSize);
+ let result = format!("({}){}", ai, field);
+ let parsedAI = parseFieldsInGeneralPurpose(&remaining)?;
+
+ Ok(if parsedAI.is_empty() {
+ result
+ } else {
+ format!("{}{}", result, parsedAI)
+ })
+}
+
+fn processVariableAI(
+ aiSize: usize,
+ variableFieldSize: usize,
+ rawInformation: &str,
+) -> Result {
+ let ai: String = rawInformation.chars().take(aiSize as usize).collect(); //rawInformation.substring(0, aiSize);
+ let maxSize = rawInformation
+ .chars()
+ .count()
+ .min(aiSize + variableFieldSize);
+ let field: String = rawInformation
+ .chars()
+ .skip(aiSize as usize)
+ .take(maxSize)
+ .collect(); // (aiSize, maxSize);
+ let remaining: String = rawInformation.chars().skip(maxSize).collect();
+ let result = format!("({}){}", ai, field); //'(' + ai + ')' + field;
+ let parsedAI = parseFieldsInGeneralPurpose(&remaining)?;
+
+ Ok(if parsedAI.is_empty() {
+ result
+ } else {
+ format!("{}{}", result, parsedAI)
+ })
+}
+
+struct DataLength {
+ pub variable: bool,
+ pub length: usize,
+}
+impl DataLength {
+ // fn new( variable:bool, length:u32) -> Self{
+ // Self(variable,length)
+ // }
+
+ pub fn fixed(length: usize) -> Self {
+ Self {
+ variable: false,
+ length,
+ }
+ }
+
+ pub fn variable(length: usize) -> Self {
+ Self {
+ variable: true,
+ length,
+ }
+ }
+}
+
+
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
+ */
+#[cfg(test)]
+ mod FieldParserTest {
+
+ fn checkFields( expected:&str) {
+ let field = expected.replace("(", "").replace(")","");
+ let actual = super::parseFieldsInGeneralPurpose(&field).expect("parse");
+ assert_eq!(expected, actual);
+ }
+
+ #[test]
+ fn testParseField() {
+ checkFields("(15)991231(3103)001750(10)12A");
+ }
+
+ #[test]
+ fn testParseField2() {
+ checkFields("(15)991231(15)991231(3103)001750(10)12A");
+ }
+}
diff --git a/src/oned/rss/expanded/decoders/general_app_id_decoder.rs b/src/oned/rss/expanded/decoders/general_app_id_decoder.rs
new file mode 100644
index 0000000..c1af427
--- /dev/null
+++ b/src/oned/rss/expanded/decoders/general_app_id_decoder.rs
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+use crate::{common::BitArray, Exceptions};
+
+use super::{CurrentParsingState, DecodedChar, DecodedNumeric, DecodedInformation, BlockParsedRXingResult, DecodedObject, field_parser};
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
+ * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es)
+ */
+pub struct GeneralAppIdDecoder<'a> {
+
+ information:&'a BitArray,
+ current : CurrentParsingState, //= new CurrentParsingState();
+ buffer :String, //= new StringBuilder();
+}
+
+impl<'a> GeneralAppIdDecoder<'_> {
+ pub fn new( information:&'a BitArray) -> GeneralAppIdDecoder<'a>{
+ GeneralAppIdDecoder{
+ information,
+ current: CurrentParsingState::new(),
+ buffer: String::new(),
+ }
+ }
+
+ pub fn decodeAllCodes(&mut self, buff:String, initialPosition:usize) -> Result {
+ let mut buff = buff;
+ let mut currentPosition = initialPosition;
+ let mut remaining = "".to_owned();
+ loop {
+ let info = self.decodeGeneralPurposeField(currentPosition, &remaining)?;
+ let parsedFields =field_parser::parseFieldsInGeneralPurpose(info.getNewString())?;
+ if !parsedFields.is_empty() {
+ buff.push_str(&parsedFields);
+ }
+ if info.isRemaining() {
+ remaining = info.getRemainingValue().to_string();
+ } else {
+ remaining = "".to_owned();
+ }
+
+ if currentPosition == info.getNewPosition() { // No step forward!
+ break;
+ }
+ currentPosition = info.getNewPosition();
+ }
+
+ Ok(buff)
+ }
+
+ fn isStillNumeric(&self, pos:usize) -> bool{
+ // It's numeric if it still has 7 positions
+ // and one of the first 4 bits is "1".
+ if pos + 7 > self.information.getSize() {
+ return pos + 4 <= self.information.getSize();
+ }
+
+ for i in pos..pos+3 {
+ // for (int i = pos; i < pos + 3; ++i) {
+ if self.information.get(i) {
+ return true;
+ }
+ }
+
+ self.information.get(pos + 3)
+ }
+
+ fn decodeNumeric(&self, pos:usize) -> Result {
+ if pos + 7 > self.information.getSize() {
+ let numeric = self.extractNumericValueFromBitArray(pos, 4);
+ if numeric == 0 {
+ return DecodedNumeric::new(self.information.getSize(), DecodedNumeric::FNC1, DecodedNumeric::FNC1);
+ }
+ return DecodedNumeric::new(self.information.getSize(), numeric - 1, DecodedNumeric::FNC1);
+ }
+ let numeric = self.extractNumericValueFromBitArray(pos, 7);
+
+ let digit1 = (numeric - 8) / 11;
+ let digit2 = (numeric - 8) % 11;
+
+ DecodedNumeric::new(pos + 7, digit1, digit2)
+ }
+
+ pub fn extractNumericValueFromBitArray(&self, pos:usize, bits:u32) -> u32{
+ Self::extractNumericValueFromBitArrayWithInformation(&self.information, pos, bits)
+ }
+
+ pub fn extractNumericValueFromBitArrayWithInformation( information:&BitArray, pos:usize, bits:u32) ->u32{
+ let mut value = 0;
+ for i in 0..bits {
+ // for (int i = 0; i < bits; ++i) {
+ if information.get(pos + i as usize) {
+ value |= 1 << (bits - i - 1);
+ }
+ }
+
+ value
+ }
+
+ pub fn decodeGeneralPurposeField(&mut self, pos:usize, remaining:&str) -> Result {
+ self.buffer.clear();
+
+ if !remaining.is_empty() {
+ self.buffer.push_str(remaining);
+ }
+
+ self.current.setPosition(pos);
+
+ if let Ok(lastDecoded) = self.parseBlocks(){
+ if lastDecoded.isRemaining() {
+ return Ok(DecodedInformation::with_remaining_value(self.current.getPosition(),
+ self.buffer.clone(), lastDecoded.getRemainingValue()));
+ }}
+ Ok(DecodedInformation::new(self.current.getPosition(), self.buffer.clone()))
+ }
+
+ fn parseBlocks(&mut self) -> Result {
+ let mut isFinished;
+ let mut result:BlockParsedRXingResult;
+ loop {
+ let initialPosition = self.current.getPosition();
+
+ if self.current.isAlpha() {
+ result =self. parseAlphaBlock()?;
+ isFinished = result.isFinished();
+ } else if self.current.isIsoIec646() {
+ result = self.parseIsoIec646Block()?;
+ isFinished = result.isFinished();
+ } else { // it must be numeric
+ result = self.parseNumericBlock()?;
+ isFinished = result.isFinished();
+ }
+
+ let positionChanged = initialPosition != self.current.getPosition();
+ if !positionChanged && !isFinished {
+ break;
+ }
+
+ if !(!isFinished) { break; }
+ } //while (!isFinished);
+
+ Ok(result.getDecodedInformation().as_ref().unwrap().clone())
+ }
+
+ fn parseNumericBlock(&mut self) -> Result {
+ while self.isStillNumeric(self.current.getPosition()) {
+ let numeric = self.decodeNumeric(self.current.getPosition())?;
+ self.current.setPosition(numeric.getNewPosition());
+
+ if numeric.isFirstDigitFNC1() {
+ let information=
+ if numeric.isSecondDigitFNC1() {
+ DecodedInformation::new(self.current.getPosition(), self.buffer.clone())
+ } else {
+ DecodedInformation::with_remaining_value(self.current.getPosition(), self.buffer.clone(), numeric.getSecondDigit())
+ };
+ return Ok(BlockParsedRXingResult::with_information(Some(information), true));
+ }
+ self.buffer.push_str(&numeric.getFirstDigit().to_string());
+
+ if numeric.isSecondDigitFNC1() {
+ let information = DecodedInformation::new(self.current.getPosition(), self.buffer.clone());
+ return Ok(BlockParsedRXingResult::with_information(Some(information), true));
+ }
+ self.buffer.push_str(&numeric.getSecondDigit().to_string());
+ }
+
+ if self.isNumericToAlphaNumericLatch(self.current.getPosition()) {
+ self.current.setAlpha();
+ self.current.incrementPosition(4);
+ }
+
+ Ok(BlockParsedRXingResult::new())
+ }
+
+ fn parseIsoIec646Block(&mut self) -> Result {
+ while self.isStillIsoIec646(self.current.getPosition()) {
+ let iso = self.decodeIsoIec646(self.current.getPosition())?;
+ self.current.setPosition(iso.getNewPosition());
+
+ if iso.isFNC1() {
+ let information = DecodedInformation::new(self.current.getPosition(), self.buffer.clone());
+ return Ok(BlockParsedRXingResult::with_information(Some(information), true));
+ }
+ self.buffer.push_str(&iso.getValue().to_string());
+ }
+
+ if self.isAlphaOr646ToNumericLatch(self.current.getPosition()) {
+ self.current.incrementPosition(3);
+ self.current.setNumeric();
+ } else if self.isAlphaTo646ToAlphaLatch(self.current.getPosition()) {
+ if self.current.getPosition() + 5 < self.information.getSize() {
+ self. current.incrementPosition(5);
+ } else {
+ self.current.setPosition(self.information.getSize());
+ }
+
+ self.current.setAlpha();
+ }
+ Ok(BlockParsedRXingResult::new())
+ }
+
+ fn parseAlphaBlock(&mut self) -> Result {
+ while self.isStillAlpha(self.current.getPosition()) {
+ let alpha = self.decodeAlphanumeric(self.current.getPosition())?;
+ self.current.setPosition(alpha.getNewPosition());
+
+ if alpha.isFNC1() {
+ let information = DecodedInformation::new(self.current.getPosition(), self.buffer.clone());
+ return Ok(BlockParsedRXingResult::with_information(Some(information), true)); //end of the char block
+ }
+
+ self.buffer.push_str(&alpha.getValue().to_string());
+ }
+
+ if self.isAlphaOr646ToNumericLatch(self.current.getPosition()) {
+ self.current.incrementPosition(3);
+ self.current.setNumeric();
+ } else if self.isAlphaTo646ToAlphaLatch(self.current.getPosition()) {
+ if self.current.getPosition() + 5 < self.information.getSize() {
+ self.current.incrementPosition(5);
+ } else {
+ self.current.setPosition(self.information.getSize());
+ }
+
+ self.current.setIsoIec646();
+ }
+
+ Ok(BlockParsedRXingResult::new())
+ }
+
+ fn isStillIsoIec646(&self, pos:usize) -> bool{
+ if pos + 5 > self.information.getSize() {
+ return false;
+ }
+
+ let fiveBitValue =self. extractNumericValueFromBitArray(pos, 5);
+ if fiveBitValue >= 5 && fiveBitValue < 16 {
+ return true;
+ }
+
+ if pos + 7 > self.information.getSize() {
+ return false;
+ }
+
+ let sevenBitValue = self.extractNumericValueFromBitArray(pos, 7);
+ if sevenBitValue >= 64 && sevenBitValue < 116 {
+ return true;
+ }
+
+ if pos + 8 > self.information.getSize() {
+ return false;
+ }
+
+ let eightBitValue = self.extractNumericValueFromBitArray(pos, 8);
+
+ eightBitValue >= 232 && eightBitValue < 253
+
+ }
+
+ fn decodeIsoIec646(&self, pos:usize) -> Result {
+ let fiveBitValue = self.extractNumericValueFromBitArray(pos, 5);
+ if fiveBitValue == 15 {
+ return Ok(DecodedChar::new(pos + 5, DecodedChar::FNC1));
+ }
+
+ if fiveBitValue >= 5 && fiveBitValue < 15 {
+ return Ok(DecodedChar::new(pos + 5, char::from_u32 ('0' as u32 + fiveBitValue - 5).unwrap()));
+ }
+
+ let sevenBitValue = self.extractNumericValueFromBitArray(pos, 7);
+
+ if sevenBitValue >= 64 && sevenBitValue < 90 {
+ return Ok(DecodedChar::new(pos + 7, char::from_u32 (sevenBitValue + 1).unwrap()));
+ }
+
+ if sevenBitValue >= 90 && sevenBitValue < 116 {
+ return Ok(DecodedChar::new(pos + 7, char::from_u32 (sevenBitValue + 7).unwrap()));
+ }
+
+ let eightBitValue = self.extractNumericValueFromBitArray(pos, 8);
+ let c=
+ match eightBitValue {
+ 232=>
+ '!',
+ 233=>
+ '"',
+ 234=>
+ '%',
+ 235=>
+ '&',
+ 236=>
+ '\'',
+ 237=>
+ '(',
+ 238=>
+ ')',
+ 239=>
+ '*',
+ 240=>
+ '+',
+ 241=>
+ ',',
+ 242=>
+ '-',
+ 243=>
+ '.',
+ 244=>
+ '/',
+ 245=>
+ ':',
+ 246=>
+ ';',
+ 247=>
+ '<',
+ 248=>
+ '=',
+ 249=>
+ '>',
+ 250=>
+ '?',
+ 251=>
+ '_',
+ 252=>
+ ' ',
+ _=>
+ return Err(Exceptions::FormatException("".to_owned())),
+ };
+
+ Ok(DecodedChar::new(pos + 8, c))
+ }
+
+ fn isStillAlpha(&self, pos:usize) -> bool{
+ if pos + 5 > self.information.getSize() {
+ return false;
+ }
+
+ // We now check if it's a valid 5-bit value (0..9 and FNC1)
+ let fiveBitValue = self.extractNumericValueFromBitArray(pos, 5);
+ if fiveBitValue >= 5 && fiveBitValue < 16 {
+ return true;
+ }
+
+ if pos + 6 > self.information.getSize() {
+ return false;
+ }
+
+ let sixBitValue = self.extractNumericValueFromBitArray(pos, 6);
+
+ sixBitValue >= 16 && sixBitValue < 63 // 63 not included
+ }
+
+ fn decodeAlphanumeric(&self, pos:usize) -> Result {
+ let fiveBitValue = self.extractNumericValueFromBitArray(pos, 5);
+ if fiveBitValue == 15 {
+ return Ok(DecodedChar::new(pos + 5, DecodedChar::FNC1));
+ }
+
+ if fiveBitValue >= 5 && fiveBitValue < 15 {
+ return Ok(DecodedChar::new(pos + 5, char::from_u32 ('0' as u32 + fiveBitValue - 5).unwrap()));
+ }
+
+ let sixBitValue = self.extractNumericValueFromBitArray(pos, 6);
+
+ if sixBitValue >= 32 && sixBitValue < 58 {
+ return Ok(DecodedChar::new(pos + 6, char::from_u32 (sixBitValue + 33).unwrap()));
+ }
+
+ let c =
+ match sixBitValue {
+ 58=>
+ '*',
+ 59=>
+ ',',
+ 60=>
+ '-',
+ 61=>
+ '.',
+ 62=>
+ '/',
+ _=>
+ return Err(Exceptions::IllegalStateException(format!("Decoding invalid alphanumeric value: {}" , sixBitValue))),
+ };
+
+ Ok(DecodedChar::new(pos + 6, c))
+ }
+
+ fn isAlphaTo646ToAlphaLatch(&self, pos:usize)-> bool {
+ if pos + 1 > self.information.getSize() {
+ return false;
+ }
+
+ let mut i = 0;
+ while i < 5 && i + pos < self.information.getSize() {
+ // for (int i = 0; i < 5 && i + pos < this.information.getSize(); ++i) {
+ if i == 2 {
+ if !self.information.get(pos + 2) {
+ return false;
+ }
+ } else if self.information.get(pos + i) {
+ return false;
+ }
+
+ i+=1;
+ }
+
+ true
+ }
+
+ fn isAlphaOr646ToNumericLatch(&self, pos:usize) -> bool{
+ // Next is alphanumeric if there are 3 positions and they are all zeros
+ if pos + 3 > self.information.getSize() {
+ return false;
+ }
+
+ for i in pos..pos+3 {
+ // for (int i = pos; i < pos + 3; ++i) {
+ if self.information.get(i) {
+ return false;
+ }
+ }
+
+ true
+ }
+
+ fn isNumericToAlphaNumericLatch(&self, pos:usize) -> bool{
+ // Next is alphanumeric if there are 4 positions and they are all zeros, or
+ // if there is a subset of this just before the end of the symbol
+ if pos + 1 > self.information.getSize() {
+ return false;
+ }
+
+ let mut i = 0;
+ while i < 4 && pos < self.information.getSize() {
+ // for (int i = 0; i < 4 && i + pos < this.information.getSize(); ++i) {
+ if self.information.get(pos + i) {
+ return false;
+ }
+ i+=1;
+ }
+
+ true
+ }
+}
diff --git a/src/oned/rss/expanded/decoders/mod.rs b/src/oned/rss/expanded/decoders/mod.rs
index 8b13789..e010fd4 100644
--- a/src/oned/rss/expanded/decoders/mod.rs
+++ b/src/oned/rss/expanded/decoders/mod.rs
@@ -1 +1,27 @@
+
+pub mod abstract_expanded_decoder;
+pub use abstract_expanded_decoder::AbstractExpandedDecoder;
+mod ai_01_and_other_ais;
+pub use ai_01_and_other_ais::*;
+mod ai_01_decoder;
+pub use ai_01_decoder::*;
+mod general_app_id_decoder;
+pub use general_app_id_decoder::*;
+mod current_parsing_state;
+pub use current_parsing_state::*;
+mod decoded_object;
+pub use decoded_object::*;
+mod decoded_char;
+pub use decoded_char::*;
+
+mod decoded_information;
+pub use decoded_information::*;
+
+mod decoded_numeric;
+pub use decoded_numeric::*;
+
+mod block_parsed_result;
+pub use block_parsed_result::*;
+
+pub mod field_parser;
\ No newline at end of file
diff --git a/src/oned/rss/expanded/expanded_pair.rs b/src/oned/rss/expanded/expanded_pair.rs
new file mode 100644
index 0000000..1d51288
--- /dev/null
+++ b/src/oned/rss/expanded/expanded_pair.rs
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 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.
+ */
+
+/*
+ * These authors would like to acknowledge the Spanish Ministry of Industry,
+ * Tourism and Trade, for the support in the project TSI020301-2008-2
+ * "PIRAmIDE: Personalizable Interactions with Resources on AmI-enabled
+ * Mobile Dynamic Environments", led by Treelogic
+ * ( http://www.treelogic.com/ ):
+ *
+ * http://www.piramidepse.com/
+ */
+
+use std::fmt::Display;
+
+use crate::oned::rss::{DataCharacter, FinderPattern};
+
+/**
+ * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es)
+ */
+#[derive(PartialEq, Eq, Hash)]
+pub struct ExpandedPair {
+ leftChar: Option,
+ rightChar: Option,
+ finderPattern: Option,
+}
+
+impl ExpandedPair {
+ pub fn new(
+ leftChar: Option,
+ rightChar: Option,
+ finderPattern: Option,
+ ) -> Self {
+ Self {
+ leftChar,
+ rightChar,
+ finderPattern,
+ }
+ }
+
+ pub fn getLeftChar(&self) -> &Option {
+ &self.leftChar
+ }
+
+ pub fn getRightChar(&self) -> &Option {
+ &self.rightChar
+ }
+
+ pub fn getFinderPattern(&self) -> &Option {
+ &self.finderPattern
+ }
+
+ pub fn mustBeLast(&self) -> bool {
+ self.rightChar.is_none()
+ }
+}
+
+impl Display for ExpandedPair {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(
+ f,
+ "[ {:?} , {:?} : {} ]",
+ self.leftChar,
+ self.rightChar,
+ if let Some(fp) = &self.finderPattern {
+ fp.getValue().to_string()
+ } else {
+ "null".to_owned()
+ }
+ )
+ }
+}
diff --git a/src/oned/rss/expanded/mod.rs b/src/oned/rss/expanded/mod.rs
index 819ec6e..1951a66 100644
--- a/src/oned/rss/expanded/mod.rs
+++ b/src/oned/rss/expanded/mod.rs
@@ -1 +1,7 @@
pub mod decoders;
+
+pub mod binary_util;
+pub mod bit_array_builder;
+
+mod expanded_pair;
+pub use expanded_pair::*;
diff --git a/src/oned/rss/rss_14_reader.rs b/src/oned/rss/rss_14_reader.rs
index d2ba498..cfe949f 100644
--- a/src/oned/rss/rss_14_reader.rs
+++ b/src/oned/rss/rss_14_reader.rs
@@ -18,7 +18,7 @@ use std::collections::HashMap;
use crate::{
common::{detector::MathUtils, BitArray},
- oned::{OneDReader, one_d_reader},
+ oned::{one_d_reader, OneDReader},
BarcodeFormat, DecodeHintType, DecodingHintDictionary, Exceptions, RXingResult,
RXingResultMetadataType, RXingResultMetadataValue, RXingResultPoint, Reader, ResultPoint,
};
@@ -293,11 +293,10 @@ impl RSS14Reader {
pattern: &FinderPattern,
outsideChar: bool,
) -> Result {
- let counters = &mut self.dataCharacterCounters; //[0_u32; 8]; //self.getDataCharacterCounters();
- //Arrays.fill(counters, 0);
- // counters.fill(0);
- counters.fill(0);
-
+ let counters = &mut self.dataCharacterCounters; //[0_u32; 8]; //self.getDataCharacterCounters();
+ //Arrays.fill(counters, 0);
+ // counters.fill(0);
+ counters.fill(0);
if outsideChar {
one_d_reader::recordPatternInReverse(row, pattern.getStartEnd()[0], &mut counters[..])?;
@@ -305,7 +304,7 @@ impl RSS14Reader {
one_d_reader::recordPattern(row, pattern.getStartEnd()[1], &mut counters[..])?;
// reverse it
let mut i = 0;
- let mut j = counters.len() -1;
+ let mut j = counters.len() - 1;
while i < j {
// for (int i = 0, j = counters.length - 1; i < j; i++, j--) {
let temp = counters[i];
@@ -468,13 +467,13 @@ impl RSS14Reader {
let firstCounter = startEnd[0] - firstElementStart as usize;
let mut counters = &mut self.decodeFinderCounters;
let counter_len = counters.len();
- let slc = counters[0..counter_len-1].to_vec();
+ let slc = counters[0..counter_len - 1].to_vec();
counters[1..counter_len].copy_from_slice(&slc);
// Make 'counters' hold 1-4
// let counters = self.getDecodeFinderCounters();
// System.arraycopy(counters, 0, counters, 1, counters.length - 1);
// counters.fill(0);
-
+
counters[0] = firstCounter as u32;
let value = Self::parseFinderValue(counters, &Self::FINDER_PATTERNS)?;
let mut start = firstElementStart as usize;
diff --git a/src/oned/upc_ean_reader.rs b/src/oned/upc_ean_reader.rs
index cd2868c..1a5cd42 100644
--- a/src/oned/upc_ean_reader.rs
+++ b/src/oned/upc_ean_reader.rs
@@ -19,7 +19,7 @@ use crate::{
RXingResultMetadataType, RXingResultMetadataValue, RXingResultPoint, Reader,
};
-use super::{EANManufacturerOrgSupport, OneDReader, UPCEANExtensionSupport, one_d_reader};
+use super::{one_d_reader, EANManufacturerOrgSupport, OneDReader, UPCEANExtensionSupport};
use lazy_static::lazy_static;
@@ -433,8 +433,11 @@ pub trait UPCEANReader: OneDReader {
counters[counterPosition] += 1;
} else {
if counterPosition == patternLength - 1 {
- if one_d_reader::patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE)
- < MAX_AVG_VARIANCE
+ if one_d_reader::patternMatchVariance(
+ counters,
+ pattern,
+ MAX_INDIVIDUAL_VARIANCE,
+ ) < MAX_AVG_VARIANCE
{
return Ok([patternStart, x]);
}
@@ -483,7 +486,7 @@ pub trait UPCEANReader: OneDReader {
// for (int i = 0; i < max; i++) {
let pattern = &patterns[i];
let variance: f32 =
- one_d_reader::patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);
+ one_d_reader::patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE);
if variance < bestVariance {
bestVariance = variance;
bestMatch = i as isize;
diff --git a/tests/rss_14_blackbox.rs b/tests/rss_14_blackbox.rs
index ac45d3f..ed980ce 100644
--- a/tests/rss_14_blackbox.rs
+++ b/tests/rss_14_blackbox.rs
@@ -1,4 +1,3 @@
-
/*
* Copyright 2008 ZXing authors
*
@@ -15,15 +14,15 @@
* limitations under the License.
*/
- use rxing::{maxicode::MaxiCodeReader, BarcodeFormat, DecodeHintType, MultiFormatReader};
+use rxing::{maxicode::MaxiCodeReader, BarcodeFormat, DecodeHintType, MultiFormatReader};
- mod common;
-
- /**
- * @author Sean Owen
- */
- #[test]
- fn rss14_black_box1_test_case() {
+mod common;
+
+/**
+ * @author Sean Owen
+ */
+#[test]
+fn rss14_black_box1_test_case() {
let mut tester = common::AbstractBlackBoxTestCase::new(
"test_resources/blackbox/rss14-1",
MultiFormatReader::default(),
@@ -31,15 +30,13 @@
);
// super("src/test/resources/blackbox/rss14-1", new MultiFormatReader(), BarcodeFormat.RSS_14);
- tester.add_test(6, 6, 0.0);
- tester.add_test(6, 6, 180.0);
+ tester.add_test(6, 6, 0.0);
+ tester.add_test(6, 6, 180.0);
- tester.test_black_box()
- }
-
-
+ tester.test_black_box()
+}
- /**
+/**
* @author Sean Owen
*/
#[test]
@@ -55,6 +52,4 @@ fn rss14_black_box2_test_case() {
tester.add_test_complex(3, 8, 0, 1, 180.0);
tester.test_black_box()
- }
-
-
\ No newline at end of file
+}