From 14d8245568d033537735304ca2a13eaffb3ecc0d Mon Sep 17 00:00:00 2001 From: Henry Schimke Date: Wed, 14 Dec 2022 17:58:40 -0600 Subject: [PATCH] cargo fmt --- .../decoders/abstract_expanded_decoder.rs | 37 +- .../expanded/decoders/ai_01_and_other_ais.rs | 42 +- .../rss/expanded/decoders/ai_01_decoder.rs | 80 +- .../rss/expanded/decoders/decoded_object.rs | 6 +- .../rss/expanded/decoders/field_parser.rs | 30 +- .../decoders/general_app_id_decoder.rs | 882 +++++++++--------- src/oned/rss/expanded/decoders/mod.rs | 4 +- 7 files changed, 557 insertions(+), 524 deletions(-) diff --git a/src/oned/rss/expanded/decoders/abstract_expanded_decoder.rs b/src/oned/rss/expanded/decoders/abstract_expanded_decoder.rs index d531e27..06f45ae 100644 --- a/src/oned/rss/expanded/decoders/abstract_expanded_decoder.rs +++ b/src/oned/rss/expanded/decoders/abstract_expanded_decoder.rs @@ -24,38 +24,35 @@ * http://www.piramidepse.com/ */ -use crate::{Exceptions, common::BitArray}; +use crate::{common::BitArray, Exceptions}; 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; - // private final BitArray information; - // private final GeneralAppIdDecoder generalDecoder; + // AbstractExpandedDecoder(BitArray information) { + // this.information = information; + // this.generalDecoder = new GeneralAppIdDecoder(information); + // } - // AbstractExpandedDecoder(BitArray information) { - // this.information = information; - // this.generalDecoder = new GeneralAppIdDecoder(information); - // } + // protected final BitArray getInformation() { + // return information; + // } - // protected final BitArray getInformation() { - // return information; - // } + // protected final GeneralAppIdDecoder getGeneralDecoder() { + // return generalDecoder; + // } - // protected final GeneralAppIdDecoder getGeneralDecoder() { - // return generalDecoder; - // } - - fn parseInformation(&mut self) -> Result; - fn getGeneralDecoder(&self) -> &GeneralAppIdDecoder; - // fn new(information:&BitArray) -> Self where Self:Sized; + fn parseInformation(&mut self) -> Result; + fn getGeneralDecoder(&self) -> &GeneralAppIdDecoder; + // fn new(information:&BitArray) -> Self where Self:Sized; } // pub fn createDecoder( information:&BitArray) -> Box{ @@ -92,4 +89,4 @@ pub trait AbstractExpandedDecoder { // } // throw new IllegalStateException("unknown decoder: " + information); -// } \ No newline at end of file +// } diff --git a/src/oned/rss/expanded/decoders/ai_01_and_other_ais.rs b/src/oned/rss/expanded/decoders/ai_01_and_other_ais.rs index 0648009..6e21aca 100644 --- a/src/oned/rss/expanded/decoders/ai_01_and_other_ais.rs +++ b/src/oned/rss/expanded/decoders/ai_01_and_other_ais.rs @@ -32,20 +32,22 @@ 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) */ -pub struct AI01AndOtherAIs<'a>(&'a BitArray,GeneralAppIdDecoder<'a>); -impl<'a> AI01decoder for AI01AndOtherAIs<'_> {} +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(); + fn parseInformation(&mut self) -> Result { + let mut buff = String::new(); //new StringBuilder(); - 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) + 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) } fn getGeneralDecoder(&self) -> &super::GeneralAppIdDecoder { @@ -53,13 +55,13 @@ impl AbstractExpandedDecoder for AI01AndOtherAIs<'_> { } } impl<'a> AI01AndOtherAIs<'_> { - fn new(information:&'a BitArray) -> AI01AndOtherAIs<'a> { - AI01AndOtherAIs( information,GeneralAppIdDecoder::new(information)) -} + 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); - // } + 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/ai_01_decoder.rs b/src/oned/rss/expanded/decoders/ai_01_decoder.rs index 4e9e52e..502759a 100644 --- a/src/oned/rss/expanded/decoders/ai_01_decoder.rs +++ b/src/oned/rss/expanded/decoders/ai_01_decoder.rs @@ -26,55 +26,57 @@ use super::AbstractExpandedDecoder; - /** * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) * @author Eduardo Castillejo, University of Deusto (eduardo.castillejo@deusto.es) */ -pub trait AI01decoder : AbstractExpandedDecoder { +pub trait AI01decoder: AbstractExpandedDecoder { + const GTIN_SIZE: u32 = 40; - const GTIN_SIZE : u32 = 40; + fn encodeCompressedGtin(&self, buf: &mut String, currentPos: usize) { + buf.push_str("(01)"); + let initialPosition = buf.chars().count(); + buf.push('9'); - 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); - } - - 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.push('0'); - } - buf.push_str(¤tBlock.to_string()); + self.encodeCompressedGtinWithoutAI(buf, currentPos, initialPosition); } - appendCheckDigit(buf, initialBufferPosition); - } - - + 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.push('0'); + } + buf.push_str(¤tBlock.to_string()); + } + appendCheckDigit(buf, initialBufferPosition); + } } -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}; - } +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; - } + checkDigit = 10 - (checkDigit % 10); + if checkDigit == 10 { + checkDigit = 0; + } - buf.push_str(&checkDigit.to_string()); -} \ No newline at end of file + buf.push_str(&checkDigit.to_string()); +} diff --git a/src/oned/rss/expanded/decoders/decoded_object.rs b/src/oned/rss/expanded/decoders/decoded_object.rs index 15816f7..1a173ea 100644 --- a/src/oned/rss/expanded/decoders/decoded_object.rs +++ b/src/oned/rss/expanded/decoders/decoded_object.rs @@ -24,13 +24,9 @@ * http://www.piramidepse.com/ */ - - /** * @author Pablo Orduña, University of Deusto (pablo.orduna@deusto.es) */ pub trait DecodedObject { - - fn getNewPosition(&self) -> usize; - + fn getNewPosition(&self) -> usize; } diff --git a/src/oned/rss/expanded/decoders/field_parser.rs b/src/oned/rss/expanded/decoders/field_parser.rs index ae67977..301ed15 100644 --- a/src/oned/rss/expanded/decoders/field_parser.rs +++ b/src/oned/rss/expanded/decoders/field_parser.rs @@ -281,28 +281,26 @@ impl DataLength { } } - - /** * @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 { +mod FieldParserTest { - fn checkFields( expected:&str) { - let field = expected.replace("(", "").replace(")",""); - let actual = super::parseFieldsInGeneralPurpose(&field).expect("parse"); - assert_eq!(expected, actual); - } + 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 testParseField() { + checkFields("(15)991231(3103)001750(10)12A"); + } - #[test] - fn testParseField2() { - checkFields("(15)991231(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 index c1af427..a0cfe03 100644 --- a/src/oned/rss/expanded/decoders/general_app_id_decoder.rs +++ b/src/oned/rss/expanded/decoders/general_app_id_decoder.rs @@ -26,444 +26,484 @@ use crate::{common::BitArray, Exceptions}; -use super::{CurrentParsingState, DecodedChar, DecodedNumeric, DecodedInformation, BlockParsedRXingResult, DecodedObject, field_parser}; +use super::{ + field_parser, BlockParsedRXingResult, CurrentParsingState, DecodedChar, DecodedInformation, + DecodedNumeric, DecodedObject, +}; /** * @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(); + 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; + pub fn new(information: &'a BitArray) -> GeneralAppIdDecoder<'a> { + GeneralAppIdDecoder { + information, + current: CurrentParsingState::new(), + buffer: String::new(), } - } else if self.information.get(pos + i) { - return false; - } - - i+=1; } - true - } + 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(); + } - 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; + if currentPosition == info.getNewPosition() { + // No step forward! + break; + } + currentPosition = info.getNewPosition(); + } + + Ok(buff) } - for i in pos..pos+3 { - // for (int i = pos; i < pos + 3; ++i) { - if self.information.get(i) { - return false; - } - } - - true - } + 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(); + } - 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; + 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) } - 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; + 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 } - - true - } } diff --git a/src/oned/rss/expanded/decoders/mod.rs b/src/oned/rss/expanded/decoders/mod.rs index e010fd4..fb9eed1 100644 --- a/src/oned/rss/expanded/decoders/mod.rs +++ b/src/oned/rss/expanded/decoders/mod.rs @@ -1,5 +1,3 @@ - - pub mod abstract_expanded_decoder; pub use abstract_expanded_decoder::AbstractExpandedDecoder; mod ai_01_and_other_ais; @@ -24,4 +22,4 @@ pub use decoded_numeric::*; mod block_parsed_result; pub use block_parsed_result::*; -pub mod field_parser; \ No newline at end of file +pub mod field_parser;