partially passing encoder tests

This commit is contained in:
Henry
2022-10-03 20:17:41 -05:00
parent 3e80f7dd71
commit 9ec895ecc5
4 changed files with 279 additions and 257 deletions

View File

@@ -84,10 +84,10 @@ const ASSUME_SHIFT_JIS: bool = false;
static SHIFT_JIS: &'static str = "SJIS"; static SHIFT_JIS: &'static str = "SJIS";
static GB2312: &'static str = "GB2312"; static GB2312: &'static str = "GB2312";
lazy_static! { lazy_static! {
pub static ref SHIFT_JIS_CHARSET: EncodingRef = encoding::label::encoding_from_whatwg_label("SJIS").unwrap(); pub static ref SHIFT_JIS_CHARSET: EncodingRef =
encoding::label::encoding_from_whatwg_label("SJIS").unwrap();
} }
// private static final boolean ASSUME_SHIFT_JIS = // private static final boolean ASSUME_SHIFT_JIS =
// SHIFT_JIS_CHARSET.equals(PLATFORM_DEFAULT_ENCODING) || // SHIFT_JIS_CHARSET.equals(PLATFORM_DEFAULT_ENCODING) ||
// EUC_JP.equals(PLATFORM_DEFAULT_ENCODING); // EUC_JP.equals(PLATFORM_DEFAULT_ENCODING);
@@ -558,27 +558,27 @@ impl BitArray {
* @param value {@code int} containing bits to append * @param value {@code int} containing bits to append
* @param numBits bits from value to append * @param numBits bits from value to append
*/ */
pub fn appendBits(&mut self, value: u32, numBits: usize) -> Result<(), Exceptions> { pub fn appendBits(&mut self, value: u32, num_bits: usize) -> Result<(), Exceptions> {
if numBits > 32 { if num_bits > 32 {
return Err(Exceptions::IllegalArgumentException( return Err(Exceptions::IllegalArgumentException(
"Num bits must be between 0 and 32".to_owned(), "Num bits must be between 0 and 32".to_owned(),
)); ));
} }
if numBits == 0 { if num_bits == 0 {
return Ok(()); return Ok(());
} }
let mut nextSize = self.size; let mut next_size = self.size;
self.ensure_capacity(nextSize + numBits); self.ensure_capacity(next_size + num_bits);
for numBitsLeft in (0..(numBits)).rev() { for numBitsLeft in (0..num_bits).rev() {
//for (int numBitsLeft = numBits - 1; numBitsLeft >= 0; numBitsLeft--) { //for (int numBitsLeft = numBits - 1; numBitsLeft >= 0; numBitsLeft--) {
if (value & (1 << numBitsLeft)) != 0 { if (value & (1 << numBitsLeft)) != 0 {
self.bits[nextSize / 32] |= 1 << (nextSize & 0x1F); self.bits[next_size / 32] |= 1 << (next_size & 0x1F);
} }
nextSize += 1; next_size += 1;
} }
self.size = nextSize; self.size = next_size;
Ok(()) Ok(())
} }
@@ -2473,7 +2473,7 @@ impl CharacterSetECI {
// this.otherEncodingNames = otherEncodingNames; // this.otherEncodingNames = otherEncodingNames;
// } // }
pub fn getValueSelf(&self) -> u32{ pub fn getValueSelf(&self) -> u32 {
Self::getValue(self) Self::getValue(self)
} }
@@ -2550,7 +2550,7 @@ impl CharacterSetECI {
pub fn getCharacterSetECI(charset: &'static dyn Encoding) -> Option<CharacterSetECI> { pub fn getCharacterSetECI(charset: &'static dyn Encoding) -> Option<CharacterSetECI> {
let name = if let Some(nm) = charset.whatwg_name() { let name = if let Some(nm) = charset.whatwg_name() {
nm nm
}else { } else {
charset.name() charset.name()
}; };
match name { match name {
@@ -2853,6 +2853,44 @@ impl fmt::Display for ECIStringBuilder {
// import java.util.ArrayList; // import java.util.ArrayList;
// import java.util.List; // import java.util.List;
lazy_static! {
static ref ENCODERS : Vec<EncodingRef> = {
let mut enc_vec = Vec::new();
for name in NAMES {
if let Some(enc) = CharacterSetECI::getCharacterSetECIByName(name) {
// try {
enc_vec.push(CharacterSetECI::getCharset(&enc));
// } catch (UnsupportedCharsetException e) {
// continue
// }
}
}
enc_vec
};
}
const NAMES: [&str; 20] = [
"IBM437",
"ISO-8859-2",
"ISO-8859-3",
"ISO-8859-4",
"ISO-8859-5",
"ISO-8859-6",
"ISO-8859-7",
"ISO-8859-8",
"ISO-8859-9",
"ISO-8859-10",
"ISO-8859-11",
"ISO-8859-13",
"ISO-8859-14",
"ISO-8859-15",
"ISO-8859-16",
"windows-1250",
"windows-1251",
"windows-1252",
"windows-1256",
"Shift_JIS",
];
/** /**
* Set of CharsetEncoders for a given input string * Set of CharsetEncoders for a given input string
* *
@@ -2882,45 +2920,8 @@ impl ECIEncoderSet {
* @param fnc1 fnc1 denotes the character in the input that represents the FNC1 character or -1 for a non-GS1 bar * @param fnc1 fnc1 denotes the character in the input that represents the FNC1 character or -1 for a non-GS1 bar
* code. When specified, it is considered an error to pass it as argument to the methods canEncode() or encode(). * code. When specified, it is considered an error to pass it as argument to the methods canEncode() or encode().
*/ */
pub fn new( pub fn new(stringToEncode: &str, priorityCharset: EncodingRef, fnc1: i16) -> Self {
stringToEncode: &str,
priorityCharset: EncodingRef,
fnc1: i16,
) -> Self {
// List of encoders that potentially encode characters not in ISO-8859-1 in one byte. // List of encoders that potentially encode characters not in ISO-8859-1 in one byte.
let mut ENCODERS :Vec<EncodingRef> = Vec::new();
let names = [
"IBM437",
"ISO-8859-2",
"ISO-8859-3",
"ISO-8859-4",
"ISO-8859-5",
"ISO-8859-6",
"ISO-8859-7",
"ISO-8859-8",
"ISO-8859-9",
"ISO-8859-10",
"ISO-8859-11",
"ISO-8859-13",
"ISO-8859-14",
"ISO-8859-15",
"ISO-8859-16",
"windows-1250",
"windows-1251",
"windows-1252",
"windows-1256",
"Shift_JIS",
];
for name in names {
if let Some(enc) = CharacterSetECI::getCharacterSetECIByName(name) {
// try {
ENCODERS.push(CharacterSetECI::getCharset(&enc));
// } catch (UnsupportedCharsetException e) {
// continue
// }
}
}
let mut encoders: Vec<EncodingRef>; let mut encoders: Vec<EncodingRef>;
let mut priorityEncoderIndexValue = 0; let mut priorityEncoderIndexValue = 0;
@@ -2929,7 +2930,6 @@ impl ECIEncoderSet {
//we always need the ISO-8859-1 encoder. It is the default encoding //we always need the ISO-8859-1 encoder. It is the default encoding
neededEncoders.push(encoding::all::ISO_8859_1); neededEncoders.push(encoding::all::ISO_8859_1);
neededEncoders.push(encoding::all::UTF_8);
let mut needUnicodeEncoder = priorityCharset.name().starts_with("UTF"); let mut needUnicodeEncoder = priorityCharset.name().starts_with("UTF");
//Walk over the input string and see if all characters can be encoded with the list of encoders //Walk over the input string and see if all characters can be encoded with the list of encoders
@@ -2950,7 +2950,9 @@ impl ECIEncoderSet {
} }
if !canEncode { if !canEncode {
//for the character at position i we don't yet have an encoder in the list //for the character at position i we don't yet have an encoder in the list
for encoder in &ENCODERS { for i in 0..ENCODERS.len() {
// for encoder in ENCODERS {
let encoder = ENCODERS.get(i).unwrap();
// for (CharsetEncoder encoder : ENCODERS) { // for (CharsetEncoder encoder : ENCODERS) {
if encoder if encoder
.encode( .encode(
@@ -4034,19 +4036,19 @@ impl HybridBinarizer {
if (max - min) as usize > HybridBinarizer::MIN_DYNAMIC_RANGE { if (max - min) as usize > HybridBinarizer::MIN_DYNAMIC_RANGE {
// finish the rest of the rows quickly // finish the rest of the rows quickly
offset += width; offset += width;
yy+=1; yy += 1;
while yy < HybridBinarizer::BLOCK_SIZE { while yy < HybridBinarizer::BLOCK_SIZE {
// for (yy++, offset += width; yy < HybridBinarizer::BLOCK_SIZE; yy++, offset += width) { // for (yy++, offset += width; yy < HybridBinarizer::BLOCK_SIZE; yy++, offset += width) {
for xx in 0..HybridBinarizer::BLOCK_SIZE { for xx in 0..HybridBinarizer::BLOCK_SIZE {
// for (int xx = 0; xx < BLOCK_SIZE; xx++) { // for (int xx = 0; xx < BLOCK_SIZE; xx++) {
sum += luminances[offset as usize + xx] as u32; sum += luminances[offset as usize + xx] as u32;
} }
yy+=1; yy += 1;
offset += width; offset += width;
} }
break; break;
} }
yy+=1; yy += 1;
offset += width; offset += width;
} }
@@ -4069,7 +4071,8 @@ impl HybridBinarizer {
// the boundaries is used for the interior. // the boundaries is used for the interior.
// The (min < bp) is arbitrary but works better than other heuristics that were tried. // The (min < bp) is arbitrary but works better than other heuristics that were tried.
let average_neighbor_black_point:u32 = (blackPoints[y as usize - 1][x as usize] let average_neighbor_black_point: u32 = (blackPoints[y as usize - 1]
[x as usize]
+ (2 * blackPoints[y as usize][x as usize - 1]) + (2 * blackPoints[y as usize][x as usize - 1])
+ blackPoints[y as usize - 1][x as usize - 1]) + blackPoints[y as usize - 1][x as usize - 1])
/ 4; / 4;

View File

@@ -16,7 +16,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::{qrcode::{encoder::encoder, decoder::{Mode, ErrorCorrectionLevel}}, EncodeHintType, EncodeHintValue, common::BitArray}; use crate::{qrcode::{encoder::{encoder, MinimalEncoder}, decoder::{Mode, ErrorCorrectionLevel, Version}}, EncodeHintType, EncodeHintValue, common::BitArray};
use encoding::EncodingRef; use encoding::EncodingRef;
use lazy_static::lazy_static; use lazy_static::lazy_static;
@@ -82,13 +82,13 @@ lazy_static! {
// AIUE in Hiragana in Shift_JIS // AIUE in Hiragana in Shift_JIS
assert_eq!(Mode::BYTE, assert_eq!(Mode::BYTE,
encoder::chooseMode(&shiftJISString(bytes(0x8, 0xa, 0x8, 0xa, 0x8, 0xa, 0x8, 0xa6)))); encoder::chooseMode(&shiftJISString(&[0x8, 0xa, 0x8, 0xa, 0x8, 0xa, 0x8, 0xa6])));
// Nihon in Kanji in Shift_JIS. // Nihon in Kanji in Shift_JIS.
assert_eq!(Mode::BYTE, encoder::chooseMode(&shiftJISString(bytes(0x9, 0xf, 0x9, 0x7b)))); assert_eq!(Mode::BYTE, encoder::chooseMode(&shiftJISString(&[0x9, 0xf, 0x9, 0x7b])));
// Sou-Utsu-Byou in Kanji in Shift_JIS. // Sou-Utsu-Byou in Kanji in Shift_JIS.
assert_eq!(Mode::BYTE, encoder::chooseMode(&shiftJISString(bytes(0xe, 0x4, 0x9, 0x5, 0x9, 0x61)))); assert_eq!(Mode::BYTE, encoder::chooseMode(&shiftJISString(&[0xe, 0x4, 0x9, 0x5, 0x9, 0x61])));
} }
#[test] #[test]
@@ -129,7 +129,7 @@ r"<<
#[test] #[test]
fn testEncodeWithVersion() { fn testEncodeWithVersion() {
let hints = HashMap::new(); let mut hints = HashMap::new();
hints.insert(EncodeHintType::QR_VERSION, EncodeHintValue::QrVersion("7".to_owned())); hints.insert(EncodeHintType::QR_VERSION, EncodeHintValue::QrVersion("7".to_owned()));
let qrCode = encoder::encode_with_hints("ABCDEF", ErrorCorrectionLevel::H, &hints).expect("encode"); let qrCode = encoder::encode_with_hints("ABCDEF", ErrorCorrectionLevel::H, &hints).expect("encode");
assert!(qrCode.to_string().contains(" version: 7\n")); assert!(qrCode.to_string().contains(" version: 7\n"));
@@ -138,16 +138,16 @@ r"<<
#[test] #[test]
#[should_panic] #[should_panic]
fn testEncodeWithVersionTooSmall() { fn testEncodeWithVersionTooSmall() {
let hints = HashMap::new(); let mut hints = HashMap::new();
hints.put(EncodeHintType::QR_VERSION, 3); hints.insert(EncodeHintType::QR_VERSION, EncodeHintValue::QrVersion("3".to_owned()));
encoder::encode_with_hints("THISMESSAGEISTOOLONGFORAQRCODEVERSION3", ErrorCorrectionLevel::H, &hints); encoder::encode_with_hints("THISMESSAGEISTOOLONGFORAQRCODEVERSION3", ErrorCorrectionLevel::H, &hints).expect("encode");
} }
#[test] #[test]
fn testSimpleUTF8ECI() { fn testSimpleUTF8ECI() {
let hints = HashMap::new(); let mut hints = HashMap::new();
hints.put(EncodeHintType::CHARACTER_SET, "UTF8"); hints.insert(EncodeHintType::CHARACTER_SET, EncodeHintValue::CharacterSet("UTF8".to_owned()));
let qrCode = encoder::encode_with_hints("hello", ErrorCorrectionLevel::H, &hints); let qrCode = encoder::encode_with_hints("hello", ErrorCorrectionLevel::H, &hints).expect("encode");
let expected = let expected =
r"<< r"<<
mode: BYTE mode: BYTE
@@ -183,11 +183,11 @@ r"<<
#[test] #[test]
fn testEncodeKanjiMode() { fn testEncodeKanjiMode() {
let hints = HashMap::new(); let mut hints = HashMap::new();
hints.put(EncodeHintType::CHARACTER_SET, "Shift_JIS"); hints.insert(EncodeHintType::CHARACTER_SET, EncodeHintValue::CharacterSet("Shift_JIS".to_owned()));
// Nihon in Kanji // Nihon in Kanji
let qrCode = encoder::encode_with_hints("\u{65e5}\u{672c}", ErrorCorrectionLevel::M, hints); let qrCode = encoder::encode_with_hints("\u{65e5}\u{672c}", ErrorCorrectionLevel::M, &hints).expect("encode");
let expected = let expected =
r"<< r"<<
mode: KANJI mode: KANJI
@@ -223,10 +223,11 @@ r"<<
#[test] #[test]
fn testEncodeShiftjisNumeric() { fn testEncodeShiftjisNumeric() {
let hints = HashMap::new(); let mut hints = HashMap::new();
hints.put(EncodeHintType::CHARACTER_SET, "Shift_JIS"); hints.insert(EncodeHintType::CHARACTER_SET, EncodeHintValue::CharacterSet("Shift_JIS".to_owned()));
let qrCode = encoder::encode_with_hints("0123", ErrorCorrectionLevel::M, hints);
let qrCode = encoder::encode_with_hints("0123", ErrorCorrectionLevel::M, &hints).expect("encode");
let expected = let expected =
r"<< r"<<
mode: NUMERIC mode: NUMERIC
@@ -262,47 +263,48 @@ r"<<
#[test] #[test]
fn testEncodeGS1WithStringTypeHint() { fn testEncodeGS1WithStringTypeHint() {
let hints = HashMap::new(); let mut hints = HashMap::new();
hints.put(EncodeHintType::GS1_FORMAT, "true"); hints.insert(EncodeHintType::GS1_FORMAT, EncodeHintValue::Gs1Format("true".to_owned()));
let qrCode = encoder::encode_with_hints("100001%11171218", ErrorCorrectionLevel::H, hints); let qrCode = encoder::encode_with_hints("100001%11171218", ErrorCorrectionLevel::H, &hints).expect("encode");
verifyGS1EncodedData(qrCode); verifyGS1EncodedData(&qrCode);
} }
#[test] #[test]
fn testEncodeGS1WithBooleanTypeHint() { fn testEncodeGS1WithBooleanTypeHint() {
let hints = HashMap::new(); let mut hints = HashMap::new();
hints.put(EncodeHintType::GS1_FORMAT, true); hints.insert(EncodeHintType::GS1_FORMAT, EncodeHintValue::Gs1Format("true".to_owned()));
let qrCode = encoder::encode_with_hints("100001%11171218", ErrorCorrectionLevel::H, hints); let qrCode = encoder::encode_with_hints("100001%11171218", ErrorCorrectionLevel::H, &hints).expect("encode");
verifyGS1EncodedData(qrCode); verifyGS1EncodedData(&qrCode);
} }
#[test] #[test]
fn testDoesNotEncodeGS1WhenBooleanTypeHintExplicitlyFalse() { fn testDoesNotEncodeGS1WhenBooleanTypeHintExplicitlyFalse() {
let hints = HashMap::new(); let mut hints = HashMap::new();
hints.put(EncodeHintType::GS1_FORMAT, false); hints.insert(EncodeHintType::GS1_FORMAT, EncodeHintValue::Gs1Format("false".to_owned()));
let qrCode = encoder::encode_with_hints("ABCDEF", ErrorCorrectionLevel::H, hints);
verifyNotGS1EncodedData(qrCode); let qrCode = encoder::encode_with_hints("ABCDEF", ErrorCorrectionLevel::H, &hints).expect("encode");
verifyNotGS1EncodedData(&qrCode);
} }
#[test] #[test]
fn testDoesNotEncodeGS1WhenStringTypeHintExplicitlyFalse() { fn testDoesNotEncodeGS1WhenStringTypeHintExplicitlyFalse() {
let hints = HashMap::new(); let mut hints = HashMap::new();
hints.put(EncodeHintType::GS1_FORMAT, "false"); hints.insert(EncodeHintType::GS1_FORMAT, EncodeHintValue::Gs1Format("false".to_owned()));
let qrCode = encoder::encode_with_hints("ABCDEF", ErrorCorrectionLevel::H, hints); let qrCode = encoder::encode_with_hints("ABCDEF", ErrorCorrectionLevel::H, &hints).expect("encode");
verifyNotGS1EncodedData(qrCode); verifyNotGS1EncodedData(&qrCode);
} }
#[test] #[test]
fn testGS1ModeHeaderWithECI() { fn testGS1ModeHeaderWithECI() {
let hints = HashMap::new(); let mut hints = HashMap::new();
hints.put(EncodeHintType::CHARACTER_SET, "UTF8"); hints.insert(EncodeHintType::CHARACTER_SET, EncodeHintValue::CharacterSet("UTF8".to_owned()));
hints.put(EncodeHintType::GS1_FORMAT, true); hints.insert(EncodeHintType::GS1_FORMAT, EncodeHintValue::Gs1Format("true".to_owned()));
let qrCode = encoder::encode_with_hints("hello", ErrorCorrectionLevel::H, hints); let qrCode = encoder::encode_with_hints("hello", ErrorCorrectionLevel::H, &hints).expect("encode");
let expected = let expected =
r"<< r"<<
mode: BYTE mode: BYTE
@@ -338,36 +340,36 @@ r"<<
#[test] #[test]
fn testAppendModeInfo() { fn testAppendModeInfo() {
let bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendModeInfo(Mode::NUMERIC, bits); encoder::appendModeInfo(Mode::NUMERIC, &mut bits);
assert_eq!(" ...X", bits.to_string()); assert_eq!(" ...X", bits.to_string());
} }
#[test] #[test]
fn testAppendLengthInfo() { fn testAppendLengthInfo() {
let bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendLengthInfo(1, // 1 letter (1/1). encoder::appendLengthInfo(1, // 1 letter (1/1).
Version::getVersionForNumber(1), Version::getVersionForNumber(1).unwrap(),
Mode::NUMERIC, Mode::NUMERIC,
bits); &mut bits);
assert_eq!(" ........ .X", bits.to_string()); // 10 bits. assert_eq!(" ........ .X", bits.to_string()); // 10 bits.
let bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendLengthInfo(2, // 2 letters (2/1). encoder::appendLengthInfo(2, // 2 letters (2/1).
Version::getVersionForNumber(10), Version::getVersionForNumber(10).unwrap(),
Mode::ALPHANUMERIC, Mode::ALPHANUMERIC,
bits); &mut bits);
assert_eq!(" ........ .X.", bits.to_string()); // 11 bits. assert_eq!(" ........ .X.", bits.to_string()); // 11 bits.
let bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendLengthInfo(255, // 255 letter (255/1). encoder::appendLengthInfo(255, // 255 letter (255/1).
Version::getVersionForNumber(27), Version::getVersionForNumber(27).unwrap(),
Mode::BYTE, Mode::BYTE,
bits); &mut bits);
assert_eq!(" ........ XXXXXXXX", bits.to_string()); // 16 bits. assert_eq!(" ........ XXXXXXXX", bits.to_string()); // 16 bits.
let bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendLengthInfo(512, // 512 letters (1024/2). encoder::appendLengthInfo(512, // 512 letters (1024/2).
Version::getVersionForNumber(40), Version::getVersionForNumber(40).unwrap(),
Mode::KANJI, Mode::KANJI,
bits); &mut bits);
assert_eq!(" ..X..... ....", bits.to_string()); // 12 bits. assert_eq!(" ..X..... ....", bits.to_string()); // 12 bits.
} }
@@ -375,139 +377,144 @@ r"<<
fn testAppendBytes() { fn testAppendBytes() {
// Should use appendNumericBytes. // Should use appendNumericBytes.
// 1 = 01 = 0001 in 4 bits. // 1 = 01 = 0001 in 4 bits.
let bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendBytes("1", Mode::NUMERIC, bits, encoder::DEFAULT_BYTE_MODE_ENCODING); encoder::appendBytes("1", Mode::NUMERIC, &mut bits, encoder::DEFAULT_BYTE_MODE_ENCODING);
assert_eq!(" ...X" , bits.to_string()); assert_eq!(" ...X" , bits.to_string());
// Should use appendAlphanumericBytes. // Should use appendAlphanumericBytes.
// A = 10 = 0xa = 001010 in 6 bits // A = 10 = 0xa = 001010 in 6 bits
let bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendBytes("A", Mode::ALPHANUMERIC, bits, encoder::DEFAULT_BYTE_MODE_ENCODING); encoder::appendBytes("A", Mode::ALPHANUMERIC, &mut bits, encoder::DEFAULT_BYTE_MODE_ENCODING);
assert_eq!(" ..X.X." , bits.to_string()); assert_eq!(" ..X.X." , bits.to_string());
// Lower letters such as 'a' cannot be encoded in MODE_ALPHANUMERIC. // Lower letters such as 'a' cannot be encoded in MODE_ALPHANUMERIC.
try { //try {
encoder::appendBytes("a", Mode::ALPHANUMERIC, bits, encoder::DEFAULT_BYTE_MODE_ENCODING); if encoder::appendBytes("a", Mode::ALPHANUMERIC, &mut bits, encoder::DEFAULT_BYTE_MODE_ENCODING).is_ok(){
} catch (WriterException we) { panic!("should never be ok");
// good
} }
//} catch (WriterException we) {
// good
//}
// Should use append8BitBytes. // Should use append8BitBytes.
// 0x61, 0x62, 0x63 // 0x61, 0x62, 0x63
let bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendBytes("abc", Mode::BYTE, bits, encoder::DEFAULT_BYTE_MODE_ENCODING); encoder::appendBytes("abc", Mode::BYTE, &mut bits, encoder::DEFAULT_BYTE_MODE_ENCODING);
assert_eq!(" .XX....X .XX...X. .XX...XX", bits.to_string()); assert_eq!(" .XX....X .XX...X. .XX...XX", bits.to_string());
// Anything can be encoded in QRCode.MODE_8BIT_BYTE. // Anything can be encoded in QRCode.MODE_8BIT_BYTE.
encoder::appendBytes("\0", Mode::BYTE, bits, encoder::DEFAULT_BYTE_MODE_ENCODING); encoder::appendBytes("\0", Mode::BYTE, &mut bits, encoder::DEFAULT_BYTE_MODE_ENCODING);
// Should use appendKanjiBytes. // Should use appendKanjiBytes.
// 0x93, 0x5f // 0x93, 0x5f
let bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendBytes(&shiftJISString(bytes(0x93, 0x5f)), Mode::KANJI, bits, encoder::appendBytes(&shiftJISString(&[0x93, 0x5f]), Mode::KANJI, &mut bits,
encoder::DEFAULT_BYTE_MODE_ENCODING); encoder::DEFAULT_BYTE_MODE_ENCODING);
assert_eq!(" .XX.XX.. XXXXX", bits.to_string()); assert_eq!(" .XX.XX.. XXXXX", bits.to_string());
} }
#[test] #[test]
fn testTerminateBits() { fn testTerminateBits() {
let v = BitArray::new(); let mut v = BitArray::new();
encoder::terminateBits(0, v); encoder::terminateBits(0, &mut v).expect("terminate");
assert_eq!("", v.to_string()); assert_eq!("", v.to_string());
let v = BitArray::new(); let mut v = BitArray::new();
encoder::terminateBits(1, v); encoder::terminateBits(1, &mut v).expect("terminate");
assert_eq!(" ........", v.to_string()); assert_eq!(" ........", v.to_string());
let v = BitArray::new(); let mut v = BitArray::new();
v.appendBits(0, 3); // Append 000 v.appendBits(0, 3).expect("terminate"); // Append 000
encoder::terminateBits(1, v); encoder::terminateBits(1, &mut v).expect("terminate");
assert_eq!(" ........", v.to_string()); assert_eq!(" ........", v.to_string());
let v = BitArray::new(); let mut v = BitArray::new();
v.appendBits(0, 5); // Append 00000 v.appendBits(0, 5).expect("terminate"); // Append 00000
encoder::terminateBits(1, v); encoder::terminateBits(1, &mut v).expect("terminate");
assert_eq!(" ........", v.to_string()); assert_eq!(" ........", v.to_string());
let v = BitArray::new(); let mut v = BitArray::new();
v.appendBits(0, 8); // Append 00000000 v.appendBits(0, 8).expect("terminate"); // Append 00000000
encoder::terminateBits(1, v); encoder::terminateBits(1, &mut v).expect("terminate");
assert_eq!(" ........", v.to_string()); assert_eq!(" ........", v.to_string());
let v = BitArray::new(); let mut v = BitArray::new();
encoder::terminateBits(2, v); encoder::terminateBits(2, &mut v).expect("terminate");
assert_eq!(" ........ XXX.XX..", v.to_string()); assert_eq!(" ........ XXX.XX..", v.to_string());
let v = BitArray::new(); let mut v = BitArray::new();
v.appendBits(0, 1); // Append 0 v.appendBits(0, 1).expect("terminate"); // Append 0
encoder::terminateBits(3, v); encoder::terminateBits(3, &mut v).expect("terminate");
assert_eq!(" ........ XXX.XX.. ...X...X", v.to_string()); assert_eq!(" ........ XXX.XX.. ...X...X", v.to_string());
} }
#[test] #[test]
fn testGetNumDataBytesAndNumECBytesForBlockID() { fn testGetNumDataBytesAndNumECBytesForBlockID() {
int[] numDataBytes = new int[1]; let mut numDataBytes = vec![0;1];
int[] numEcBytes = new int[1]; let mut numEcBytes = vec![0;1];
// Version 1-H. // Version 1-H.
encoder::getNumDataBytesAndNumECBytesForBlockID(26, 9, 1, 0, numDataBytes, numEcBytes); encoder::getNumDataBytesAndNumECBytesForBlockID(26, 9, 1, 0, &mut numDataBytes, &mut numEcBytes);
assert_eq!(9, numDataBytes[0]); assert_eq!(9, numDataBytes[0]);
assert_eq!(17, numEcBytes[0]); assert_eq!(17, numEcBytes[0]);
// Version 3-H. 2 blocks. // Version 3-H. 2 blocks.
encoder::getNumDataBytesAndNumECBytesForBlockID(70, 26, 2, 0, numDataBytes, numEcBytes); encoder::getNumDataBytesAndNumECBytesForBlockID(70, 26, 2, 0, &mut numDataBytes, &mut numEcBytes);
assert_eq!(13, numDataBytes[0]); assert_eq!(13, numDataBytes[0]);
assert_eq!(22, numEcBytes[0]); assert_eq!(22, numEcBytes[0]);
encoder::getNumDataBytesAndNumECBytesForBlockID(70, 26, 2, 1, numDataBytes, numEcBytes); encoder::getNumDataBytesAndNumECBytesForBlockID(70, 26, 2, 1, &mut numDataBytes, &mut numEcBytes);
assert_eq!(13, numDataBytes[0]); assert_eq!(13, numDataBytes[0]);
assert_eq!(22, numEcBytes[0]); assert_eq!(22, numEcBytes[0]);
// Version 7-H. (4 + 1) blocks. // Version 7-H. (4 + 1) blocks.
encoder::getNumDataBytesAndNumECBytesForBlockID(196, 66, 5, 0, numDataBytes, numEcBytes); encoder::getNumDataBytesAndNumECBytesForBlockID(196, 66, 5, 0, &mut numDataBytes, &mut numEcBytes);
assert_eq!(13, numDataBytes[0]); assert_eq!(13, numDataBytes[0]);
assert_eq!(26, numEcBytes[0]); assert_eq!(26, numEcBytes[0]);
encoder::getNumDataBytesAndNumECBytesForBlockID(196, 66, 5, 4, numDataBytes, numEcBytes); encoder::getNumDataBytesAndNumECBytesForBlockID(196, 66, 5, 4, &mut numDataBytes, &mut numEcBytes);
assert_eq!(14, numDataBytes[0]); assert_eq!(14, numDataBytes[0]);
assert_eq!(26, numEcBytes[0]); assert_eq!(26, numEcBytes[0]);
// Version 40-H. (20 + 61) blocks. // Version 40-H. (20 + 61) blocks.
encoder::getNumDataBytesAndNumECBytesForBlockID(3706, 1276, 81, 0, numDataBytes, numEcBytes); encoder::getNumDataBytesAndNumECBytesForBlockID(3706, 1276, 81, 0, &mut numDataBytes, &mut numEcBytes);
assert_eq!(15, numDataBytes[0]); assert_eq!(15, numDataBytes[0]);
assert_eq!(30, numEcBytes[0]); assert_eq!(30, numEcBytes[0]);
encoder::getNumDataBytesAndNumECBytesForBlockID(3706, 1276, 81, 20, numDataBytes, numEcBytes); encoder::getNumDataBytesAndNumECBytesForBlockID(3706, 1276, 81, 20, &mut numDataBytes, &mut numEcBytes);
assert_eq!(16, numDataBytes[0]); assert_eq!(16, numDataBytes[0]);
assert_eq!(30, numEcBytes[0]); assert_eq!(30, numEcBytes[0]);
encoder::getNumDataBytesAndNumECBytesForBlockID(3706, 1276, 81, 80, numDataBytes, numEcBytes); encoder::getNumDataBytesAndNumECBytesForBlockID(3706, 1276, 81, 80, &mut numDataBytes, &mut numEcBytes);
assert_eq!(16, numDataBytes[0]); assert_eq!(16, numDataBytes[0]);
assert_eq!(30, numEcBytes[0]); assert_eq!(30, numEcBytes[0]);
} }
#[test] #[test]
fn testInterleaveWithECBytes() { fn testInterleaveWithECBytes() {
byte[] dataBytes = bytes(32, 65, 205, 69, 41, 220, 46, 128, 236); let dataBytes = &[32u32, 65, 205, 69, 41, 220, 46, 128, 236];
BitArray in = new BitArray(); let mut in_ = BitArray::new();
for (byte dataByte: dataBytes) { for dataByte in dataBytes {
in.appendBits(dataByte, 8); // for (byte dataByte: dataBytes) {
in_.appendBits(*dataByte, 8);
} }
BitArray out = encoder::interleaveWithECBytes(in, 26, 9, 1); let out = encoder::interleaveWithECBytes(&in_, 26, 9, 1).expect("encode");
byte[] expected = bytes( let expected = &[
// Data bytes. // Data bytes.
32, 65, 205, 69, 41, 220, 46, 128, 236, 32, 65, 205, 69, 41, 220, 46, 128, 236,
// Error correction bytes. // Error correction bytes.
42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 42, 159, 74, 221, 244, 169, 239, 150, 138, 70,
237, 85, 224, 96, 74, 219, 61 237, 85, 224, 96, 74, 219, 61
); ];
assert_eq!(expected.length, out.getSizeInBytes()); assert_eq!(expected.len(), out.getSizeInBytes());
byte[] outArray = new byte[expected.length]; let mut outArray = vec![0u8;expected.len()];
out.toBytes(0, outArray, 0, expected.length); out.toBytes(0, &mut outArray, 0, expected.len());
// Can't use Arrays.equals(), because outArray may be longer than out.sizeInBytes() // Can't use Arrays.equals(), because outArray may be longer than out.sizeInBytes()
for (int x = 0; x < expected.length; x++) { for x in 0..expected.len() {
// for (int x = 0; x < expected.length; x++) {
assert_eq!(expected[x], outArray[x]); assert_eq!(expected[x], outArray[x]);
} }
// Numbers are from http://www.swetake.com/qr/qr8.html // Numbers are from http://www.swetake.com/qr/qr8.html
dataBytes = bytes( let dataBytes = &[
67, 70, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 182, 67u32, 70, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 182,
198, 214, 230, 247, 7, 23, 39, 55, 71, 87, 103, 119, 135, 198, 214, 230, 247, 7, 23, 39, 55, 71, 87, 103, 119, 135,
151, 166, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 151, 166, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166,
182, 198, 214, 230, 247, 7, 23, 39, 55, 71, 87, 103, 119, 182, 198, 214, 230, 247, 7, 23, 39, 55, 71, 87, 103, 119,
135, 151, 160, 236, 17, 236, 17, 236, 17, 236, 135, 151, 160, 236, 17, 236, 17, 236, 17, 236,
17 17
); ];
in = new BitArray(); in_ = BitArray::new();
for (byte dataByte: dataBytes) { for dataByte in dataBytes{
in.appendBits(dataByte, 8); // for (byte dataByte: dataBytes) {
in_.appendBits(*dataByte, 8);
} }
out = encoder::interleaveWithECBytes(in, 134, 62, 4); let out = encoder::interleaveWithECBytes(&in_, 134, 62, 4).expect("interleave ok");
expected = bytes( let expected = &[
// Data bytes. // Data bytes.
67, 230, 54, 55, 70, 247, 70, 71, 22, 7, 86, 87, 38, 23, 102, 103, 54, 39, 67, 230, 54, 55, 70, 247, 70, 71, 22, 7, 86, 87, 38, 23, 102, 103, 54, 39,
118, 119, 70, 55, 134, 135, 86, 71, 150, 151, 102, 87, 166, 118, 119, 70, 55, 134, 135, 86, 71, 150, 151, 102, 87, 166,
@@ -523,11 +530,12 @@ r"<<
211, 164, 117, 30, 158, 225, 31, 190, 242, 38, 211, 164, 117, 30, 158, 225, 31, 190, 242, 38,
140, 61, 179, 154, 214, 138, 147, 87, 27, 96, 77, 47, 140, 61, 179, 154, 214, 138, 147, 87, 27, 96, 77, 47,
187, 49, 156, 214 187, 49, 156, 214
); ];
assert_eq!(expected.length, out.getSizeInBytes()); assert_eq!(expected.len(), out.getSizeInBytes());
outArray = new byte[expected.length]; outArray = vec![0u8;expected.len()];
out.toBytes(0, outArray, 0, expected.length); out.toBytes(0, &mut outArray, 0, expected.len());
for (int x = 0; x < expected.length; x++) { for x in 0..expected.len(){
// for (int x = 0; x < expected.length; x++) {
assert_eq!(expected[x], outArray[x]); assert_eq!(expected[x], outArray[x]);
} }
} }
@@ -544,23 +552,23 @@ r"<<
fn testAppendNumericBytes() { fn testAppendNumericBytes() {
// 1 = 01 = 0001 in 4 bits. // 1 = 01 = 0001 in 4 bits.
let mut bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendNumericBytes("1", bits); encoder::appendNumericBytes("1", &mut bits);
assert_eq!(" ...X" , bits.to_string()); assert_eq!(" ...X" , bits.to_string());
// 12 = 0xc = 0001100 in 7 bits. // 12 = 0xc = 0001100 in 7 bits.
let mut bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendNumericBytes("12", bits); encoder::appendNumericBytes("12", &mut bits);
assert_eq!(" ...XX.." , bits.to_string()); assert_eq!(" ...XX.." , bits.to_string());
// 123 = 0x7b = 0001111011 in 10 bits. // 123 = 0x7b = 0001111011 in 10 bits.
let mut bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendNumericBytes("123", bits); encoder::appendNumericBytes("123", &mut bits);
assert_eq!(" ...XXXX. XX" , bits.to_string()); assert_eq!(" ...XXXX. XX" , bits.to_string());
// 1234 = "123" + "4" = 0001111011 + 0100 // 1234 = "123" + "4" = 0001111011 + 0100
let mut bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendNumericBytes("1234", bits); encoder::appendNumericBytes("1234", &mut bits);
assert_eq!(" ...XXXX. XX.X.." , bits.to_string()); assert_eq!(" ...XXXX. XX.X.." , bits.to_string());
// Empty. // Empty.
let mut bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendNumericBytes("", bits); encoder::appendNumericBytes("", &mut bits);
assert_eq!("" , bits.to_string()); assert_eq!("" , bits.to_string());
} }
@@ -568,37 +576,39 @@ r"<<
fn testAppendAlphanumericBytes() { fn testAppendAlphanumericBytes() {
// A = 10 = 0xa = 001010 in 6 bits // A = 10 = 0xa = 001010 in 6 bits
let mut bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendAlphanumericBytes("A", bits); encoder::appendAlphanumericBytes("A", &mut bits);
assert_eq!(" ..X.X." , bits.to_string()); assert_eq!(" ..X.X." , bits.to_string());
// AB = 10 * 45 + 11 = 461 = 0x1cd = 00111001101 in 11 bits // AB = 10 * 45 + 11 = 461 = 0x1cd = 00111001101 in 11 bits
let mut bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendAlphanumericBytes("AB", bits); encoder::appendAlphanumericBytes("AB", &mut bits);
assert_eq!(" ..XXX..X X.X", bits.to_string()); assert_eq!(" ..XXX..X X.X", bits.to_string());
// ABC = "AB" + "C" = 00111001101 + 001100 // ABC = "AB" + "C" = 00111001101 + 001100
let mut bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendAlphanumericBytes("ABC", bits); encoder::appendAlphanumericBytes("ABC", &mut bits);
assert_eq!(" ..XXX..X X.X..XX. ." , bits.to_string()); assert_eq!(" ..XXX..X X.X..XX. ." , bits.to_string());
// Empty. // Empty.
let mut bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendAlphanumericBytes("", bits); encoder::appendAlphanumericBytes("", &mut bits);
assert_eq!("" , bits.to_string()); assert_eq!("" , bits.to_string());
// Invalid data. // Invalid data.
try { // try {
encoder::appendAlphanumericBytes("abc", BitArray::new()); if encoder::appendAlphanumericBytes("abc", &mut BitArray::new()).is_ok() {
} catch (WriterException we) { panic!("should not be ok");
// good
} }
// } catch (WriterException we) {
// good
// }
} }
#[test] #[test]
fn testAppend8BitBytes() { fn testAppend8BitBytes() {
// 0x61, 0x62, 0x63 // 0x61, 0x62, 0x63
let mut bits = BitArray::new(); let mut bits = BitArray::new();
encoder::append8BitBytes("abc", bits, encoder::DEFAULT_BYTE_MODE_ENCODING); encoder::append8BitBytes("abc", &mut bits, encoder::DEFAULT_BYTE_MODE_ENCODING);
assert_eq!(" .XX....X .XX...X. .XX...XX", bits.to_string()); assert_eq!(" .XX....X .XX...X. .XX...XX", bits.to_string());
// Empty. // Empty.
let mut bits = BitArray::new(); let mut bits = BitArray::new();
encoder::append8BitBytes("", bits, encoder::DEFAULT_BYTE_MODE_ENCODING); encoder::append8BitBytes("", &mut bits, encoder::DEFAULT_BYTE_MODE_ENCODING);
assert_eq!("", bits.to_string()); assert_eq!("", bits.to_string());
} }
@@ -606,9 +616,9 @@ r"<<
#[test] #[test]
fn testAppendKanjiBytes() { fn testAppendKanjiBytes() {
let mut bits = BitArray::new(); let mut bits = BitArray::new();
encoder::appendKanjiBytes(shiftJISString(bytes(0x93, 0x5f)), bits); encoder::appendKanjiBytes(&shiftJISString(&[0x93, 0x5f]), &mut bits);
assert_eq!(" .XX.XX.. XXXXX", bits.to_string()); assert_eq!(" .XX.XX.. XXXXX", bits.to_string());
encoder::appendKanjiBytes(shiftJISString(bytes(0xe4, 0xaa)), bits); encoder::appendKanjiBytes(&shiftJISString(&[0xe4, 0xaa]), &mut bits);
assert_eq!(" .XX.XX.. XXXXXXX. X.X.X.X. X.", bits.to_string()); assert_eq!(" .XX.XX.. XXXXXXX. X.X.X.X. X.", bits.to_string());
} }
@@ -616,32 +626,35 @@ r"<<
// http://www.swetake.com/qr/qr9.html // http://www.swetake.com/qr/qr9.html
#[test] #[test]
fn testGenerateECBytes() { fn testGenerateECBytes() {
let dataBytes = bytes(32, 65, 205, 69, 41, 220, 46, 128, 236); let dataBytes = &[32, 65, 205, 69, 41, 220, 46, 128, 236];
let ecBytes = encoder::generateECBytes(dataBytes, 17); let ecBytes = encoder::generateECBytes(dataBytes, 17);
let expected = [ let expected = [
42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 237, 85, 224, 96, 74, 219, 61 42, 159, 74, 221, 244, 169, 239, 150, 138, 70, 237, 85, 224, 96, 74, 219, 61
]; ];
assert_eq!(expected.length, ecBytes.length); assert_eq!(expected.len(), ecBytes.len());
for (int x = 0; x < expected.length; x++) { for x in 0..expected.len() {
// for (int x = 0; x < expected.length; x++) {
assert_eq!(expected[x], ecBytes[x] & 0xFF); assert_eq!(expected[x], ecBytes[x] & 0xFF);
} }
dataBytes = bytes(67, 70, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 182, 198, 214); let dataBytes = &[67, 70, 22, 38, 54, 70, 86, 102, 118, 134, 150, 166, 182, 198, 214];
ecBytes = encoder::generateECBytes(dataBytes, 18); let ecBytes = encoder::generateECBytes(dataBytes, 18);
expected = new int[] { let expected = &[
175, 80, 155, 64, 178, 45, 214, 233, 65, 209, 12, 155, 117, 31, 140, 214, 27, 187 175, 80, 155, 64, 178, 45, 214, 233, 65, 209, 12, 155, 117, 31, 140, 214, 27, 187
}; ];
assert_eq!(expected.length, ecBytes.length); assert_eq!(expected.len(), ecBytes.len());
for (int x = 0; x < expected.length; x++) { for x in 0..expected.len() {
// for (int x = 0; x < expected.length; x++) {
assert_eq!(expected[x], ecBytes[x] & 0xFF); assert_eq!(expected[x], ecBytes[x] & 0xFF);
} }
// High-order zero coefficient case. // High-order zero coefficient case.
dataBytes = bytes(32, 49, 205, 69, 42, 20, 0, 236, 17); let dataBytes = &[32, 49, 205, 69, 42, 20, 0, 236, 17];
ecBytes = encoder::generateECBytes(dataBytes, 17); let ecBytes = encoder::generateECBytes(dataBytes, 17);
expected = new int[] { let expected = &[
0, 3, 130, 179, 194, 0, 55, 211, 110, 79, 98, 72, 170, 96, 211, 137, 213 0, 3, 130, 179, 194, 0, 55, 211, 110, 79, 98, 72, 170, 96, 211, 137, 213
}; ];
assert_eq!(expected.length, ecBytes.length); assert_eq!(expected.len(), ecBytes.len());
for (int x = 0; x < expected.length; x++) { for x in 0..expected.len() {
// for (int x = 0; x < expected.length; x++) {
assert_eq!(expected[x], ecBytes[x] & 0xFF); assert_eq!(expected[x], ecBytes[x] & 0xFF);
} }
} }
@@ -676,12 +689,12 @@ r"<<
// - To be precise, it needs 11727 + 4 (getMode info) + 14 (length info) = // - To be precise, it needs 11727 + 4 (getMode info) + 14 (length info) =
// 11745 bits = 1468.125 bytes are needed (i.e. cannot fit in 1468 // 11745 bits = 1468.125 bytes are needed (i.e. cannot fit in 1468
// bytes). // bytes).
let builder = String::with_capacity(3518); let mut builder = String::with_capacity(3518);
for x in 0..3518 { for x in 0..3518 {
// for (int x = 0; x < 3518; x++) { // for (int x = 0; x < 3518; x++) {
builder.push('0'); builder.push('0');
} }
encoder::encode(builder.to_string(), ErrorCorrectionLevel::L); encoder::encode(&builder, ErrorCorrectionLevel::L);
} }
#[test] #[test]
@@ -841,14 +854,14 @@ r"<<
#[test] #[test]
fn testMinimalEncoder32() { fn testMinimalEncoder32() {
verifyMinimalEncoding("http://foo.com", "BYTE(http://foo.com)" + verifyMinimalEncoding("http://foo.com", "BYTE(http://foo.com)\
"", None, false); ", None, false);
} }
#[test] #[test]
fn testMinimalEncoder33() { fn testMinimalEncoder33() {
verifyMinimalEncoding("HTTP://FOO.COM", "ALPHANUMERIC(HTTP://FOO.COM" + verifyMinimalEncoding("HTTP://FOO.COM", "ALPHANUMERIC(HTTP://FOO.COM\
")", None, false); )", None, false);
} }
#[test] #[test]
@@ -874,27 +887,27 @@ r"<<
#[test] #[test]
fn testMinimalEncoder38() { fn testMinimalEncoder38() {
verifyMinimalEncoding("\u{0150}\u{0150}\u{015C}\u{015C}", "ECI(ISO-8859-2),BYTE(." + verifyMinimalEncoding("\u{0150}\u{0150}\u{015C}\u{015C}", "ECI(ISO-8859-2),BYTE(.\
".),ECI(ISO-8859-3),BYTE(..)", None, false); .),ECI(ISO-8859-3),BYTE(..)", None, false);
} }
#[test] #[test]
fn testMinimalEncoder39() { fn testMinimalEncoder39() {
verifyMinimalEncoding("abcdef\u{0150}ghij", "ECI(ISO-8859-2),BYTE(abcde" + verifyMinimalEncoding("abcdef\u{0150}ghij", "ECI(ISO-8859-2),BYTE(abcde\
"f.ghij)", None, false); f.ghij)", None, false);
} }
#[test] #[test]
fn testMinimalEncoder40() { fn testMinimalEncoder40() {
verifyMinimalEncoding("2938928329832983\u{0150}2938928329832983\u{015C}2938928329832983", verifyMinimalEncoding("2938928329832983\u{0150}2938928329832983\u{015C}2938928329832983",
"NUMERIC(2938928329832983),ECI(ISO-8859-2),BYTE(.),NUMERIC(2938928329832983),ECI(ISO-8" + "NUMERIC(2938928329832983),ECI(ISO-8859-2),BYTE(.),NUMERIC(2938928329832983),ECI(ISO-8\
"859-3),BYTE(.),NUMERIC(2938928329832983)", None, false); 859-3),BYTE(.),NUMERIC(2938928329832983)", None, false);
} }
#[test] #[test]
fn testMinimalEncoder41() { fn testMinimalEncoder41() {
verifyMinimalEncoding("1001114670010%01201220%107211220%140045003267781", "FNC1_FIRST_POSITION(),NUMERIC(100111" + verifyMinimalEncoding("1001114670010%01201220%107211220%140045003267781", "FNC1_FIRST_POSITION(),NUMERIC(100111\
"4670010),ALPHANUMERIC(%01201220%107211220%),NUMERIC(140045003267781)", None, 4670010),ALPHANUMERIC(%01201220%107211220%),NUMERIC(140045003267781)", None,
true); true);
} }
@@ -917,14 +930,14 @@ r"<<
// The character \u30A2 encodes as double byte in Shift_JIS but KANJI is not more compact in this case because // The character \u30A2 encodes as double byte in Shift_JIS but KANJI is not more compact in this case because
// KANJI is only more compact when it encodes pairs of characters. In the case of mixed text it can however be // KANJI is only more compact when it encodes pairs of characters. In the case of mixed text it can however be
// that Shift_JIS encoding is more compact as in this example // that Shift_JIS encoding is more compact as in this example
verifyMinimalEncoding("Katakana:\u{30A2}a\u{30A2}a\u{30A2}a\u{30A2}a\u{30A2}a\u{30A2}", "ECI(Shift_JIS),BYTE(Katakana:.a.a.a" + verifyMinimalEncoding("Katakana:\u{30A2}a\u{30A2}a\u{30A2}a\u{30A2}a\u{30A2}a\u{30A2}", "ECI(Shift_JIS),BYTE(Katakana:.a.a.a\
".a.a.)", None, false); .a.a.)", None, false);
} }
fn verifyMinimalEncoding( input:&str, expectedRXingResult:&str, priorityCharset:Option<EncodingRef>, isGS1:bool) fn verifyMinimalEncoding( input:&str, expectedRXingResult:&str, priorityCharset:Option<EncodingRef>, isGS1:bool)
{ {
let result = Minimalencoder::encode(input, None, priorityCharset, isGS1, let result = MinimalEncoder::encode_with_details(input, None, priorityCharset.unwrap_or(encoding::all::ISO_8859_1), isGS1,
ErrorCorrectionLevel::L); ErrorCorrectionLevel::L).expect("encode");
assert_eq!(result.to_string(), expectedRXingResult); assert_eq!(result.to_string(), expectedRXingResult);
} }

View File

@@ -70,7 +70,7 @@ const ALPHANUMERIC_TABLE: [i8; 96] = [
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // 0x50-0x5f 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // 0x50-0x5f
]; ];
const DEFAULT_BYTE_MODE_ENCODING: EncodingRef = encoding::all::ISO_8859_1; pub const DEFAULT_BYTE_MODE_ENCODING: EncodingRef = encoding::all::ISO_8859_1;
// The mask penalty calculation is complicated. See Table 21 of JISX0510:2004 (p.45) for details. // The mask penalty calculation is complicated. See Table 21 of JISX0510:2004 (p.45) for details.
// Basically it applies four rules and summate all penalties. // Basically it applies four rules and summate all penalties.
@@ -89,13 +89,13 @@ pub fn calculateMaskPenalty(matrix: &ByteMatrix) -> u32 {
* or configuration * or configuration
*/ */
pub fn encode(content: &str, ecLevel: ErrorCorrectionLevel) -> Result<QRCode, Exceptions> { pub fn encode(content: &str, ecLevel: ErrorCorrectionLevel) -> Result<QRCode, Exceptions> {
return encode_with_hints(content, ecLevel, HashMap::new()); return encode_with_hints(content, ecLevel, &HashMap::new());
} }
pub fn encode_with_hints( pub fn encode_with_hints(
content: &str, content: &str,
ecLevel: ErrorCorrectionLevel, ecLevel: ErrorCorrectionLevel,
hints: EncodingHintDictionary, hints: &EncodingHintDictionary,
) -> Result<QRCode, Exceptions> { ) -> Result<QRCode, Exceptions> {
let version; let version;
let mut headerAndDataBits; let mut headerAndDataBits;
@@ -431,8 +431,8 @@ pub fn willFit(numInputBits: u32, version: VersionRef, ecLevel: &ErrorCorrection
/** /**
* Terminate bits as described in 8.4.8 and 8.4.9 of JISX0510:2004 (p.24). * Terminate bits as described in 8.4.8 and 8.4.9 of JISX0510:2004 (p.24).
*/ */
pub fn terminateBits(numDataBytes: u32, bits: &mut BitArray) -> Result<(), Exceptions> { pub fn terminateBits(num_data_bytes: u32, bits: &mut BitArray) -> Result<(), Exceptions> {
let capacity = numDataBytes * 8; let capacity = num_data_bytes * 8;
if bits.getSize() > capacity as usize { if bits.getSize() > capacity as usize {
return Err(Exceptions::WriterException(format!( return Err(Exceptions::WriterException(format!(
"data bits cannot fit in the QR Code{} > ", "data bits cannot fit in the QR Code{} > ",
@@ -442,8 +442,8 @@ pub fn terminateBits(numDataBytes: u32, bits: &mut BitArray) -> Result<(), Excep
// capacity); // capacity);
} }
// Append Mode.TERMINATE if there is enough space (value is 0000) // Append Mode.TERMINATE if there is enough space (value is 0000)
for i in 0..4 { for _i in 0..4 {
if bits.getSize() > 0 { if bits.getSize() >= capacity as usize {
break; break;
} }
// } // }
@@ -452,18 +452,19 @@ pub fn terminateBits(numDataBytes: u32, bits: &mut BitArray) -> Result<(), Excep
} }
// Append termination bits. See 8.4.8 of JISX0510:2004 (p.24) for details. // Append termination bits. See 8.4.8 of JISX0510:2004 (p.24) for details.
// If the last byte isn't 8-bit aligned, we'll add padding bits. // If the last byte isn't 8-bit aligned, we'll add padding bits.
let numBitsInLastByte = bits.getSize() & 0x07; let num_bits_in_last_byte = bits.getSize() & 0x07;
if numBitsInLastByte > 0 { if num_bits_in_last_byte > 0 {
for i in numBitsInLastByte..8 { for _i in num_bits_in_last_byte..8 {
// for (int i = numBitsInLastByte; i < 8; i++) { // for (int i = numBitsInLastByte; i < 8; i++) {
bits.appendBit(false); bits.appendBit(false);
} }
} }
// If we have more space, we'll fill the space with padding patterns defined in 8.4.9 (p.24). // If we have more space, we'll fill the space with padding patterns defined in 8.4.9 (p.24).
let numPaddingBytes = numDataBytes as usize - bits.getSizeInBytes(); let num_padding_bytes = num_data_bytes as isize - bits.getSizeInBytes() as isize;
for i in 0..numPaddingBytes { for i in 0..num_padding_bytes {
if i >= num_padding_bytes{ break }
// for (int i = 0; i < numPaddingBytes; ++i) { // for (int i = 0; i < numPaddingBytes; ++i) {
bits.appendBits(if (i & 0x01) == 0 { 0xEC } else { 0x11 }, 8); bits.appendBits(if (i & 0x01) == 0 { 0xEC } else { 0x11 }, 8)?;
} }
if bits.getSize() != capacity as usize { if bits.getSize() != capacity as usize {
return Err(Exceptions::WriterException( return Err(Exceptions::WriterException(
@@ -757,22 +758,22 @@ pub fn appendAlphanumericBytes(content: &str, bits: &mut BitArray) -> Result<(),
} }
if i + 1 < length { if i + 1 < length {
let code2 = getAlphanumericCode(content.chars().nth(i + 1).unwrap() as u32); let code2 = getAlphanumericCode(content.chars().nth(i + 1).unwrap() as u32);
if (code2 == -1) { if code2 == -1 {
return Err(Exceptions::WriterException("".to_owned())); return Err(Exceptions::WriterException("".to_owned()));
} }
// Encode two alphanumeric letters in 11 bits. // Encode two alphanumeric letters in 11 bits.
bits.appendBits((code1 * 45 + code2) as u32, 11); bits.appendBits((code1 as i16 * 45 + code2 as i16) as u32, 11)?;
i += 2; i += 2;
} else { } else {
// Encode one alphanumeric letter in six bits. // Encode one alphanumeric letter in six bits.
bits.appendBits(code1 as u32, 6); bits.appendBits(code1 as u32, 6)?;
i += 1; i += 1;
} }
} }
Ok(()) Ok(())
} }
fn append8BitBytes(content: &str, bits: &mut BitArray, encoding: EncodingRef) { pub fn append8BitBytes(content: &str, bits: &mut BitArray, encoding: EncodingRef) {
let bytes = encoding let bytes = encoding
.encode(content, encoding::EncoderTrap::Strict) .encode(content, encoding::EncoderTrap::Strict)
.expect("should encode"); .expect("should encode");
@@ -783,7 +784,7 @@ fn append8BitBytes(content: &str, bits: &mut BitArray, encoding: EncodingRef) {
} }
} }
fn appendKanjiBytes(content: &str, bits: &mut BitArray) -> Result<(), Exceptions> { pub fn appendKanjiBytes(content: &str, bits: &mut BitArray) -> Result<(), Exceptions> {
let sjis = &SHIFT_JIS_CHARSET; //encoding::label::encoding_from_whatwg_label("SJIS").unwrap(); let sjis = &SHIFT_JIS_CHARSET; //encoding::label::encoding_from_whatwg_label("SJIS").unwrap();
let bytes = sjis let bytes = sjis

View File

@@ -584,7 +584,10 @@ impl MinimalEncoder {
} }
Ok(RXingResultList::new( Ok(RXingResultList::new(
version, version,
edges[inputLength][minimalJ.unwrap()][minimalK.unwrap()].as_ref().unwrap().clone(), edges[inputLength][minimalJ.unwrap()][minimalK.unwrap()]
.as_ref()
.unwrap()
.clone(),
self.isGS1, self.isGS1,
&self.ecLevel, &self.ecLevel,
self.encoders.clone(), self.encoders.clone(),
@@ -807,9 +810,9 @@ impl RXingResultList {
)); ));
} }
} }
let first = list.get(0).unwrap(); let first = list.get(0);
// prepend or insert a FNC1_FIRST_POSITION after the ECI (if any) // prepend or insert a FNC1_FIRST_POSITION after the ECI (if any)
// if first != null && first.mode != Mode.ECI && containsECI { if first.is_some() && first.as_ref().unwrap().mode != Mode::ECI && containsECI {
list.push(RXingResultNode::new( list.push(RXingResultNode::new(
Mode::FNC1_FIRST_POSITION, Mode::FNC1_FIRST_POSITION,
0, 0,
@@ -820,6 +823,7 @@ impl RXingResultList {
version, version,
)); ));
} }
}
// set version to smallest version into which the bits fit. // set version to smallest version into which the bits fit.
let mut versionNumber = version.getVersionNumber(); let mut versionNumber = version.getVersionNumber();
@@ -867,6 +871,7 @@ impl RXingResultList {
versionNumber -= 1; versionNumber -= 1;
} }
let version = Version::getVersionForNumber(versionNumber).unwrap(); let version = Version::getVersionForNumber(versionNumber).unwrap();
list.reverse();
Self { list, version } Self { list, version }
} }