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::{AlphanumericMode, EncodingMode, KanjiMode, NumericMode};
31use crate::optimize::{Parser, Segment, optimize_segments, 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.bits & 0b1111) >> self.index).count_ones() as usize;
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
146fn additional_bytes_for_bits(bit_offset: usize, bit_count: usize) -> usize {
147 debug_assert!(bit_offset < 8);
148 let existing_space = if bit_offset == 0 { 0 } else { 8 - bit_offset };
149 bit_count.saturating_sub(existing_space).div_ceil(8)
150}
151
152impl Bits {
153 pub const fn new(version: Version) -> Self {
155 Self {
156 data: Vec::new(),
157 bit_offset: 0,
158 version,
159 encoding_modes: EncodingModes::empty(),
160 payload_bits_len: None,
161 }
162 }
163
164 fn push_number(&mut self, n: usize, number: u16) {
170 debug_assert!(n == 16 || n < 16 && number < (1 << n), "{number} is too big as a {n}-bit number");
171
172 let b = self.bit_offset + n;
173 let last_index = self.data.len().wrapping_sub(1);
174 match (self.bit_offset, b) {
175 (0, 0..=8) => {
176 self.data.push((number << (8 - b)).truncate_as_u8());
177 }
178 (0, _) => {
179 self.data.push((number >> (b - 8)).truncate_as_u8());
180 self.data.push((number << (16 - b)).truncate_as_u8());
181 }
182 (_, 0..=8) => {
183 self.data[last_index] |= (number << (8 - b)).truncate_as_u8();
184 }
185 (_, 9..=16) => {
186 self.data[last_index] |= (number >> (b - 8)).truncate_as_u8();
187 self.data.push((number << (16 - b)).truncate_as_u8());
188 }
189 _ => {
190 self.data[last_index] |= (number >> (b - 8)).truncate_as_u8();
191 self.data.push((number >> (b - 16)).truncate_as_u8());
192 self.data.push((number << (24 - b)).truncate_as_u8());
193 }
194 }
195 self.bit_offset = b & 7;
196 }
197
198 pub fn push_number_checked(&mut self, n: usize, number: usize) -> QrResult<()> {
205 if n > 16 || number >= (1 << n) {
206 Err(QrError::DataTooLong)
207 } else {
208 if n > 0 {
209 self.push_number(n, number.as_u16());
210 }
211 Ok(())
212 }
213 }
214
215 pub fn reserve(&mut self, n: usize) {
220 let extra_bytes = additional_bytes_for_bits(self.bit_offset, n);
221 self.data.reserve(extra_bytes);
222 }
223
224 pub fn into_bytes(self) -> Vec<u8> {
226 self.data
227 }
228
229 pub fn len(&self) -> usize {
231 if self.bit_offset == 0 { self.data.len() * 8 } else { (self.data.len() - 1) * 8 + self.bit_offset }
232 }
233
234 pub fn is_empty(&self) -> bool {
236 self.data.is_empty()
237 }
238
239 pub fn max_len(&self, ec_level: EcLevel) -> QrResult<usize> {
248 self.version.fetch(ec_level, &DATA_LENGTHS)
249 }
250
251 pub fn version(&self) -> Version {
253 self.version
254 }
255
256 #[must_use]
258 pub const fn encoding_modes(&self) -> EncodingModes {
259 self.encoding_modes
260 }
261
262 #[must_use]
267 pub fn payload_bits_len(&self) -> usize {
268 match self.payload_bits_len {
269 Some(len) => len,
270 None => self.len(),
271 }
272 }
273
274 pub fn remaining_capacity_bits(&self, ec_level: EcLevel) -> QrResult<usize> {
281 Ok(self.max_len(ec_level)?.saturating_sub(self.payload_bits_len()))
282 }
283}
284
285#[test]
286fn test_push_number() {
287 let mut bits = Bits::new(Version::Normal(1));
288
289 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();
299
300 assert_eq!(
301 bytes,
302 vec![
303 0b010_110_10, 0b1_001_1010, 0b1100_1011, 0b0110_1101, 0b01_1001_00, 0b01_111_001, 0b0_1110_001, 0b1_0000000, ]
312 );
313}
314
315#[cfg(test)]
316mod reservation_tests {
317 use crate::bits::{Bits, additional_bytes_for_bits};
318 use crate::types::{EcLevel, Version};
319
320 fn reference_byte_increment(offset: usize, count: usize) -> usize {
321 let total_bytes = (count as u128 + offset as u128).div_ceil(8);
322 usize::try_from(total_bytes - u128::from(offset > 0)).unwrap()
323 }
324
325 #[test]
326 fn additional_byte_increment_matches_all_small_bit_counts_and_offsets() {
327 for offset in 0..8 {
328 for count in 0..=256 {
329 assert_eq!(
330 additional_bytes_for_bits(offset, count),
331 reference_byte_increment(offset, count),
332 "offset {offset}, count {count}"
333 );
334 }
335 }
336 assert_eq!(additional_bytes_for_bits(0, 1), 1);
337 assert_eq!(additional_bytes_for_bits(7, 2), 1);
338 assert_eq!(additional_bytes_for_bits(1, 1), 0);
339 }
340
341 #[test]
342 fn additional_byte_increment_handles_usize_max_without_allocation() {
343 for offset in 0..8 {
344 for count in [usize::MAX - 8, usize::MAX - 7, usize::MAX - 1, usize::MAX] {
345 assert_eq!(additional_bytes_for_bits(offset, count), reference_byte_increment(offset, count));
346 }
347 }
348 }
349
350 fn filled_to_capacity(offset: usize) -> Bits {
351 let mut bits = Bits::new(Version::Normal(40));
352 bits.reserve(64);
353 let capacity = bits.data.capacity();
354 let whole_bytes = capacity - usize::from(offset > 0);
355 for _ in 0..whole_bytes {
356 bits.push_number_checked(8, 0xa5).unwrap();
357 }
358 if offset > 0 {
359 bits.push_number_checked(offset, (1 << offset) - 1).unwrap();
360 }
361 assert_eq!(bits.data.len(), capacity);
362 assert_eq!(bits.bit_offset, offset);
363 bits
364 }
365
366 fn write_bits(bits: &mut Bits, mut count: usize) {
367 while count > 0 {
368 let width = count.min(16);
369 bits.push_number_checked(width, (1 << width) - 1).unwrap();
370 count -= width;
371 }
372 }
373
374 #[test]
375 fn reserved_bits_can_be_written_without_growing_capacity() {
376 for offset in 0..8 {
377 for count in 0..=128 {
378 let mut reserved = filled_to_capacity(offset);
379 let mut reference = filled_to_capacity(offset);
380 let before_bytes = reserved.data.clone();
381 let before_len = reserved.len();
382 let before_modes = reserved.encoding_modes();
383 let before_payload = reserved.payload_bits_len;
384
385 reserved.reserve(count);
386 let reserved_capacity = reserved.data.capacity();
387 assert_eq!(reserved.data, before_bytes);
388 assert_eq!(reserved.len(), before_len);
389 assert_eq!(reserved.encoding_modes(), before_modes);
390 assert_eq!(reserved.payload_bits_len, before_payload);
391
392 write_bits(&mut reserved, count);
393 write_bits(&mut reference, count);
394
395 assert_eq!(reserved.data.capacity(), reserved_capacity, "offset {offset}, count {count}");
396 assert_eq!(reserved.data, reference.data);
397 assert_eq!(reserved.len(), before_len + count);
398 assert_eq!(reserved.bit_offset, reference.bit_offset);
399 assert_eq!(reserved.encoding_modes(), reference.encoding_modes());
400 assert_eq!(reserved.payload_bits_len, reference.payload_bits_len);
401 }
402 }
403 }
404
405 #[test]
406 fn reserving_empty_or_padded_streams_keeps_contents_and_metadata() {
407 let mut empty = Bits::new(Version::Normal(1));
408 empty.reserve(0);
409 assert!(empty.is_empty());
410 assert_eq!(empty.data.capacity(), 0);
411 empty.reserve(1);
412 let capacity = empty.data.capacity();
413 assert!(capacity >= 1);
414 assert!(empty.is_empty());
415 empty.push_number_checked(1, 1).unwrap();
416 assert_eq!(empty.data.capacity(), capacity);
417
418 let mut padded = Bits::new(Version::Normal(1));
419 padded.push_byte_data(b"abc").unwrap();
420 padded.push_terminator(EcLevel::M).unwrap();
421 let before_bytes = padded.data.clone();
422 let before_len = padded.len();
423 let before_modes = padded.encoding_modes();
424 let before_payload = padded.payload_bits_len;
425 padded.reserve(65);
426 assert_eq!(padded.data, before_bytes);
427 assert_eq!(padded.len(), before_len);
428 assert_eq!(padded.encoding_modes(), before_modes);
429 assert_eq!(padded.payload_bits_len, before_payload);
430 }
431}
432
433#[cfg(test)]
434mod metadata_tests {
435 use crate::bits::{Bits, EncodingModes};
436 use crate::types::{EcLevel, Mode, Version};
437
438 #[test]
439 fn encoding_modes_iterates_in_stable_mode_order() {
440 let modes = EncodingModes::from_mode(Mode::Byte);
441 let mut modes_with_numeric = modes;
442 modes_with_numeric.insert(Mode::Numeric);
443
444 assert_eq!(modes_with_numeric.iter().collect::<Vec<_>>(), vec![Mode::Numeric, Mode::Byte]);
445 }
446
447 #[test]
448 fn encoding_modes_iterator_reports_exact_remaining_length_for_every_subset() {
449 let order = [Mode::Numeric, Mode::Alphanumeric, Mode::Byte, Mode::Kanji];
450 for mask in 0..=0b1111 {
451 let modes = EncodingModes { bits: mask };
452 let expected = order.iter().copied().filter(|&mode| modes.contains(mode)).collect::<Vec<_>>();
453 let mut iter = modes.iter();
454
455 for (index, &mode) in expected.iter().enumerate() {
456 let remaining = expected.len() - index;
457 assert_eq!(iter.size_hint(), (remaining, Some(remaining)), "mask {mask}");
458 assert_eq!(iter.len(), remaining, "mask {mask}");
459 assert_eq!(iter.next(), Some(mode));
460 }
461 assert_eq!(iter.size_hint(), (0, Some(0)), "mask {mask}");
462 assert_eq!(iter.len(), 0);
463 assert_eq!(iter.next(), None);
464 assert_eq!(iter.next(), None);
465 }
466 }
467
468 #[test]
469 fn bits_records_successful_payload_modes() {
470 let mut bits = Bits::new(Version::Normal(1));
471
472 bits.push_numeric_data(b"012").unwrap();
473 bits.push_byte_data(b"abc").unwrap();
474
475 assert!(bits.encoding_modes().contains(Mode::Numeric));
476 assert!(bits.encoding_modes().contains(Mode::Byte));
477 assert!(!bits.encoding_modes().contains(Mode::Kanji));
478 }
479
480 #[test]
481 fn remaining_capacity_uses_payload_len_before_padding() {
482 let mut bits = Bits::new(Version::Normal(1));
483
484 bits.push_numeric_data(b"01234567").unwrap();
485 bits.push_terminator(EcLevel::M).unwrap();
486
487 assert_eq!(bits.len(), 128);
488 assert_eq!(bits.payload_bits_len(), 41);
489 assert_eq!(bits.remaining_capacity_bits(EcLevel::M), Ok(87));
490 }
491}
492
493#[derive(Copy, Clone)]
500pub enum ExtendedMode {
501 Eci,
503
504 Data(Mode),
506
507 Fnc1First,
509
510 Fnc1Second,
512
513 StructuredAppend,
515}
516
517impl Bits {
518 pub fn push_mode_indicator(&mut self, mode: ExtendedMode) -> QrResult<()> {
525 let (bits, number) = self.mode_indicator_bits(mode)?;
526 if bits > 0 {
527 self.push_number(bits, number.as_u16());
528 }
529 Ok(())
530 }
531
532 fn mode_indicator_bits(&self, mode: ExtendedMode) -> QrResult<(usize, usize)> {
533 #[allow(clippy::match_same_arms)]
534 let number = match (self.version, mode) {
535 (Version::Micro(_), ExtendedMode::Data(Mode::Numeric)) => 0,
536 (Version::Micro(_), ExtendedMode::Data(Mode::Alphanumeric)) => 1,
537 (Version::Micro(_), ExtendedMode::Data(Mode::Byte)) => 0b10,
538 (Version::Micro(_), ExtendedMode::Data(Mode::Kanji)) => 0b11,
539 (Version::Micro(_), _) => return Err(QrError::UnsupportedCharacterSet),
540 (_, ExtendedMode::Data(Mode::Numeric)) => 0b0001,
541 (_, ExtendedMode::Data(Mode::Alphanumeric)) => 0b0010,
542 (_, ExtendedMode::Data(Mode::Byte)) => 0b0100,
543 (_, ExtendedMode::Data(Mode::Kanji)) => 0b1000,
544 (_, ExtendedMode::Eci) => 0b0111,
545 (_, ExtendedMode::Fnc1First) => 0b0101,
546 (_, ExtendedMode::Fnc1Second) => 0b1001,
547 (_, ExtendedMode::StructuredAppend) => 0b0011,
548 };
549 let bits = self.version.mode_bits_count();
550 if bits > 16 || number >= (1 << bits) {
551 return Err(QrError::UnsupportedCharacterSet);
552 }
553 Ok((bits, number))
554 }
555}
556
557impl Bits {
562 pub fn push_eci_designator(&mut self, eci_designator: u32) -> QrResult<()> {
600 self.reserve(12); self.push_mode_indicator(ExtendedMode::Eci)?;
602 match eci_designator {
603 0..=127 => {
604 self.push_number(8, eci_designator.as_u16());
605 }
606 128..=16383 => {
607 self.push_number(2, 0b10);
608 self.push_number(14, eci_designator.as_u16());
609 }
610 16384..=999_999 => {
611 self.push_number(3, 0b110);
612 self.push_number(5, (eci_designator >> 16).as_u16());
613 self.push_number(16, (eci_designator & 0xffff).as_u16());
614 }
615 _ => return Err(QrError::InvalidEciDesignator { value: eci_designator }),
616 }
617 Ok(())
618 }
619}
620
621#[cfg(test)]
622mod eci_tests {
623 use crate::bits::Bits;
624 use crate::types::{QrError, Version};
625
626 #[test]
627 fn test_9() {
628 let mut bits = Bits::new(Version::Normal(1));
629 assert_eq!(bits.push_eci_designator(9), Ok(()));
630 assert_eq!(bits.into_bytes(), vec![0b0111_0000, 0b1001_0000]);
631 }
632
633 #[test]
634 fn test_899() {
635 let mut bits = Bits::new(Version::Normal(1));
636 assert_eq!(bits.push_eci_designator(899), Ok(()));
637 assert_eq!(bits.into_bytes(), vec![0b0111_10_00, 0b00111000, 0b0011_0000]);
638 }
639
640 #[test]
641 fn test_999999() {
642 let mut bits = Bits::new(Version::Normal(1));
643 assert_eq!(bits.push_eci_designator(999999), Ok(()));
644 assert_eq!(bits.into_bytes(), vec![0b0111_110_0, 0b11110100, 0b00100011, 0b1111_0000]);
645 }
646
647 #[test]
648 fn test_invalid_designator() {
649 let mut bits = Bits::new(Version::Normal(1));
650 assert_eq!(bits.push_eci_designator(1000000), Err(QrError::InvalidEciDesignator { value: 1000000 }));
651 }
652
653 #[test]
654 fn test_unsupported_character_set() {
655 let mut bits = Bits::new(Version::Micro(4));
656 assert_eq!(bits.push_eci_designator(9), Err(QrError::UnsupportedCharacterSet));
657 }
658}
659
660impl Bits {
665 fn push_header(&mut self, mode: Mode, raw_data_len: usize) -> QrResult<()> {
666 let (mode_bits, mode_number) = self.mode_indicator_bits(ExtendedMode::Data(mode))?;
667 let length_bits = mode.length_bits_count(self.version);
668 if raw_data_len >= (1_usize << length_bits) {
669 return Err(QrError::DataTooLong);
670 }
671 self.reserve(length_bits + mode_bits + mode.data_bits_count(raw_data_len));
672 if mode_bits > 0 {
673 self.push_number(mode_bits, mode_number.as_u16());
674 }
675 self.push_number(length_bits, raw_data_len.as_u16());
676 Ok(())
677 }
678
679 pub fn push_numeric_data(&mut self, data: &[u8]) -> QrResult<()> {
688 self.mode_indicator_bits(ExtendedMode::Data(Mode::Numeric))?;
689 if let Some((position, byte)) = NumericMode::invalid_character(data) {
690 return Err(QrError::InvalidCharacter { position, byte });
691 }
692 self.push_header(Mode::Numeric, data.len())?;
693 for chunk in data.chunks(3) {
694 let number = chunk.iter().map(|b| u16::from(*b - b'0')).fold(0, |a, b| a * 10 + b);
695 let length = chunk.len() * 3 + 1;
696 self.push_number(length, number);
697 }
698 self.encoding_modes.insert(Mode::Numeric);
699 self.payload_bits_len = None;
700 Ok(())
701 }
702}
703
704#[cfg(test)]
705mod numeric_tests {
706 use crate::bits::Bits;
707 use crate::types::{QrError, Version};
708
709 #[test]
710 fn test_iso_18004_2006_example_1() {
711 let mut bits = Bits::new(Version::Normal(1));
712 assert_eq!(bits.push_numeric_data(b"01234567"), Ok(()));
713 assert_eq!(bits.into_bytes(), vec![0b0001_0000, 0b001000_00, 0b00001100, 0b01010110, 0b01_100001, 0b1_0000000]);
714 }
715
716 #[test]
717 fn test_iso_18004_2000_example_2() {
718 let mut bits = Bits::new(Version::Normal(1));
719 assert_eq!(bits.push_numeric_data(b"0123456789012345"), Ok(()));
720 assert_eq!(
721 bits.into_bytes(),
722 vec![
723 0b0001_0000,
724 0b010000_00,
725 0b00001100,
726 0b01010110,
727 0b01_101010,
728 0b0110_1110,
729 0b000101_00,
730 0b11101010,
731 0b0101_0000,
732 ]
733 );
734 }
735
736 #[test]
737 fn test_iso_18004_2006_example_2() {
738 let mut bits = Bits::new(Version::Micro(3));
739 assert_eq!(bits.push_numeric_data(b"0123456789012345"), Ok(()));
740 assert_eq!(
741 bits.into_bytes(),
742 vec![0b00_10000_0, 0b00000110, 0b0_0101011, 0b001_10101, 0b00110_111, 0b0000101_0, 0b01110101, 0b00101_000,]
743 );
744 }
745
746 #[test]
747 fn test_data_too_long_error() {
748 let mut bits = Bits::new(Version::Micro(1));
749 assert_eq!(bits.push_numeric_data(b"12345678"), Err(QrError::DataTooLong));
750 }
751}
752
753#[inline]
763fn alphanumeric_digit(character: u8) -> u16 {
764 match character {
765 b'0'..=b'9' => u16::from(character - b'0'),
766 b'A'..=b'Z' => u16::from(character - b'A') + 10,
767 b' ' => 36,
768 b'$' => 37,
769 b'%' => 38,
770 b'*' => 39,
771 b'+' => 40,
772 b'-' => 41,
773 b'.' => 42,
774 b'/' => 43,
775 b':' => 44,
776 _ => 0,
777 }
778}
779
780impl Bits {
781 pub fn push_alphanumeric_data(&mut self, data: &[u8]) -> QrResult<()> {
792 self.mode_indicator_bits(ExtendedMode::Data(Mode::Alphanumeric))?;
793 if let Some((position, byte)) = AlphanumericMode::invalid_character(data) {
794 return Err(QrError::InvalidCharacter { position, byte });
795 }
796 self.push_header(Mode::Alphanumeric, data.len())?;
797 for chunk in data.chunks(2) {
798 let number = chunk.iter().map(|b| alphanumeric_digit(*b)).fold(0, |a, b| a * 45 + b);
799 let length = chunk.len() * 5 + 1;
800 self.push_number(length, number);
801 }
802 self.encoding_modes.insert(Mode::Alphanumeric);
803 self.payload_bits_len = None;
804 Ok(())
805 }
806}
807
808#[cfg(test)]
809mod alphanumeric_tests {
810 use crate::bits::Bits;
811 use crate::types::{QrError, Version};
812
813 #[test]
814 fn test_iso_18004_2006_example() {
815 let mut bits = Bits::new(Version::Normal(1));
816 assert_eq!(bits.push_alphanumeric_data(b"AC-42"), Ok(()));
817 assert_eq!(bits.into_bytes(), vec![0b0010_0000, 0b00101_001, 0b11001110, 0b11100111, 0b001_00001, 0b0_0000000]);
818 }
819
820 #[test]
821 fn test_micro_qr_unsupported() {
822 let mut bits = Bits::new(Version::Micro(1));
823 assert_eq!(bits.push_alphanumeric_data(b"A"), Err(QrError::UnsupportedCharacterSet));
824 }
825
826 #[test]
827 fn test_data_too_long() {
828 let mut bits = Bits::new(Version::Micro(2));
829 assert_eq!(bits.push_alphanumeric_data(b"ABCDEFGH"), Err(QrError::DataTooLong));
830 }
831}
832
833impl Bits {
838 pub fn push_byte_data(&mut self, data: &[u8]) -> QrResult<()> {
844 self.push_header(Mode::Byte, data.len())?;
845 let offset = self.bit_offset;
846 if offset == 0 {
847 self.data.extend_from_slice(data);
848 } else if let Some((&last, _)) = data.split_last() {
849 let last_index = self.data.len() - 1;
850 self.data[last_index] |= data[0] >> offset;
851 let shift = 8 - offset;
852 self.data.extend(data.windows(2).map(|pair| (pair[0] << shift) | (pair[1] >> offset)));
853 self.data.push(last << shift);
854 }
855 self.encoding_modes.insert(Mode::Byte);
856 self.payload_bits_len = None;
857 Ok(())
858 }
859
860 #[cfg(feature = "bench-internals")]
862 #[doc(hidden)]
863 pub fn push_byte_data_scalar_for_bench(&mut self, data: &[u8]) -> QrResult<()> {
864 self.push_header(Mode::Byte, data.len())?;
865 for &byte in data {
866 self.push_number(8, u16::from(byte));
867 }
868 self.encoding_modes.insert(Mode::Byte);
869 self.payload_bits_len = None;
870 Ok(())
871 }
872}
873
874#[cfg(test)]
875mod byte_tests {
876 use crate::bits::Bits;
877 use crate::types::{EcLevel, Mode, QrError, Version};
878
879 fn reference_write(bytes: &mut Vec<u8>, bit_len: &mut usize, width: usize, value: usize) {
882 for index in (0..width).rev() {
883 if (*bit_len).is_multiple_of(8) {
884 bytes.push(0);
885 }
886 let byte_index = bytes.len() - 1;
887 bytes[byte_index] |= (((value >> index) & 1) as u8) << (7 - *bit_len % 8);
888 *bit_len += 1;
889 }
890 }
891
892 fn reference_byte_segment(bytes: &mut Vec<u8>, bit_len: &mut usize, version: Version, data: &[u8]) {
893 let mode_number = if version.is_micro() { 2 } else { 4 };
894 reference_write(bytes, bit_len, version.mode_bits_count(), mode_number);
895 reference_write(bytes, bit_len, Mode::Byte.length_bits_count(version), data.len());
896 for &byte in data {
897 reference_write(bytes, bit_len, 8, usize::from(byte));
898 }
899 }
900
901 fn check_byte_segment(data: &[u8], version: Version, prefix_len: usize) {
902 let mut bits = Bits::new(version);
903 let mut expected = Vec::new();
904 let mut bit_len = 0;
905 if prefix_len > 0 {
906 let prefix = (1 << prefix_len) - 1;
907 bits.push_number_checked(prefix_len, prefix).unwrap();
908 reference_write(&mut expected, &mut bit_len, prefix_len, prefix);
909 }
910 bits.push_byte_data(data).unwrap();
911 reference_byte_segment(&mut expected, &mut bit_len, version, data);
912
913 assert_eq!(bits.len(), bit_len, "{version:?} prefix {prefix_len}, data {data:?}");
914 assert_eq!(bits.bit_offset, bit_len % 8);
915 assert_eq!(bits.data, expected);
916 assert_eq!(bits.encoding_modes(), crate::bits::EncodingModes::from_mode(Mode::Byte));
917 assert_eq!(bits.payload_bits_len, None);
918 #[cfg(feature = "bench-internals")]
919 {
920 let mut scalar = Bits::new(version);
921 if prefix_len > 0 {
922 scalar.push_number_checked(prefix_len, (1 << prefix_len) - 1).unwrap();
923 }
924 scalar.push_byte_data_scalar_for_bench(data).unwrap();
925 assert_eq!(bits.data, scalar.data);
926 assert_eq!(bits.len(), scalar.len());
927 }
928 }
929
930 #[test]
931 fn byte_packing_matches_bit_reference_at_every_offset_and_version_group() {
932 for version in [
933 Version::Normal(1),
934 Version::Normal(9),
935 Version::Normal(10),
936 Version::Normal(26),
937 Version::Normal(27),
938 Version::Normal(40),
939 Version::Micro(3),
940 Version::Micro(4),
941 ] {
942 let max_length = (1 << Mode::Byte.length_bits_count(version)) - 1;
943 for len in [0, 1, 2, 15, 31, 255, 256, 2048].into_iter().filter(|&len| len <= max_length) {
944 let data = (0..len).map(|index| (index % 256) as u8).collect::<Vec<_>>();
945 for prefix_len in 0..8 {
946 check_byte_segment(&data, version, prefix_len);
947 }
948 }
949 }
950 }
951
952 #[test]
953 fn micro_byte_packing_preserves_every_byte_value_at_every_offset() {
954 for version in [Version::Micro(3), Version::Micro(4)] {
955 for byte in 0..=255 {
956 for prefix_len in 0..8 {
957 check_byte_segment(&[byte], version, prefix_len);
958 }
959 }
960 }
961 }
962
963 #[test]
964 fn byte_packing_preserves_consecutive_and_mixed_segment_boundaries() {
965 let version = Version::Normal(40);
966 for prefix_len in 0..8 {
967 let mut bits = Bits::new(version);
968 let mut expected = Vec::new();
969 let mut bit_len = 0;
970 if prefix_len > 0 {
971 let prefix = (1 << prefix_len) - 1;
972 bits.push_number_checked(prefix_len, prefix).unwrap();
973 reference_write(&mut expected, &mut bit_len, prefix_len, prefix);
974 }
975 for data in [&b""[..], &[0xff], &[0, 0xa5, 0x7f], &b"longer byte segment"[..], &b""[..]] {
976 bits.push_byte_data(data).unwrap();
977 reference_byte_segment(&mut expected, &mut bit_len, version, data);
978 }
979
980 bits.push_numeric_data(b"12345").unwrap();
981 reference_write(&mut expected, &mut bit_len, 4, 1);
982 reference_write(&mut expected, &mut bit_len, 14, 5);
983 reference_write(&mut expected, &mut bit_len, 10, 123);
984 reference_write(&mut expected, &mut bit_len, 7, 45);
985 bits.push_byte_data(&[0xf0, 0x0f, 0xaa, 0x55]).unwrap();
986 reference_byte_segment(&mut expected, &mut bit_len, version, &[0xf0, 0x0f, 0xaa, 0x55]);
987
988 assert_eq!(bits.data, expected);
989 assert_eq!(bits.len(), bit_len);
990 assert!(bits.encoding_modes().contains(Mode::Numeric));
991 assert!(bits.encoding_modes().contains(Mode::Byte));
992 }
993 }
994
995 #[test]
996 fn empty_byte_segment_after_padding_keeps_header_and_resets_payload_metadata() {
997 let version = Version::Normal(1);
998 let mut bits = Bits::new(version);
999 bits.push_numeric_data(b"1").unwrap();
1000 bits.push_terminator(EcLevel::L).unwrap();
1001 assert!(bits.payload_bits_len.is_some());
1002 let mut expected = bits.data.clone();
1003 let mut bit_len = bits.len();
1004
1005 bits.push_byte_data(&[]).unwrap();
1006 reference_byte_segment(&mut expected, &mut bit_len, version, &[]);
1007
1008 assert_eq!(bits.data, expected);
1009 assert_eq!(bits.len(), bit_len);
1010 assert_eq!(bits.payload_bits_len, None);
1011 assert!(bits.encoding_modes().contains(Mode::Byte));
1012 }
1013
1014 #[test]
1015 fn zero_width_checked_writes_preserve_empty_aligned_and_mixed_streams() {
1016 let empty = Bits::new(Version::Normal(40));
1017 let mut aligned = Bits::new(Version::Normal(40));
1018 aligned.push_number_checked(4, 0xa).unwrap();
1019 aligned.push_byte_data(b"abc").unwrap();
1020 assert_eq!(aligned.bit_offset, 0);
1021 let mut unaligned = Bits::new(Version::Normal(40));
1022 unaligned.push_numeric_data(b"12345").unwrap();
1023 assert_ne!(unaligned.bit_offset, 0);
1024 let mut terminated = Bits::new(Version::Normal(1));
1025 terminated.push_numeric_data(b"1").unwrap();
1026 terminated.push_terminator(EcLevel::M).unwrap();
1027 assert!(terminated.payload_bits_len.is_some());
1028 let mut mixed_byte = Bits::new(Version::Normal(40));
1029 mixed_byte.push_numeric_data(b"12345").unwrap();
1030 mixed_byte.push_byte_data(&[0xab, 0xcd]).unwrap();
1031 let mut mixed_terminated = Bits::new(Version::Normal(40));
1032 mixed_terminated.push_numeric_data(b"12345").unwrap();
1033 mixed_terminated.push_byte_data(&[0xab, 0xcd]).unwrap();
1034 mixed_terminated.push_terminator(EcLevel::M).unwrap();
1035
1036 for (name, mut bits) in [
1037 ("empty", empty),
1038 ("aligned", aligned),
1039 ("unaligned", unaligned),
1040 ("terminated", terminated),
1041 ("mixed_byte", mixed_byte),
1042 ("mixed_terminated", mixed_terminated),
1043 ] {
1044 let expected = bits.data.clone();
1045 let bit_len = bits.len();
1046 let offset = bits.bit_offset;
1047 let capacity = bits.data.capacity();
1048 let modes = bits.encoding_modes();
1049 let payload_len = bits.payload_bits_len;
1050 for number in [0, 1, usize::MAX] {
1051 let result = if number == 0 { Ok(()) } else { Err(QrError::DataTooLong) };
1052 assert_eq!(bits.push_number_checked(0, number), result, "{name} value {number}");
1053 assert_eq!(bits.data, expected, "{name}");
1054 assert_eq!(bits.len(), bit_len, "{name}");
1055 assert_eq!(bits.bit_offset, offset, "{name}");
1056 assert_eq!(bits.data.capacity(), capacity, "{name}");
1057 assert_eq!(bits.encoding_modes(), modes, "{name}");
1058 assert_eq!(bits.payload_bits_len, payload_len, "{name}");
1059 }
1060 }
1061 }
1062
1063 #[test]
1064 fn byte_packing_errors_leave_existing_bits_and_metadata_unchanged() {
1065 for (version, len, error) in [
1066 (Version::Normal(1), 256, QrError::DataTooLong),
1067 (Version::Micro(3), 16, QrError::DataTooLong),
1068 (Version::Micro(4), 32, QrError::DataTooLong),
1069 (Version::Micro(1), 256, QrError::UnsupportedCharacterSet),
1070 (Version::Micro(2), 256, QrError::UnsupportedCharacterSet),
1071 ] {
1072 let mut bits = Bits::new(version);
1073 bits.push_numeric_data(b"1").unwrap();
1074 let expected = bits.data.clone();
1075 let bit_len = bits.len();
1076 let modes = bits.encoding_modes();
1077 let payload_len = bits.payload_bits_len;
1078
1079 assert_eq!(bits.push_byte_data(&vec![0xff; len]), Err(error));
1080 assert_eq!(bits.data, expected);
1081 assert_eq!(bits.len(), bit_len);
1082 assert_eq!(bits.encoding_modes(), modes);
1083 assert_eq!(bits.payload_bits_len, payload_len);
1084 }
1085 }
1086
1087 #[test]
1088 fn test() {
1089 let mut bits = Bits::new(Version::Normal(1));
1090 assert_eq!(bits.push_byte_data(b"\x12\x34\x56\x78\x9a\xbc\xde\xf0"), Ok(()));
1091 assert_eq!(
1092 bits.into_bytes(),
1093 vec![
1094 0b0100_0000,
1095 0b1000_0001,
1096 0b0010_0011,
1097 0b0100_0101,
1098 0b0110_0111,
1099 0b1000_1001,
1100 0b1010_1011,
1101 0b1100_1101,
1102 0b1110_1111,
1103 0b0000_0000,
1104 ]
1105 );
1106 }
1107
1108 #[test]
1109 fn test_micro_qr_unsupported() {
1110 let mut bits = Bits::new(Version::Micro(2));
1111 assert_eq!(bits.push_byte_data(b"?"), Err(QrError::UnsupportedCharacterSet));
1112 }
1113
1114 #[test]
1115 fn test_data_too_long() {
1116 let mut bits = Bits::new(Version::Micro(3));
1117 assert_eq!(bits.push_byte_data(b"0123456701234567"), Err(QrError::DataTooLong));
1118 }
1119}
1120
1121impl Bits {
1126 pub fn push_kanji_data(&mut self, data: &[u8]) -> QrResult<()> {
1136 self.mode_indicator_bits(ExtendedMode::Data(Mode::Kanji))?;
1137 if let Some((position, byte)) = KanjiMode::invalid_character(data) {
1138 return Err(QrError::InvalidCharacter { position, byte });
1139 }
1140 self.push_header(Mode::Kanji, data.len() / 2)?;
1141 for kanji in data.as_chunks::<2>().0 {
1142 let cp = u16::from(kanji[0]) * 256 + u16::from(kanji[1]);
1143 let bytes = if cp < 0xe040 { cp - 0x8140 } else { cp - 0xc140 };
1144 let number = (bytes >> 8) * 0xc0 + (bytes & 0xff);
1145 self.push_number(13, number);
1146 }
1147 self.encoding_modes.insert(Mode::Kanji);
1148 self.payload_bits_len = None;
1149 Ok(())
1150 }
1151}
1152
1153impl Bits {
1154 pub fn push_mode_data<M: EncodingMode>(&mut self, data: &[u8]) -> QrResult<()> {
1168 if let Some((position, byte)) = M::invalid_character(data) {
1169 return Err(QrError::InvalidCharacter { position, byte });
1170 }
1171
1172 match M::MODE {
1173 Mode::Numeric => self.push_numeric_data(data),
1174 Mode::Alphanumeric => self.push_alphanumeric_data(data),
1175 Mode::Byte => self.push_byte_data(data),
1176 Mode::Kanji => self.push_kanji_data(data),
1177 }
1178 }
1179}
1180
1181#[cfg(test)]
1182mod typed_mode_tests {
1183 use crate::bits::Bits;
1184 use crate::mode::{AlphanumericMode, ByteMode, KanjiMode, NumericMode};
1185 use crate::types::{EcLevel, Mode, QrError, Version};
1186
1187 #[test]
1188 fn push_mode_data_matches_numeric_specific_encoder() {
1189 let mut typed = Bits::new(Version::Normal(1));
1190 let mut direct = Bits::new(Version::Normal(1));
1191
1192 assert_eq!(typed.push_mode_data::<NumericMode>(b"01234567"), Ok(()));
1193 assert_eq!(direct.push_numeric_data(b"01234567"), Ok(()));
1194 assert_eq!(typed.into_bytes(), direct.into_bytes());
1195 }
1196
1197 #[test]
1198 fn push_mode_data_matches_other_specific_encoders() {
1199 let mut alphanumeric = Bits::new(Version::Normal(1));
1200 let mut byte = Bits::new(Version::Normal(1));
1201 let mut kanji = Bits::new(Version::Normal(1));
1202
1203 assert_eq!(alphanumeric.push_mode_data::<AlphanumericMode>(b"AC-42"), Ok(()));
1204 assert_eq!(byte.push_mode_data::<ByteMode>(b"\x12\x34"), Ok(()));
1205 assert_eq!(kanji.push_mode_data::<KanjiMode>(b"\x93\x5f\xe4\xaa"), Ok(()));
1206 }
1207
1208 #[test]
1209 fn push_mode_data_rejects_invalid_mode_input_before_writing() {
1210 let mut bits = Bits::new(Version::Normal(1));
1211
1212 assert_eq!(
1213 bits.push_mode_data::<NumericMode>(b"12a"),
1214 Err(QrError::InvalidCharacter { position: 2, byte: b'a' })
1215 );
1216 assert!(bits.into_bytes().is_empty());
1217 }
1218
1219 #[test]
1220 fn direct_modes_reject_invalid_input_without_changing_existing_bits() {
1221 let cases: &[(Mode, &[u8], usize, u8)] = &[
1222 (Mode::Numeric, b"12/4", 2, b'/'),
1223 (Mode::Alphanumeric, b"ABc", 2, b'c'),
1224 (Mode::Kanji, b"\x00\x00", 0, 0),
1225 (Mode::Kanji, b"\xeb\xc0", 0, 0xeb),
1226 (Mode::Kanji, b"\x93\x5f\x81", 2, 0x81),
1227 (Mode::Kanji, b"\x93\x5f\xe0\x00", 2, 0xe0),
1228 ];
1229 for &(mode, data, position, byte) in cases {
1230 let mut bits = Bits::new(Version::Normal(1));
1231 bits.push_byte_data(b"seed").unwrap();
1232 bits.push_terminator(EcLevel::L).unwrap();
1233 let previous_data = bits.data.clone();
1234 let previous_modes = bits.encoding_modes();
1235 let previous_payload_len = bits.payload_bits_len();
1236 let result = match mode {
1237 Mode::Numeric => bits.push_numeric_data(data),
1238 Mode::Alphanumeric => bits.push_alphanumeric_data(data),
1239 Mode::Kanji => bits.push_kanji_data(data),
1240 Mode::Byte => unreachable!(),
1241 };
1242
1243 assert_eq!(result, Err(QrError::InvalidCharacter { position, byte }), "{mode:?} {data:?}");
1244 assert_eq!(bits.data, previous_data);
1245 assert_eq!(bits.encoding_modes(), previous_modes);
1246 assert_eq!(bits.payload_bits_len(), previous_payload_len);
1247 }
1248 }
1249
1250 #[test]
1251 fn mode_length_overflow_does_not_write_a_mode_header() {
1252 let mut numeric = Bits::new(Version::Micro(2));
1253 let mut alphanumeric = Bits::new(Version::Micro(2));
1254 let mut byte = Bits::new(Version::Micro(3));
1255 let mut kanji = Bits::new(Version::Micro(3));
1256 let kanji_data = b"\x93\x5f".repeat(8);
1257
1258 assert_eq!(numeric.push_numeric_data(b"0123456789012345"), Err(QrError::DataTooLong));
1259 assert_eq!(alphanumeric.push_alphanumeric_data(b"ABCDEFGH"), Err(QrError::DataTooLong));
1260 assert_eq!(byte.push_byte_data(b"0123456789012345"), Err(QrError::DataTooLong));
1261 assert_eq!(kanji.push_kanji_data(&kanji_data), Err(QrError::DataTooLong));
1262
1263 for bits in [numeric, alphanumeric, byte, kanji] {
1264 assert!(bits.encoding_modes().is_empty());
1265 assert!(bits.into_bytes().is_empty());
1266 }
1267 }
1268
1269 #[test]
1270 fn unsupported_mode_is_rejected_before_length_overflow_without_writing() {
1271 let mut alphanumeric = Bits::new(Version::Micro(1));
1272 let mut byte = Bits::new(Version::Micro(2));
1273
1274 assert_eq!(alphanumeric.push_alphanumeric_data(b"ABCDEFGH"), Err(QrError::UnsupportedCharacterSet));
1275 assert_eq!(byte.push_byte_data(b"0123456789012345"), Err(QrError::UnsupportedCharacterSet));
1276 assert!(alphanumeric.into_bytes().is_empty());
1277 assert!(byte.into_bytes().is_empty());
1278 }
1279
1280 #[test]
1281 fn direct_mode_errors_preserve_unsupported_mode_precedence() {
1282 let cases: &[(Mode, Version, &[u8], QrError)] = &[
1283 (Mode::Alphanumeric, Version::Micro(1), b"c", QrError::UnsupportedCharacterSet),
1284 (Mode::Kanji, Version::Micro(2), b"?", QrError::UnsupportedCharacterSet),
1285 (Mode::Numeric, Version::Micro(1), b"a", QrError::InvalidCharacter { position: 0, byte: b'a' }),
1286 (Mode::Alphanumeric, Version::Micro(2), b"c", QrError::InvalidCharacter { position: 0, byte: b'c' }),
1287 (Mode::Kanji, Version::Micro(3), b"?", QrError::InvalidCharacter { position: 0, byte: b'?' }),
1288 ];
1289 for &(mode, version, data, error) in cases {
1290 let mut bits = Bits::new(version);
1291 bits.push_numeric_data(b"1").unwrap();
1292 let previous_data = bits.data.clone();
1293 let previous_len = bits.len();
1294 let previous_modes = bits.encoding_modes();
1295 let result = match mode {
1296 Mode::Numeric => bits.push_numeric_data(data),
1297 Mode::Alphanumeric => bits.push_alphanumeric_data(data),
1298 Mode::Kanji => bits.push_kanji_data(data),
1299 Mode::Byte => unreachable!(),
1300 };
1301
1302 assert_eq!(result, Err(error), "{mode:?} {version:?} {data:?}");
1303 assert_eq!(bits.data, previous_data);
1304 assert_eq!(bits.len(), previous_len);
1305 assert_eq!(bits.encoding_modes(), previous_modes);
1306 }
1307 }
1308}
1309
1310#[cfg(test)]
1311mod kanji_tests {
1312 use crate::bits::Bits;
1313 use crate::types::{QrError, Version};
1314
1315 #[test]
1316 fn test_iso_18004_example() {
1317 let mut bits = Bits::new(Version::Normal(1));
1318 assert_eq!(bits.push_kanji_data(b"\x93\x5f\xe4\xaa"), Ok(()));
1319 assert_eq!(bits.into_bytes(), vec![0b1000_0000, 0b0010_0110, 0b11001111, 0b1_1101010, 0b101010_00]);
1320 }
1321
1322 #[test]
1323 fn test_micro_qr_unsupported() {
1324 let mut bits = Bits::new(Version::Micro(2));
1325 assert_eq!(bits.push_kanji_data(b"?"), Err(QrError::UnsupportedCharacterSet));
1326 }
1327
1328 #[test]
1329 fn test_data_too_long() {
1330 let mut bits = Bits::new(Version::Micro(3));
1331 assert_eq!(bits.push_kanji_data(b"\x93_\x93_\x93_\x93_\x93_\x93_\x93_\x93_"), Err(QrError::DataTooLong));
1332 }
1333}
1334
1335impl Bits {
1340 pub fn push_fnc1_first_position(&mut self) -> QrResult<()> {
1360 self.push_mode_indicator(ExtendedMode::Fnc1First)
1361 }
1362
1363 pub fn push_fnc1_second_position(&mut self, application_indicator: u8) -> QrResult<()> {
1389 self.push_mode_indicator(ExtendedMode::Fnc1Second)?;
1390 self.push_number(8, u16::from(application_indicator));
1391 Ok(())
1392 }
1393}
1394
1395impl Bits {
1400 pub fn push_structured_append_header(&mut self, position: u8, total: u8, parity: u8) -> QrResult<()> {
1432 if self.version.is_micro() {
1433 return Err(QrError::UnsupportedCharacterSet);
1434 }
1435 if !(2..=16).contains(&total) || !(1..=total).contains(&position) {
1436 return Err(QrError::InvalidStructuredAppend {
1437 value: if !(2..=16).contains(&total) { total } else { position },
1438 });
1439 }
1440 let sequence = (u16::from(position - 1) << 4) | u16::from(total - 1);
1443 self.reserve(20);
1444 self.push_mode_indicator(ExtendedMode::StructuredAppend)?;
1445 self.push_number(8, sequence);
1446 self.push_number(8, u16::from(parity));
1447 Ok(())
1448 }
1449}
1450
1451#[cfg(test)]
1452mod structured_append_tests {
1453 use crate::bits::Bits;
1454 use crate::types::{EcLevel, QrError, Version};
1455
1456 #[test]
1457 fn test_header_bit_layout() {
1458 let mut bits = Bits::new(Version::Normal(1));
1461 assert_eq!(bits.push_structured_append_header(1, 3, 0x5a), Ok(()));
1462 assert_eq!(bits.into_bytes(), vec![0x30, 0x25, 0xA0]);
1463 }
1464
1465 #[test]
1466 fn test_header_bit_layout_second_of_two() {
1467 let mut bits = Bits::new(Version::Normal(1));
1471 assert_eq!(bits.push_structured_append_header(2, 2, 0xff), Ok(()));
1472 assert_eq!(bits.into_bytes(), vec![0x31, 0x1F, 0xF0]);
1473 }
1474
1475 #[test]
1476 fn test_header_value_16_uses_max_nibble() {
1477 let mut bits = Bits::new(Version::Normal(1));
1480 assert_eq!(bits.push_structured_append_header(16, 16, 0x00), Ok(()));
1481 assert_eq!(bits.into_bytes(), vec![0x3F, 0xF0, 0x00]);
1482 }
1483
1484 #[test]
1485 fn test_micro_rejected() {
1486 let mut bits = Bits::new(Version::Micro(2));
1487 assert_eq!(bits.push_structured_append_header(1, 2, 0), Err(QrError::UnsupportedCharacterSet));
1488 }
1489
1490 #[test]
1491 fn test_invalid_total() {
1492 let mut bits = Bits::new(Version::Normal(1));
1493 assert_eq!(bits.push_structured_append_header(1, 1, 0), Err(QrError::InvalidStructuredAppend { value: 1 }));
1494 assert_eq!(bits.push_structured_append_header(1, 17, 0), Err(QrError::InvalidStructuredAppend { value: 17 }));
1495 }
1496
1497 #[test]
1498 fn test_invalid_position() {
1499 let mut bits = Bits::new(Version::Normal(1));
1500 assert_eq!(bits.push_structured_append_header(0, 3, 0), Err(QrError::InvalidStructuredAppend { value: 0 }));
1501 assert_eq!(bits.push_structured_append_header(4, 3, 0), Err(QrError::InvalidStructuredAppend { value: 4 }));
1502 }
1503
1504 #[test]
1505 fn test_header_then_data_round_trips() {
1506 let mut bits = Bits::new(Version::Normal(1));
1508 bits.push_structured_append_header(1, 2, 0).unwrap();
1509 bits.push_byte_data(b"ab").unwrap();
1510 assert!(bits.push_terminator(EcLevel::M).is_ok());
1511 }
1512}
1513
1514static DATA_LENGTHS: [[usize; 4]; 44] = [
1520 [152, 128, 104, 72],
1522 [272, 224, 176, 128],
1523 [440, 352, 272, 208],
1524 [640, 512, 384, 288],
1525 [864, 688, 496, 368],
1526 [1088, 864, 608, 480],
1527 [1248, 992, 704, 528],
1528 [1552, 1232, 880, 688],
1529 [1856, 1456, 1056, 800],
1530 [2192, 1728, 1232, 976],
1531 [2592, 2032, 1440, 1120],
1532 [2960, 2320, 1648, 1264],
1533 [3424, 2672, 1952, 1440],
1534 [3688, 2920, 2088, 1576],
1535 [4184, 3320, 2360, 1784],
1536 [4712, 3624, 2600, 2024],
1537 [5176, 4056, 2936, 2264],
1538 [5768, 4504, 3176, 2504],
1539 [6360, 5016, 3560, 2728],
1540 [6888, 5352, 3880, 3080],
1541 [7456, 5712, 4096, 3248],
1542 [8048, 6256, 4544, 3536],
1543 [8752, 6880, 4912, 3712],
1544 [9392, 7312, 5312, 4112],
1545 [10208, 8000, 5744, 4304],
1546 [10960, 8496, 6032, 4768],
1547 [11744, 9024, 6464, 5024],
1548 [12248, 9544, 6968, 5288],
1549 [13048, 10136, 7288, 5608],
1550 [13880, 10984, 7880, 5960],
1551 [14744, 11640, 8264, 6344],
1552 [15640, 12328, 8920, 6760],
1553 [16568, 13048, 9368, 7208],
1554 [17528, 13800, 9848, 7688],
1555 [18448, 14496, 10288, 7888],
1556 [19472, 15312, 10832, 8432],
1557 [20528, 15936, 11408, 8768],
1558 [21616, 16816, 12016, 9136],
1559 [22496, 17728, 12656, 9776],
1560 [23648, 18672, 13328, 10208],
1561 [20, 0, 0, 0],
1563 [40, 32, 0, 0],
1564 [84, 68, 0, 0],
1565 [128, 112, 80, 0],
1566];
1567
1568impl Bits {
1569 pub fn push_terminator(&mut self, ec_level: EcLevel) -> QrResult<()> {
1579 let terminator_size = match self.version {
1580 Version::Micro(a) => a.as_usize() * 2 + 1,
1581 Version::Normal(_) => 4,
1582 };
1583
1584 let cur_length = self.len();
1585 let data_length = self.max_len(ec_level)?;
1586 if cur_length > data_length {
1587 return Err(QrError::DataTooLong);
1588 }
1589 self.payload_bits_len = Some(cur_length);
1590
1591 let terminator_size = min(terminator_size, data_length - cur_length);
1592 if terminator_size > 0 {
1593 self.push_number(terminator_size, 0);
1594 }
1595
1596 if self.len() < data_length {
1597 const PADDING_BYTES: &[u8] = &[0b1110_1100, 0b0001_0001];
1598
1599 self.bit_offset = 0;
1600 let data_bytes_length = data_length / 8;
1601 let padding_bytes_count = data_bytes_length.saturating_sub(self.data.len());
1602 let padding = PADDING_BYTES.iter().copied().cycle().take(padding_bytes_count);
1603 self.data.extend(padding);
1604 }
1605
1606 if self.len() < data_length {
1607 self.data.push(0);
1608 }
1609
1610 Ok(())
1611 }
1612}
1613
1614#[cfg(test)]
1615mod finish_tests {
1616 use crate::bits::Bits;
1617 use crate::types::{EcLevel, QrError, Version};
1618
1619 #[test]
1620 fn test_hello_world() {
1621 let mut bits = Bits::new(Version::Normal(1));
1622 assert_eq!(bits.push_alphanumeric_data(b"HELLO WORLD"), Ok(()));
1623 assert_eq!(bits.push_terminator(EcLevel::Q), Ok(()));
1624 assert_eq!(
1625 bits.into_bytes(),
1626 vec![
1627 0b00100000, 0b01011011, 0b00001011, 0b01111000, 0b11010001, 0b01110010, 0b11011100, 0b01001101,
1628 0b01000011, 0b01000000, 0b11101100, 0b00010001, 0b11101100,
1629 ]
1630 );
1631 }
1632
1633 #[test]
1634 fn test_too_long() {
1635 let mut bits = Bits::new(Version::Micro(1));
1636 assert_eq!(bits.push_numeric_data(b"9999999"), Ok(()));
1637 assert_eq!(bits.push_terminator(EcLevel::L), Err(QrError::DataTooLong));
1638 }
1639
1640 #[test]
1641 fn test_no_terminator() {
1642 let mut bits = Bits::new(Version::Micro(1));
1643 assert_eq!(bits.push_numeric_data(b"99999"), Ok(()));
1644 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
1645 assert_eq!(bits.into_bytes(), vec![0b101_11111, 0b00111_110, 0b0011_0000]);
1646 }
1647
1648 #[test]
1649 fn test_no_padding() {
1650 let mut bits = Bits::new(Version::Micro(1));
1651 assert_eq!(bits.push_numeric_data(b"9999"), Ok(()));
1652 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
1653 assert_eq!(bits.into_bytes(), vec![0b100_11111, 0b00111_100, 0b1_000_0000]);
1654 }
1655
1656 #[test]
1657 fn test_micro_version_1_half_byte_padding() {
1658 let mut bits = Bits::new(Version::Micro(1));
1659 assert_eq!(bits.push_numeric_data(b"999"), Ok(()));
1660 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
1661 assert_eq!(bits.into_bytes(), vec![0b011_11111, 0b00111_000, 0b0000_0000]);
1662 }
1663
1664 #[test]
1665 fn test_micro_version_1_full_byte_padding() {
1666 let mut bits = Bits::new(Version::Micro(1));
1667 assert_eq!(bits.push_numeric_data(b""), Ok(()));
1668 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
1669 assert_eq!(bits.into_bytes(), vec![0b000_000_00, 0b11101100, 0]);
1670 }
1671}
1672
1673impl Bits {
1678 pub fn push_segments<I>(&mut self, data: &[u8], segments_iter: I) -> QrResult<()>
1687 where
1688 I: Iterator<Item = Segment>,
1689 {
1690 for segment in segments_iter {
1691 let slice = &data[segment.begin..segment.end];
1692 match segment.mode {
1693 Mode::Numeric => self.push_numeric_data(slice),
1694 Mode::Alphanumeric => self.push_alphanumeric_data(slice),
1695 Mode::Byte => self.push_byte_data(slice),
1696 Mode::Kanji => self.push_kanji_data(slice),
1697 }?;
1698 }
1699 Ok(())
1700 }
1701
1702 pub fn push_optimal_data(&mut self, data: &[u8]) -> QrResult<()> {
1708 let segments = Parser::new(data).optimize(self.version);
1709 self.push_segments(data, segments)
1710 }
1711}
1712
1713#[cfg(test)]
1714mod encode_tests {
1715 use crate::bits::Bits;
1716 use crate::types::{EcLevel, QrError, QrResult, Version};
1717
1718 fn encode(data: &[u8], version: Version, ec_level: EcLevel) -> QrResult<Vec<u8>> {
1719 let mut bits = Bits::new(version);
1720 bits.push_optimal_data(data)?;
1721 bits.push_terminator(ec_level)?;
1722 Ok(bits.into_bytes())
1723 }
1724
1725 #[test]
1726 fn test_alphanumeric() {
1727 let res = encode(b"HELLO WORLD", Version::Normal(1), EcLevel::Q);
1728 assert_eq!(
1729 res,
1730 Ok(vec![
1731 0b00100000, 0b01011011, 0b00001011, 0b01111000, 0b11010001, 0b01110010, 0b11011100, 0b01001101,
1732 0b01000011, 0b01000000, 0b11101100, 0b00010001, 0b11101100,
1733 ])
1734 );
1735 }
1736
1737 #[test]
1738 fn test_auto_mode_switch() {
1739 let res = encode(b"123A", Version::Micro(2), EcLevel::L);
1740 assert_eq!(res, Ok(vec![0b0_0011_000, 0b1111011_1, 0b001_00101, 0b0_00000_00, 0b11101100]));
1741 }
1742
1743 #[test]
1744 fn test_too_long() {
1745 let res = encode(b">>>>>>>>", Version::Normal(1), EcLevel::H);
1746 assert_eq!(res, Err(QrError::DataTooLong));
1747 }
1748}
1749
1750pub fn data_capacity_bits(version: Version, ec_level: EcLevel) -> QrResult<usize> {
1763 version.fetch(ec_level, &DATA_LENGTHS)
1764}
1765
1766pub fn encode_auto(data: &[u8], ec_level: EcLevel) -> QrResult<Bits> {
1776 if data.len() > crate::limits::DEFAULT_MAX_DATA_LENGTH {
1777 return Err(QrError::DataTooLong);
1778 }
1779 encode_auto_with_max_version(data, ec_level, 40)
1780}
1781
1782pub fn encode_auto_with_max_version(data: &[u8], ec_level: EcLevel, max_version: i16) -> QrResult<Bits> {
1789 if !(1..=40).contains(&max_version) {
1790 return Err(QrError::InvalidResourceLimits);
1791 }
1792 let segments = Parser::new(data).collect::<Vec<Segment>>();
1793 let mut checkpoints = [0_i16; 4];
1794 let mut checkpoint_count = 0;
1795 for candidate in [9_i16, 26, 40, max_version] {
1796 if candidate <= max_version && !checkpoints[..checkpoint_count].contains(&candidate) {
1797 checkpoints[checkpoint_count] = candidate;
1798 checkpoint_count += 1;
1799 }
1800 }
1801 for candidate in checkpoints[..checkpoint_count].iter() {
1802 let version = Version::Normal(*candidate);
1803 let opt_segments = optimize_segments(&segments, version);
1804 let total_len = total_encoded_len(&opt_segments, version);
1805 let data_capacity = version.fetch(ec_level, &DATA_LENGTHS)?;
1806 if total_len <= data_capacity {
1807 let min_version = find_min_version_up_to(total_len, ec_level, *candidate);
1808 let mut bits = Bits::new(min_version);
1809 bits.reserve(total_len);
1810 bits.push_segments(data, opt_segments.into_iter())?;
1811 bits.push_terminator(ec_level)?;
1812 return Ok(bits);
1813 }
1814 }
1815 Err(QrError::DataTooLong)
1816}
1817
1818fn find_min_version_up_to(length: usize, ec_level: EcLevel, max_version: i16) -> Version {
1819 for version in 1..=max_version {
1820 if DATA_LENGTHS[(version - 1) as usize][ec_level as usize] >= length {
1821 return Version::Normal(version);
1822 }
1823 }
1824 Version::Normal(max_version)
1825}
1826
1827pub fn encode_auto_micro(data: &[u8], ec_level: EcLevel) -> QrResult<Bits> {
1840 Version::Micro(4).fetch(ec_level, &DATA_LENGTHS)?;
1842 if data.len() > crate::limits::DEFAULT_MAX_DATA_LENGTH {
1843 return Err(QrError::DataTooLong);
1844 }
1845 let segments = Parser::new(data).collect::<Vec<Segment>>();
1846 for micro_version in 1..=4 {
1847 let version = Version::Micro(micro_version);
1848 let data_capacity = match version.fetch(ec_level, &DATA_LENGTHS) {
1849 Ok(cap) if cap > 0 => cap,
1850 _ => continue,
1851 };
1852 if !segments.iter().all(|segment| match segment.mode {
1853 Mode::Numeric => true,
1854 Mode::Alphanumeric => micro_version >= 2,
1855 Mode::Byte | Mode::Kanji => micro_version >= 3,
1856 }) {
1857 continue;
1858 }
1859 let opt_segments = optimize_segments(&segments, version);
1860 let total_len = total_encoded_len(&opt_segments, version);
1861 if total_len <= data_capacity {
1862 let mut bits = Bits::new(version);
1863 bits.reserve(total_len);
1864 bits.push_segments(data, opt_segments.into_iter())?;
1865 bits.push_terminator(ec_level)?;
1866 return Ok(bits);
1867 }
1868 }
1869 Err(QrError::DataTooLong)
1870}
1871
1872pub fn find_min_version(length: usize, ec_level: EcLevel) -> Version {
1875 let mut base = 0_usize;
1876 let mut size = 39;
1877 while size > 1 {
1878 let half = size / 2;
1879 let mid = base + half;
1880 base = if DATA_LENGTHS[mid][ec_level as usize] > length { base } else { mid };
1884 size -= half;
1885 }
1886 base = if DATA_LENGTHS[base][ec_level as usize] >= length { base } else { base + 1 };
1888 Version::Normal((base + 1).as_i16())
1889}
1890
1891#[cfg(test)]
1892mod encode_auto_tests {
1893 use crate::bits::{encode_auto, encode_auto_micro, encode_auto_with_max_version, find_min_version};
1894 use crate::types::{EcLevel, QrError, Version};
1895
1896 #[test]
1897 fn test_find_min_version() {
1898 assert_eq!(find_min_version(60, EcLevel::L), Version::Normal(1));
1899 assert_eq!(find_min_version(200, EcLevel::L), Version::Normal(2));
1900 assert_eq!(find_min_version(200, EcLevel::H), Version::Normal(3));
1901 assert_eq!(find_min_version(20000, EcLevel::L), Version::Normal(37));
1902 assert_eq!(find_min_version(640, EcLevel::L), Version::Normal(4));
1903 assert_eq!(find_min_version(641, EcLevel::L), Version::Normal(5));
1904 assert_eq!(find_min_version(999999, EcLevel::H), Version::Normal(40));
1905 }
1906
1907 #[test]
1908 fn test_alpha_q() {
1909 let bits = encode_auto(b"HELLO WORLD", EcLevel::Q).unwrap();
1910 assert_eq!(bits.version(), Version::Normal(1));
1911 }
1912
1913 #[test]
1914 fn test_alpha_h() {
1915 let bits = encode_auto(b"HELLO WORLD", EcLevel::H).unwrap();
1916 assert_eq!(bits.version(), Version::Normal(2));
1917 }
1918
1919 #[test]
1920 fn test_mixed() {
1921 let bits = encode_auto(b"This is a mixed data test. 1234567890", EcLevel::H).unwrap();
1922 assert_eq!(bits.version(), Version::Normal(4));
1923 }
1924
1925 #[test]
1926 fn bounded_auto_encoding_rejects_version_overflow_and_caps_search() {
1927 assert!(matches!(encode_auto_with_max_version(b"x", EcLevel::M, 0), Err(QrError::InvalidResourceLimits)));
1928 assert!(matches!(encode_auto_with_max_version(&[0_u8; 128], EcLevel::M, 1), Err(QrError::DataTooLong)));
1929 }
1930
1931 #[test]
1932 fn micro_auto_selection_skips_versions_that_cannot_encode_the_payload_mode() {
1933 let cases: &[(&[u8], EcLevel, i16)] = &[
1934 (b"1", EcLevel::L, 1),
1935 (b"A", EcLevel::L, 2),
1936 (b"a", EcLevel::L, 3),
1937 (b"abc", EcLevel::L, 3),
1938 (b"\x93\x5f", EcLevel::L, 3),
1939 (b"123A", EcLevel::L, 2),
1940 (b"123a", EcLevel::L, 3),
1941 (b"\x93\x5f1", EcLevel::L, 3),
1942 (b"A", EcLevel::Q, 4),
1943 ];
1944 for &(data, ec_level, expected) in cases {
1945 let bits = encode_auto_micro(data, ec_level).unwrap();
1946 assert_eq!(bits.version(), Version::Micro(expected), "{data:?} {ec_level:?}");
1947
1948 let mut fixed = crate::bits::Bits::new(Version::Micro(expected));
1949 fixed.push_optimal_data(data).unwrap();
1950 fixed.push_terminator(ec_level).unwrap();
1951 assert_eq!(bits.into_bytes(), fixed.into_bytes(), "{data:?} {ec_level:?}");
1952 }
1953 }
1954
1955 #[test]
1956 fn micro_auto_selection_distinguishes_unsupported_ec_from_payload_overflow() {
1957 assert!(matches!(
1958 encode_auto_micro(b"1", EcLevel::H),
1959 Err(QrError::InvalidVersion { version: Version::Micro(4), ec_level: EcLevel::H })
1960 ));
1961 assert!(matches!(encode_auto_micro(&[b'1'; 100], EcLevel::L), Err(QrError::DataTooLong)));
1962 }
1963}
1964
1965