1#![allow(clippy::unreadable_literal, clippy::unusual_byte_groupings)]
2#[cfg(not(feature = "std"))]
18#[allow(unused_imports)]
19use alloc::{
20 borrow::ToOwned,
21 format,
22 string::{String, ToString},
23 vec,
24 vec::Vec,
25};
26
27use core::cmp::min;
28
29use crate::cast::{As, Truncate};
30use crate::mode::EncodingMode;
31use crate::optimize::{Optimizer, Parser, Segment, total_encoded_len};
32use crate::types::{EcLevel, Mode, QrError, QrResult, Version};
33
34#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
43#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
44pub struct EncodingModes {
45 bits: u8,
46}
47
48impl EncodingModes {
49 #[must_use]
51 pub const fn empty() -> Self {
52 Self { bits: 0 }
53 }
54
55 #[must_use]
57 pub const fn from_mode(mode: Mode) -> Self {
58 Self { bits: mode_bit(mode) }
59 }
60
61 #[must_use]
63 pub const fn contains(self, mode: Mode) -> bool {
64 self.bits & mode_bit(mode) != 0
65 }
66
67 #[must_use]
69 pub const fn is_empty(self) -> bool {
70 self.bits == 0
71 }
72
73 #[must_use]
75 pub const fn len(self) -> usize {
76 (self.contains(Mode::Numeric) as usize)
77 + (self.contains(Mode::Alphanumeric) as usize)
78 + (self.contains(Mode::Byte) as usize)
79 + (self.contains(Mode::Kanji) as usize)
80 }
81
82 pub const fn iter(self) -> EncodingModesIter {
85 EncodingModesIter { modes: self, index: 0 }
86 }
87
88 fn insert(&mut self, mode: Mode) {
89 self.bits |= mode_bit(mode);
90 }
91}
92
93#[derive(Clone, Debug)]
95pub struct EncodingModesIter {
96 modes: EncodingModes,
97 index: u8,
98}
99
100impl Iterator for EncodingModesIter {
101 type Item = Mode;
102
103 fn next(&mut self) -> Option<Self::Item> {
104 while self.index < 4 {
105 let mode = match self.index {
106 0 => Mode::Numeric,
107 1 => Mode::Alphanumeric,
108 2 => Mode::Byte,
109 _ => Mode::Kanji,
110 };
111 self.index += 1;
112 if self.modes.contains(mode) {
113 return Some(mode);
114 }
115 }
116 None
117 }
118
119 fn size_hint(&self) -> (usize, Option<usize>) {
120 let remaining = self.modes.iter().skip(self.index as usize).count();
121 (remaining, Some(remaining))
122 }
123}
124
125impl ExactSizeIterator for EncodingModesIter {}
126impl core::iter::FusedIterator for EncodingModesIter {}
127
128const fn mode_bit(mode: Mode) -> u8 {
129 match mode {
130 Mode::Numeric => 1 << 0,
131 Mode::Alphanumeric => 1 << 1,
132 Mode::Byte => 1 << 2,
133 Mode::Kanji => 1 << 3,
134 }
135}
136
137pub struct Bits {
139 data: Vec<u8>,
140 bit_offset: usize,
141 version: Version,
142 encoding_modes: EncodingModes,
143 payload_bits_len: Option<usize>,
144}
145
146impl Bits {
147 pub const fn new(version: Version) -> Self {
149 Self {
150 data: Vec::new(),
151 bit_offset: 0,
152 version,
153 encoding_modes: EncodingModes::empty(),
154 payload_bits_len: None,
155 }
156 }
157
158 fn push_number(&mut self, n: usize, number: u16) {
164 debug_assert!(n == 16 || n < 16 && number < (1 << n), "{number} is too big as a {n}-bit number");
165
166 let b = self.bit_offset + n;
167 let last_index = self.data.len().wrapping_sub(1);
168 match (self.bit_offset, b) {
169 (0, 0..=8) => {
170 self.data.push((number << (8 - b)).truncate_as_u8());
171 }
172 (0, _) => {
173 self.data.push((number >> (b - 8)).truncate_as_u8());
174 self.data.push((number << (16 - b)).truncate_as_u8());
175 }
176 (_, 0..=8) => {
177 self.data[last_index] |= (number << (8 - b)).truncate_as_u8();
178 }
179 (_, 9..=16) => {
180 self.data[last_index] |= (number >> (b - 8)).truncate_as_u8();
181 self.data.push((number << (16 - b)).truncate_as_u8());
182 }
183 _ => {
184 self.data[last_index] |= (number >> (b - 8)).truncate_as_u8();
185 self.data.push((number >> (b - 16)).truncate_as_u8());
186 self.data.push((number << (24 - b)).truncate_as_u8());
187 }
188 }
189 self.bit_offset = b & 7;
190 }
191
192 pub fn push_number_checked(&mut self, n: usize, number: usize) -> QrResult<()> {
197 if n > 16 || number >= (1 << n) {
198 Err(QrError::DataTooLong)
199 } else {
200 self.push_number(n, number.as_u16());
201 Ok(())
202 }
203 }
204
205 pub fn reserve(&mut self, n: usize) {
207 let extra_bytes = (n + (8 - self.bit_offset) % 8) / 8;
208 self.data.reserve(extra_bytes);
209 }
210
211 pub fn into_bytes(self) -> Vec<u8> {
213 self.data
214 }
215
216 pub fn len(&self) -> usize {
218 if self.bit_offset == 0 { self.data.len() * 8 } else { (self.data.len() - 1) * 8 + self.bit_offset }
219 }
220
221 pub fn is_empty(&self) -> bool {
223 self.data.is_empty()
224 }
225
226 pub fn max_len(&self, ec_level: EcLevel) -> QrResult<usize> {
235 self.version.fetch(ec_level, &DATA_LENGTHS)
236 }
237
238 pub fn version(&self) -> Version {
240 self.version
241 }
242
243 #[must_use]
245 pub const fn encoding_modes(&self) -> EncodingModes {
246 self.encoding_modes
247 }
248
249 #[must_use]
254 pub fn payload_bits_len(&self) -> usize {
255 match self.payload_bits_len {
256 Some(len) => len,
257 None => self.len(),
258 }
259 }
260
261 pub fn remaining_capacity_bits(&self, ec_level: EcLevel) -> QrResult<usize> {
268 Ok(self.max_len(ec_level)?.saturating_sub(self.payload_bits_len()))
269 }
270}
271
272#[test]
273fn test_push_number() {
274 let mut bits = Bits::new(Version::Normal(1));
275
276 bits.push_number(3, 0b010); bits.push_number(3, 0b110); bits.push_number(3, 0b101); bits.push_number(7, 0b001_1010); bits.push_number(4, 0b1100); bits.push_number(12, 0b1011_0110_1101); bits.push_number(10, 0b01_1001_0001); bits.push_number(15, 0b111_0010_1110_0011); let bytes = bits.into_bytes();
286
287 assert_eq!(
288 bytes,
289 vec![
290 0b010_110_10, 0b1_001_1010, 0b1100_1011, 0b0110_1101, 0b01_1001_00, 0b01_111_001, 0b0_1110_001, 0b1_0000000, ]
299 );
300}
301
302#[cfg(test)]
303mod metadata_tests {
304 use crate::bits::{Bits, EncodingModes};
305 use crate::types::{EcLevel, Mode, Version};
306
307 #[test]
308 fn encoding_modes_iterates_in_stable_mode_order() {
309 let modes = EncodingModes::from_mode(Mode::Byte);
310 let mut modes_with_numeric = modes;
311 modes_with_numeric.insert(Mode::Numeric);
312
313 assert_eq!(modes_with_numeric.iter().collect::<Vec<_>>(), vec![Mode::Numeric, Mode::Byte]);
314 }
315
316 #[test]
317 fn bits_records_successful_payload_modes() {
318 let mut bits = Bits::new(Version::Normal(1));
319
320 bits.push_numeric_data(b"012").unwrap();
321 bits.push_byte_data(b"abc").unwrap();
322
323 assert!(bits.encoding_modes().contains(Mode::Numeric));
324 assert!(bits.encoding_modes().contains(Mode::Byte));
325 assert!(!bits.encoding_modes().contains(Mode::Kanji));
326 }
327
328 #[test]
329 fn remaining_capacity_uses_payload_len_before_padding() {
330 let mut bits = Bits::new(Version::Normal(1));
331
332 bits.push_numeric_data(b"01234567").unwrap();
333 bits.push_terminator(EcLevel::M).unwrap();
334
335 assert_eq!(bits.len(), 128);
336 assert_eq!(bits.payload_bits_len(), 41);
337 assert_eq!(bits.remaining_capacity_bits(EcLevel::M), Ok(87));
338 }
339}
340
341#[derive(Copy, Clone)]
348pub enum ExtendedMode {
349 Eci,
351
352 Data(Mode),
354
355 Fnc1First,
357
358 Fnc1Second,
360
361 StructuredAppend,
363}
364
365impl Bits {
366 pub fn push_mode_indicator(&mut self, mode: ExtendedMode) -> QrResult<()> {
373 #[allow(clippy::match_same_arms)]
374 let number = match (self.version, mode) {
375 (Version::Micro(1), ExtendedMode::Data(Mode::Numeric)) => return Ok(()),
376 (Version::Micro(_), ExtendedMode::Data(Mode::Numeric)) => 0,
377 (Version::Micro(_), ExtendedMode::Data(Mode::Alphanumeric)) => 1,
378 (Version::Micro(_), ExtendedMode::Data(Mode::Byte)) => 0b10,
379 (Version::Micro(_), ExtendedMode::Data(Mode::Kanji)) => 0b11,
380 (Version::Micro(_), _) => return Err(QrError::UnsupportedCharacterSet),
381 (_, ExtendedMode::Data(Mode::Numeric)) => 0b0001,
382 (_, ExtendedMode::Data(Mode::Alphanumeric)) => 0b0010,
383 (_, ExtendedMode::Data(Mode::Byte)) => 0b0100,
384 (_, ExtendedMode::Data(Mode::Kanji)) => 0b1000,
385 (_, ExtendedMode::Eci) => 0b0111,
386 (_, ExtendedMode::Fnc1First) => 0b0101,
387 (_, ExtendedMode::Fnc1Second) => 0b1001,
388 (_, ExtendedMode::StructuredAppend) => 0b0011,
389 };
390 let bits = self.version.mode_bits_count();
391 self.push_number_checked(bits, number).or(Err(QrError::UnsupportedCharacterSet))
392 }
393}
394
395impl Bits {
400 pub fn push_eci_designator(&mut self, eci_designator: u32) -> QrResult<()> {
438 self.reserve(12); self.push_mode_indicator(ExtendedMode::Eci)?;
440 match eci_designator {
441 0..=127 => {
442 self.push_number(8, eci_designator.as_u16());
443 }
444 128..=16383 => {
445 self.push_number(2, 0b10);
446 self.push_number(14, eci_designator.as_u16());
447 }
448 16384..=999_999 => {
449 self.push_number(3, 0b110);
450 self.push_number(5, (eci_designator >> 16).as_u16());
451 self.push_number(16, (eci_designator & 0xffff).as_u16());
452 }
453 _ => return Err(QrError::InvalidEciDesignator { value: eci_designator }),
454 }
455 Ok(())
456 }
457}
458
459#[cfg(test)]
460mod eci_tests {
461 use crate::bits::Bits;
462 use crate::types::{QrError, Version};
463
464 #[test]
465 fn test_9() {
466 let mut bits = Bits::new(Version::Normal(1));
467 assert_eq!(bits.push_eci_designator(9), Ok(()));
468 assert_eq!(bits.into_bytes(), vec![0b0111_0000, 0b1001_0000]);
469 }
470
471 #[test]
472 fn test_899() {
473 let mut bits = Bits::new(Version::Normal(1));
474 assert_eq!(bits.push_eci_designator(899), Ok(()));
475 assert_eq!(bits.into_bytes(), vec![0b0111_10_00, 0b00111000, 0b0011_0000]);
476 }
477
478 #[test]
479 fn test_999999() {
480 let mut bits = Bits::new(Version::Normal(1));
481 assert_eq!(bits.push_eci_designator(999999), Ok(()));
482 assert_eq!(bits.into_bytes(), vec![0b0111_110_0, 0b11110100, 0b00100011, 0b1111_0000]);
483 }
484
485 #[test]
486 fn test_invalid_designator() {
487 let mut bits = Bits::new(Version::Normal(1));
488 assert_eq!(bits.push_eci_designator(1000000), Err(QrError::InvalidEciDesignator { value: 1000000 }));
489 }
490
491 #[test]
492 fn test_unsupported_character_set() {
493 let mut bits = Bits::new(Version::Micro(4));
494 assert_eq!(bits.push_eci_designator(9), Err(QrError::UnsupportedCharacterSet));
495 }
496}
497
498impl Bits {
503 fn push_header(&mut self, mode: Mode, raw_data_len: usize) -> QrResult<()> {
504 let length_bits = mode.length_bits_count(self.version);
505 self.reserve(length_bits + 4 + mode.data_bits_count(raw_data_len));
506 self.push_mode_indicator(ExtendedMode::Data(mode))?;
507 self.push_number_checked(length_bits, raw_data_len)?;
508 Ok(())
509 }
510
511 pub fn push_numeric_data(&mut self, data: &[u8]) -> QrResult<()> {
519 self.push_header(Mode::Numeric, data.len())?;
520 for chunk in data.chunks(3) {
521 let number = chunk.iter().map(|b| u16::from(*b - b'0')).fold(0, |a, b| a * 10 + b);
522 let length = chunk.len() * 3 + 1;
523 self.push_number(length, number);
524 }
525 self.encoding_modes.insert(Mode::Numeric);
526 self.payload_bits_len = None;
527 Ok(())
528 }
529}
530
531#[cfg(test)]
532mod numeric_tests {
533 use crate::bits::Bits;
534 use crate::types::{QrError, Version};
535
536 #[test]
537 fn test_iso_18004_2006_example_1() {
538 let mut bits = Bits::new(Version::Normal(1));
539 assert_eq!(bits.push_numeric_data(b"01234567"), Ok(()));
540 assert_eq!(bits.into_bytes(), vec![0b0001_0000, 0b001000_00, 0b00001100, 0b01010110, 0b01_100001, 0b1_0000000]);
541 }
542
543 #[test]
544 fn test_iso_18004_2000_example_2() {
545 let mut bits = Bits::new(Version::Normal(1));
546 assert_eq!(bits.push_numeric_data(b"0123456789012345"), Ok(()));
547 assert_eq!(
548 bits.into_bytes(),
549 vec![
550 0b0001_0000,
551 0b010000_00,
552 0b00001100,
553 0b01010110,
554 0b01_101010,
555 0b0110_1110,
556 0b000101_00,
557 0b11101010,
558 0b0101_0000,
559 ]
560 );
561 }
562
563 #[test]
564 fn test_iso_18004_2006_example_2() {
565 let mut bits = Bits::new(Version::Micro(3));
566 assert_eq!(bits.push_numeric_data(b"0123456789012345"), Ok(()));
567 assert_eq!(
568 bits.into_bytes(),
569 vec![0b00_10000_0, 0b00000110, 0b0_0101011, 0b001_10101, 0b00110_111, 0b0000101_0, 0b01110101, 0b00101_000,]
570 );
571 }
572
573 #[test]
574 fn test_data_too_long_error() {
575 let mut bits = Bits::new(Version::Micro(1));
576 assert_eq!(bits.push_numeric_data(b"12345678"), Err(QrError::DataTooLong));
577 }
578}
579
580#[inline]
590fn alphanumeric_digit(character: u8) -> u16 {
591 match character {
592 b'0'..=b'9' => u16::from(character - b'0'),
593 b'A'..=b'Z' => u16::from(character - b'A') + 10,
594 b' ' => 36,
595 b'$' => 37,
596 b'%' => 38,
597 b'*' => 39,
598 b'+' => 40,
599 b'-' => 41,
600 b'.' => 42,
601 b'/' => 43,
602 b':' => 44,
603 _ => 0,
604 }
605}
606
607impl Bits {
608 pub fn push_alphanumeric_data(&mut self, data: &[u8]) -> QrResult<()> {
617 self.push_header(Mode::Alphanumeric, data.len())?;
618 for chunk in data.chunks(2) {
619 let number = chunk.iter().map(|b| alphanumeric_digit(*b)).fold(0, |a, b| a * 45 + b);
620 let length = chunk.len() * 5 + 1;
621 self.push_number(length, number);
622 }
623 self.encoding_modes.insert(Mode::Alphanumeric);
624 self.payload_bits_len = None;
625 Ok(())
626 }
627}
628
629#[cfg(test)]
630mod alphanumeric_tests {
631 use crate::bits::Bits;
632 use crate::types::{QrError, Version};
633
634 #[test]
635 fn test_iso_18004_2006_example() {
636 let mut bits = Bits::new(Version::Normal(1));
637 assert_eq!(bits.push_alphanumeric_data(b"AC-42"), Ok(()));
638 assert_eq!(bits.into_bytes(), vec![0b0010_0000, 0b00101_001, 0b11001110, 0b11100111, 0b001_00001, 0b0_0000000]);
639 }
640
641 #[test]
642 fn test_micro_qr_unsupported() {
643 let mut bits = Bits::new(Version::Micro(1));
644 assert_eq!(bits.push_alphanumeric_data(b"A"), Err(QrError::UnsupportedCharacterSet));
645 }
646
647 #[test]
648 fn test_data_too_long() {
649 let mut bits = Bits::new(Version::Micro(2));
650 assert_eq!(bits.push_alphanumeric_data(b"ABCDEFGH"), Err(QrError::DataTooLong));
651 }
652}
653
654impl Bits {
659 pub fn push_byte_data(&mut self, data: &[u8]) -> QrResult<()> {
665 self.push_header(Mode::Byte, data.len())?;
666 for b in data {
667 self.push_number(8, u16::from(*b));
668 }
669 self.encoding_modes.insert(Mode::Byte);
670 self.payload_bits_len = None;
671 Ok(())
672 }
673}
674
675#[cfg(test)]
676mod byte_tests {
677 use crate::bits::Bits;
678 use crate::types::{QrError, Version};
679
680 #[test]
681 fn test() {
682 let mut bits = Bits::new(Version::Normal(1));
683 assert_eq!(bits.push_byte_data(b"\x12\x34\x56\x78\x9a\xbc\xde\xf0"), Ok(()));
684 assert_eq!(
685 bits.into_bytes(),
686 vec![
687 0b0100_0000,
688 0b1000_0001,
689 0b0010_0011,
690 0b0100_0101,
691 0b0110_0111,
692 0b1000_1001,
693 0b1010_1011,
694 0b1100_1101,
695 0b1110_1111,
696 0b0000_0000,
697 ]
698 );
699 }
700
701 #[test]
702 fn test_micro_qr_unsupported() {
703 let mut bits = Bits::new(Version::Micro(2));
704 assert_eq!(bits.push_byte_data(b"?"), Err(QrError::UnsupportedCharacterSet));
705 }
706
707 #[test]
708 fn test_data_too_long() {
709 let mut bits = Bits::new(Version::Micro(3));
710 assert_eq!(bits.push_byte_data(b"0123456701234567"), Err(QrError::DataTooLong));
711 }
712}
713
714impl Bits {
719 pub fn push_kanji_data(&mut self, data: &[u8]) -> QrResult<()> {
728 self.push_header(Mode::Kanji, data.len() / 2)?;
729 for (i, kanji) in data.chunks(2).enumerate() {
730 if kanji.len() != 2 {
731 return Err(QrError::InvalidCharacter { position: i * 2, byte: kanji[0] });
732 }
733 let cp = u16::from(kanji[0]) * 256 + u16::from(kanji[1]);
734 let bytes = if cp < 0xe040 { cp - 0x8140 } else { cp - 0xc140 };
735 let number = (bytes >> 8) * 0xc0 + (bytes & 0xff);
736 self.push_number(13, number);
737 }
738 self.encoding_modes.insert(Mode::Kanji);
739 self.payload_bits_len = None;
740 Ok(())
741 }
742}
743
744impl Bits {
745 pub fn push_mode_data<M: EncodingMode>(&mut self, data: &[u8]) -> QrResult<()> {
759 if let Some((position, byte)) = M::invalid_character(data) {
760 return Err(QrError::InvalidCharacter { position, byte });
761 }
762
763 match M::MODE {
764 Mode::Numeric => self.push_numeric_data(data),
765 Mode::Alphanumeric => self.push_alphanumeric_data(data),
766 Mode::Byte => self.push_byte_data(data),
767 Mode::Kanji => self.push_kanji_data(data),
768 }
769 }
770}
771
772#[cfg(test)]
773mod typed_mode_tests {
774 use crate::bits::Bits;
775 use crate::mode::{AlphanumericMode, ByteMode, KanjiMode, NumericMode};
776 use crate::types::{QrError, Version};
777
778 #[test]
779 fn push_mode_data_matches_numeric_specific_encoder() {
780 let mut typed = Bits::new(Version::Normal(1));
781 let mut direct = Bits::new(Version::Normal(1));
782
783 assert_eq!(typed.push_mode_data::<NumericMode>(b"01234567"), Ok(()));
784 assert_eq!(direct.push_numeric_data(b"01234567"), Ok(()));
785 assert_eq!(typed.into_bytes(), direct.into_bytes());
786 }
787
788 #[test]
789 fn push_mode_data_matches_other_specific_encoders() {
790 let mut alphanumeric = Bits::new(Version::Normal(1));
791 let mut byte = Bits::new(Version::Normal(1));
792 let mut kanji = Bits::new(Version::Normal(1));
793
794 assert_eq!(alphanumeric.push_mode_data::<AlphanumericMode>(b"AC-42"), Ok(()));
795 assert_eq!(byte.push_mode_data::<ByteMode>(b"\x12\x34"), Ok(()));
796 assert_eq!(kanji.push_mode_data::<KanjiMode>(b"\x93\x5f\xe4\xaa"), Ok(()));
797 }
798
799 #[test]
800 fn push_mode_data_rejects_invalid_mode_input_before_writing() {
801 let mut bits = Bits::new(Version::Normal(1));
802
803 assert_eq!(
804 bits.push_mode_data::<NumericMode>(b"12a"),
805 Err(QrError::InvalidCharacter { position: 2, byte: b'a' })
806 );
807 assert!(bits.into_bytes().is_empty());
808 }
809}
810
811#[cfg(test)]
812mod kanji_tests {
813 use crate::bits::Bits;
814 use crate::types::{QrError, Version};
815
816 #[test]
817 fn test_iso_18004_example() {
818 let mut bits = Bits::new(Version::Normal(1));
819 assert_eq!(bits.push_kanji_data(b"\x93\x5f\xe4\xaa"), Ok(()));
820 assert_eq!(bits.into_bytes(), vec![0b1000_0000, 0b0010_0110, 0b11001111, 0b1_1101010, 0b101010_00]);
821 }
822
823 #[test]
824 fn test_micro_qr_unsupported() {
825 let mut bits = Bits::new(Version::Micro(2));
826 assert_eq!(bits.push_kanji_data(b"?"), Err(QrError::UnsupportedCharacterSet));
827 }
828
829 #[test]
830 fn test_data_too_long() {
831 let mut bits = Bits::new(Version::Micro(3));
832 assert_eq!(bits.push_kanji_data(b"\x93_\x93_\x93_\x93_\x93_\x93_\x93_\x93_"), Err(QrError::DataTooLong));
833 }
834}
835
836impl Bits {
841 pub fn push_fnc1_first_position(&mut self) -> QrResult<()> {
861 self.push_mode_indicator(ExtendedMode::Fnc1First)
862 }
863
864 pub fn push_fnc1_second_position(&mut self, application_indicator: u8) -> QrResult<()> {
890 self.push_mode_indicator(ExtendedMode::Fnc1Second)?;
891 self.push_number(8, u16::from(application_indicator));
892 Ok(())
893 }
894}
895
896impl Bits {
901 pub fn push_structured_append_header(&mut self, position: u8, total: u8, parity: u8) -> QrResult<()> {
933 if self.version.is_micro() {
934 return Err(QrError::UnsupportedCharacterSet);
935 }
936 if !(2..=16).contains(&total) || !(1..=total).contains(&position) {
937 return Err(QrError::InvalidStructuredAppend {
938 value: if !(2..=16).contains(&total) { total } else { position },
939 });
940 }
941 let sequence = (u16::from(position - 1) << 4) | u16::from(total - 1);
944 self.reserve(20);
945 self.push_mode_indicator(ExtendedMode::StructuredAppend)?;
946 self.push_number(8, sequence);
947 self.push_number(8, u16::from(parity));
948 Ok(())
949 }
950}
951
952#[cfg(test)]
953mod structured_append_tests {
954 use crate::bits::Bits;
955 use crate::types::{EcLevel, QrError, Version};
956
957 #[test]
958 fn test_header_bit_layout() {
959 let mut bits = Bits::new(Version::Normal(1));
962 assert_eq!(bits.push_structured_append_header(1, 3, 0x5a), Ok(()));
963 assert_eq!(bits.into_bytes(), vec![0x30, 0x25, 0xA0]);
964 }
965
966 #[test]
967 fn test_header_bit_layout_second_of_two() {
968 let mut bits = Bits::new(Version::Normal(1));
972 assert_eq!(bits.push_structured_append_header(2, 2, 0xff), Ok(()));
973 assert_eq!(bits.into_bytes(), vec![0x31, 0x1F, 0xF0]);
974 }
975
976 #[test]
977 fn test_header_value_16_uses_max_nibble() {
978 let mut bits = Bits::new(Version::Normal(1));
981 assert_eq!(bits.push_structured_append_header(16, 16, 0x00), Ok(()));
982 assert_eq!(bits.into_bytes(), vec![0x3F, 0xF0, 0x00]);
983 }
984
985 #[test]
986 fn test_micro_rejected() {
987 let mut bits = Bits::new(Version::Micro(2));
988 assert_eq!(bits.push_structured_append_header(1, 2, 0), Err(QrError::UnsupportedCharacterSet));
989 }
990
991 #[test]
992 fn test_invalid_total() {
993 let mut bits = Bits::new(Version::Normal(1));
994 assert_eq!(bits.push_structured_append_header(1, 1, 0), Err(QrError::InvalidStructuredAppend { value: 1 }));
995 assert_eq!(bits.push_structured_append_header(1, 17, 0), Err(QrError::InvalidStructuredAppend { value: 17 }));
996 }
997
998 #[test]
999 fn test_invalid_position() {
1000 let mut bits = Bits::new(Version::Normal(1));
1001 assert_eq!(bits.push_structured_append_header(0, 3, 0), Err(QrError::InvalidStructuredAppend { value: 0 }));
1002 assert_eq!(bits.push_structured_append_header(4, 3, 0), Err(QrError::InvalidStructuredAppend { value: 4 }));
1003 }
1004
1005 #[test]
1006 fn test_header_then_data_round_trips() {
1007 let mut bits = Bits::new(Version::Normal(1));
1009 bits.push_structured_append_header(1, 2, 0).unwrap();
1010 bits.push_byte_data(b"ab").unwrap();
1011 assert!(bits.push_terminator(EcLevel::M).is_ok());
1012 }
1013}
1014
1015static DATA_LENGTHS: [[usize; 4]; 44] = [
1021 [152, 128, 104, 72],
1023 [272, 224, 176, 128],
1024 [440, 352, 272, 208],
1025 [640, 512, 384, 288],
1026 [864, 688, 496, 368],
1027 [1088, 864, 608, 480],
1028 [1248, 992, 704, 528],
1029 [1552, 1232, 880, 688],
1030 [1856, 1456, 1056, 800],
1031 [2192, 1728, 1232, 976],
1032 [2592, 2032, 1440, 1120],
1033 [2960, 2320, 1648, 1264],
1034 [3424, 2672, 1952, 1440],
1035 [3688, 2920, 2088, 1576],
1036 [4184, 3320, 2360, 1784],
1037 [4712, 3624, 2600, 2024],
1038 [5176, 4056, 2936, 2264],
1039 [5768, 4504, 3176, 2504],
1040 [6360, 5016, 3560, 2728],
1041 [6888, 5352, 3880, 3080],
1042 [7456, 5712, 4096, 3248],
1043 [8048, 6256, 4544, 3536],
1044 [8752, 6880, 4912, 3712],
1045 [9392, 7312, 5312, 4112],
1046 [10208, 8000, 5744, 4304],
1047 [10960, 8496, 6032, 4768],
1048 [11744, 9024, 6464, 5024],
1049 [12248, 9544, 6968, 5288],
1050 [13048, 10136, 7288, 5608],
1051 [13880, 10984, 7880, 5960],
1052 [14744, 11640, 8264, 6344],
1053 [15640, 12328, 8920, 6760],
1054 [16568, 13048, 9368, 7208],
1055 [17528, 13800, 9848, 7688],
1056 [18448, 14496, 10288, 7888],
1057 [19472, 15312, 10832, 8432],
1058 [20528, 15936, 11408, 8768],
1059 [21616, 16816, 12016, 9136],
1060 [22496, 17728, 12656, 9776],
1061 [23648, 18672, 13328, 10208],
1062 [20, 0, 0, 0],
1064 [40, 32, 0, 0],
1065 [84, 68, 0, 0],
1066 [128, 112, 80, 0],
1067];
1068
1069impl Bits {
1070 pub fn push_terminator(&mut self, ec_level: EcLevel) -> QrResult<()> {
1080 let terminator_size = match self.version {
1081 Version::Micro(a) => a.as_usize() * 2 + 1,
1082 Version::Normal(_) => 4,
1083 };
1084
1085 let cur_length = self.len();
1086 let data_length = self.max_len(ec_level)?;
1087 if cur_length > data_length {
1088 return Err(QrError::DataTooLong);
1089 }
1090 self.payload_bits_len = Some(cur_length);
1091
1092 let terminator_size = min(terminator_size, data_length - cur_length);
1093 if terminator_size > 0 {
1094 self.push_number(terminator_size, 0);
1095 }
1096
1097 if self.len() < data_length {
1098 const PADDING_BYTES: &[u8] = &[0b1110_1100, 0b0001_0001];
1099
1100 self.bit_offset = 0;
1101 let data_bytes_length = data_length / 8;
1102 let padding_bytes_count = data_bytes_length.saturating_sub(self.data.len());
1103 let padding = PADDING_BYTES.iter().copied().cycle().take(padding_bytes_count);
1104 self.data.extend(padding);
1105 }
1106
1107 if self.len() < data_length {
1108 self.data.push(0);
1109 }
1110
1111 Ok(())
1112 }
1113}
1114
1115#[cfg(test)]
1116mod finish_tests {
1117 use crate::bits::Bits;
1118 use crate::types::{EcLevel, QrError, Version};
1119
1120 #[test]
1121 fn test_hello_world() {
1122 let mut bits = Bits::new(Version::Normal(1));
1123 assert_eq!(bits.push_alphanumeric_data(b"HELLO WORLD"), Ok(()));
1124 assert_eq!(bits.push_terminator(EcLevel::Q), Ok(()));
1125 assert_eq!(
1126 bits.into_bytes(),
1127 vec![
1128 0b00100000, 0b01011011, 0b00001011, 0b01111000, 0b11010001, 0b01110010, 0b11011100, 0b01001101,
1129 0b01000011, 0b01000000, 0b11101100, 0b00010001, 0b11101100,
1130 ]
1131 );
1132 }
1133
1134 #[test]
1135 fn test_too_long() {
1136 let mut bits = Bits::new(Version::Micro(1));
1137 assert_eq!(bits.push_numeric_data(b"9999999"), Ok(()));
1138 assert_eq!(bits.push_terminator(EcLevel::L), Err(QrError::DataTooLong));
1139 }
1140
1141 #[test]
1142 fn test_no_terminator() {
1143 let mut bits = Bits::new(Version::Micro(1));
1144 assert_eq!(bits.push_numeric_data(b"99999"), Ok(()));
1145 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
1146 assert_eq!(bits.into_bytes(), vec![0b101_11111, 0b00111_110, 0b0011_0000]);
1147 }
1148
1149 #[test]
1150 fn test_no_padding() {
1151 let mut bits = Bits::new(Version::Micro(1));
1152 assert_eq!(bits.push_numeric_data(b"9999"), Ok(()));
1153 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
1154 assert_eq!(bits.into_bytes(), vec![0b100_11111, 0b00111_100, 0b1_000_0000]);
1155 }
1156
1157 #[test]
1158 fn test_micro_version_1_half_byte_padding() {
1159 let mut bits = Bits::new(Version::Micro(1));
1160 assert_eq!(bits.push_numeric_data(b"999"), Ok(()));
1161 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
1162 assert_eq!(bits.into_bytes(), vec![0b011_11111, 0b00111_000, 0b0000_0000]);
1163 }
1164
1165 #[test]
1166 fn test_micro_version_1_full_byte_padding() {
1167 let mut bits = Bits::new(Version::Micro(1));
1168 assert_eq!(bits.push_numeric_data(b""), Ok(()));
1169 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
1170 assert_eq!(bits.into_bytes(), vec![0b000_000_00, 0b11101100, 0]);
1171 }
1172}
1173
1174impl Bits {
1179 pub fn push_segments<I>(&mut self, data: &[u8], segments_iter: I) -> QrResult<()>
1188 where
1189 I: Iterator<Item = Segment>,
1190 {
1191 for segment in segments_iter {
1192 let slice = &data[segment.begin..segment.end];
1193 match segment.mode {
1194 Mode::Numeric => self.push_numeric_data(slice),
1195 Mode::Alphanumeric => self.push_alphanumeric_data(slice),
1196 Mode::Byte => self.push_byte_data(slice),
1197 Mode::Kanji => self.push_kanji_data(slice),
1198 }?;
1199 }
1200 Ok(())
1201 }
1202
1203 pub fn push_optimal_data(&mut self, data: &[u8]) -> QrResult<()> {
1209 let segments = Parser::new(data).optimize(self.version);
1210 self.push_segments(data, segments)
1211 }
1212}
1213
1214#[cfg(test)]
1215mod encode_tests {
1216 use crate::bits::Bits;
1217 use crate::types::{EcLevel, QrError, QrResult, Version};
1218
1219 fn encode(data: &[u8], version: Version, ec_level: EcLevel) -> QrResult<Vec<u8>> {
1220 let mut bits = Bits::new(version);
1221 bits.push_optimal_data(data)?;
1222 bits.push_terminator(ec_level)?;
1223 Ok(bits.into_bytes())
1224 }
1225
1226 #[test]
1227 fn test_alphanumeric() {
1228 let res = encode(b"HELLO WORLD", Version::Normal(1), EcLevel::Q);
1229 assert_eq!(
1230 res,
1231 Ok(vec![
1232 0b00100000, 0b01011011, 0b00001011, 0b01111000, 0b11010001, 0b01110010, 0b11011100, 0b01001101,
1233 0b01000011, 0b01000000, 0b11101100, 0b00010001, 0b11101100,
1234 ])
1235 );
1236 }
1237
1238 #[test]
1239 fn test_auto_mode_switch() {
1240 let res = encode(b"123A", Version::Micro(2), EcLevel::L);
1241 assert_eq!(res, Ok(vec![0b0_0011_000, 0b1111011_1, 0b001_00101, 0b0_00000_00, 0b11101100]));
1242 }
1243
1244 #[test]
1245 fn test_too_long() {
1246 let res = encode(b">>>>>>>>", Version::Normal(1), EcLevel::H);
1247 assert_eq!(res, Err(QrError::DataTooLong));
1248 }
1249}
1250
1251pub fn data_capacity_bits(version: Version, ec_level: EcLevel) -> QrResult<usize> {
1264 version.fetch(ec_level, &DATA_LENGTHS)
1265}
1266
1267pub fn encode_auto(data: &[u8], ec_level: EcLevel) -> QrResult<Bits> {
1277 if data.len() > crate::limits::DEFAULT_MAX_DATA_LENGTH {
1278 return Err(QrError::DataTooLong);
1279 }
1280 encode_auto_with_max_version(data, ec_level, 40)
1281}
1282
1283pub fn encode_auto_with_max_version(data: &[u8], ec_level: EcLevel, max_version: i16) -> QrResult<Bits> {
1290 if !(1..=40).contains(&max_version) {
1291 return Err(QrError::InvalidResourceLimits);
1292 }
1293 let segments = Parser::new(data).collect::<Vec<Segment>>();
1294 let mut checkpoints = [0_i16; 4];
1295 let mut checkpoint_count = 0;
1296 for candidate in [9_i16, 26, 40, max_version] {
1297 if candidate <= max_version && !checkpoints[..checkpoint_count].contains(&candidate) {
1298 checkpoints[checkpoint_count] = candidate;
1299 checkpoint_count += 1;
1300 }
1301 }
1302 for candidate in checkpoints[..checkpoint_count].iter() {
1303 let version = Version::Normal(*candidate);
1304 let opt_segments = Optimizer::new(segments.iter().copied(), version).collect::<Vec<_>>();
1305 let total_len = total_encoded_len(&opt_segments, version);
1306 let data_capacity = version.fetch(ec_level, &DATA_LENGTHS)?;
1307 if total_len <= data_capacity {
1308 let min_version = find_min_version_up_to(total_len, ec_level, *candidate);
1309 let mut bits = Bits::new(min_version);
1310 bits.reserve(total_len);
1311 bits.push_segments(data, opt_segments.into_iter())?;
1312 bits.push_terminator(ec_level)?;
1313 return Ok(bits);
1314 }
1315 }
1316 Err(QrError::DataTooLong)
1317}
1318
1319fn find_min_version_up_to(length: usize, ec_level: EcLevel, max_version: i16) -> Version {
1320 for version in 1..=max_version {
1321 if DATA_LENGTHS[(version - 1) as usize][ec_level as usize] >= length {
1322 return Version::Normal(version);
1323 }
1324 }
1325 Version::Normal(max_version)
1326}
1327
1328pub fn encode_auto_micro(data: &[u8], ec_level: EcLevel) -> QrResult<Bits> {
1341 if data.len() > crate::limits::DEFAULT_MAX_DATA_LENGTH {
1342 return Err(QrError::DataTooLong);
1343 }
1344 let segments = Parser::new(data).collect::<Vec<Segment>>();
1345 for micro_version in 1..=4 {
1346 let version = Version::Micro(micro_version);
1347 let data_capacity = match version.fetch(ec_level, &DATA_LENGTHS) {
1348 Ok(cap) if cap > 0 => cap,
1349 _ => continue,
1350 };
1351 let opt_segments = Optimizer::new(segments.iter().copied(), version).collect::<Vec<_>>();
1352 let total_len = total_encoded_len(&opt_segments, version);
1353 if total_len <= data_capacity {
1354 let mut bits = Bits::new(version);
1355 bits.reserve(total_len);
1356 bits.push_segments(data, opt_segments.into_iter())?;
1357 bits.push_terminator(ec_level)?;
1358 return Ok(bits);
1359 }
1360 }
1361 Err(QrError::DataTooLong)
1362}
1363
1364pub fn find_min_version(length: usize, ec_level: EcLevel) -> Version {
1367 let mut base = 0_usize;
1368 let mut size = 39;
1369 while size > 1 {
1370 let half = size / 2;
1371 let mid = base + half;
1372 base = if DATA_LENGTHS[mid][ec_level as usize] > length { base } else { mid };
1376 size -= half;
1377 }
1378 base = if DATA_LENGTHS[base][ec_level as usize] >= length { base } else { base + 1 };
1380 Version::Normal((base + 1).as_i16())
1381}
1382
1383#[cfg(test)]
1384mod encode_auto_tests {
1385 use crate::bits::{encode_auto, encode_auto_with_max_version, find_min_version};
1386 use crate::types::{EcLevel, QrError, Version};
1387
1388 #[test]
1389 fn test_find_min_version() {
1390 assert_eq!(find_min_version(60, EcLevel::L), Version::Normal(1));
1391 assert_eq!(find_min_version(200, EcLevel::L), Version::Normal(2));
1392 assert_eq!(find_min_version(200, EcLevel::H), Version::Normal(3));
1393 assert_eq!(find_min_version(20000, EcLevel::L), Version::Normal(37));
1394 assert_eq!(find_min_version(640, EcLevel::L), Version::Normal(4));
1395 assert_eq!(find_min_version(641, EcLevel::L), Version::Normal(5));
1396 assert_eq!(find_min_version(999999, EcLevel::H), Version::Normal(40));
1397 }
1398
1399 #[test]
1400 fn test_alpha_q() {
1401 let bits = encode_auto(b"HELLO WORLD", EcLevel::Q).unwrap();
1402 assert_eq!(bits.version(), Version::Normal(1));
1403 }
1404
1405 #[test]
1406 fn test_alpha_h() {
1407 let bits = encode_auto(b"HELLO WORLD", EcLevel::H).unwrap();
1408 assert_eq!(bits.version(), Version::Normal(2));
1409 }
1410
1411 #[test]
1412 fn test_mixed() {
1413 let bits = encode_auto(b"This is a mixed data test. 1234567890", EcLevel::H).unwrap();
1414 assert_eq!(bits.version(), Version::Normal(4));
1415 }
1416
1417 #[test]
1418 fn bounded_auto_encoding_rejects_version_overflow_and_caps_search() {
1419 assert!(matches!(encode_auto_with_max_version(b"x", EcLevel::M, 0), Err(QrError::InvalidResourceLimits)));
1420 assert!(matches!(encode_auto_with_max_version(&[0_u8; 128], EcLevel::M, 1), Err(QrError::DataTooLong)));
1421 }
1422}
1423
1424