1use std::cmp::min;
4
5#[cfg(feature = "bench")]
6extern crate test;
7
8use crate::cast::{As, Truncate};
9use crate::optimize::{total_encoded_len, Optimizer, Parser, Segment};
10use crate::types::{EcLevel, Mode, QrError, QrResult, Version};
11
12pub struct Bits {
17 data: Vec<u8>,
18 bit_offset: usize,
19 version: Version,
20}
21
22impl Bits {
23 pub fn new(version: Version) -> Self {
25 Self { data: Vec::new(), bit_offset: 0, version }
26 }
27
28 fn push_number(&mut self, n: usize, number: u16) {
34 debug_assert!(n == 16 || n < 16 && number < (1 << n), "{number} is too big as a {n}-bit number");
35
36 let b = self.bit_offset + n;
37 let last_index = self.data.len().wrapping_sub(1);
38 match (self.bit_offset, b) {
39 (0, 0..=8) => {
40 self.data.push((number << (8 - b)).truncate_as_u8());
41 }
42 (0, _) => {
43 self.data.push((number >> (b - 8)).truncate_as_u8());
44 self.data.push((number << (16 - b)).truncate_as_u8());
45 }
46 (_, 0..=8) => {
47 self.data[last_index] |= (number << (8 - b)).truncate_as_u8();
48 }
49 (_, 9..=16) => {
50 self.data[last_index] |= (number >> (b - 8)).truncate_as_u8();
51 self.data.push((number << (16 - b)).truncate_as_u8());
52 }
53 _ => {
54 self.data[last_index] |= (number >> (b - 8)).truncate_as_u8();
55 self.data.push((number >> (b - 16)).truncate_as_u8());
56 self.data.push((number << (24 - b)).truncate_as_u8());
57 }
58 }
59 self.bit_offset = b & 7;
60 }
61
62 fn push_number_checked(&mut self, n: usize, number: usize) -> QrResult<()> {
67 if n > 16 || number >= (1 << n) {
68 Err(QrError::DataTooLong)
69 } else {
70 self.push_number(n, number.as_u16());
71 Ok(())
72 }
73 }
74
75 fn reserve(&mut self, n: usize) {
77 let extra_bytes = (n + (8 - self.bit_offset) % 8) / 8;
78 self.data.reserve(extra_bytes);
79 }
80
81 pub fn into_bytes(self) -> Vec<u8> {
83 self.data
84 }
85
86 pub fn len(&self) -> usize {
88 if self.bit_offset == 0 {
89 self.data.len() * 8
90 } else {
91 (self.data.len() - 1) * 8 + self.bit_offset
92 }
93 }
94
95 pub fn is_empty(&self) -> bool {
97 self.data.is_empty()
98 }
99
100 pub fn max_len(&self, ec_level: EcLevel) -> QrResult<usize> {
109 self.version.fetch(ec_level, &DATA_LENGTHS)
110 }
111
112 pub fn version(&self) -> Version {
114 self.version
115 }
116}
117
118#[test]
119fn test_push_number() {
120 let mut bits = Bits::new(Version::Normal(1));
121
122 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();
132
133 assert_eq!(
134 bytes,
135 vec![
136 0b010__110__10, 0b1__001_1010, 0b1100__1011, 0b0110_1101, 0b01_1001_00, 0b01__111_001, 0b0_1110_001, 0b1__0000000, ]
145 );
146}
147
148#[cfg(feature = "bench")]
149#[bench]
150fn bench_push_splitted_bytes(bencher: &mut test::Bencher) {
151 bencher.iter(|| {
152 let mut bits = Bits::new(Version::Normal(40));
153 bits.push_number(4, 0b0101);
154 for _ in 0..1024 {
155 bits.push_number(8, 0b10101010);
156 }
157 bits.into_bytes()
158 });
159}
160
161#[derive(Copy, Clone)]
168pub enum ExtendedMode {
169 Eci,
171
172 Data(Mode),
174
175 Fnc1First,
177
178 Fnc1Second,
180
181 StructuredAppend,
183}
184
185impl Bits {
186 pub fn push_mode_indicator(&mut self, mode: ExtendedMode) -> QrResult<()> {
193 #[allow(clippy::match_same_arms)]
194 let number = match (self.version, mode) {
195 (Version::Micro(1), ExtendedMode::Data(Mode::Numeric)) => return Ok(()),
196 (Version::Micro(_), ExtendedMode::Data(Mode::Numeric)) => 0,
197 (Version::Micro(_), ExtendedMode::Data(Mode::Alphanumeric)) => 1,
198 (Version::Micro(_), ExtendedMode::Data(Mode::Byte)) => 0b10,
199 (Version::Micro(_), ExtendedMode::Data(Mode::Kanji)) => 0b11,
200 (Version::Micro(_), _) => return Err(QrError::UnsupportedCharacterSet),
201 (_, ExtendedMode::Data(Mode::Numeric)) => 0b0001,
202 (_, ExtendedMode::Data(Mode::Alphanumeric)) => 0b0010,
203 (_, ExtendedMode::Data(Mode::Byte)) => 0b0100,
204 (_, ExtendedMode::Data(Mode::Kanji)) => 0b1000,
205 (_, ExtendedMode::Eci) => 0b0111,
206 (_, ExtendedMode::Fnc1First) => 0b0101,
207 (_, ExtendedMode::Fnc1Second) => 0b1001,
208 (_, ExtendedMode::StructuredAppend) => 0b0011,
209 };
210 let bits = self.version.mode_bits_count();
211 self.push_number_checked(bits, number).or(Err(QrError::UnsupportedCharacterSet))
212 }
213}
214
215impl Bits {
220 pub fn push_eci_designator(&mut self, eci_designator: u32) -> QrResult<()> {
258 self.reserve(12); self.push_mode_indicator(ExtendedMode::Eci)?;
260 match eci_designator {
261 0..=127 => {
262 self.push_number(8, eci_designator.as_u16());
263 }
264 128..=16383 => {
265 self.push_number(2, 0b10);
266 self.push_number(14, eci_designator.as_u16());
267 }
268 16384..=999_999 => {
269 self.push_number(3, 0b110);
270 self.push_number(5, (eci_designator >> 16).as_u16());
271 self.push_number(16, (eci_designator & 0xffff).as_u16());
272 }
273 _ => return Err(QrError::InvalidEciDesignator),
274 }
275 Ok(())
276 }
277}
278
279#[cfg(test)]
280mod eci_tests {
281 use crate::bits::Bits;
282 use crate::types::{QrError, Version};
283
284 #[test]
285 fn test_9() {
286 let mut bits = Bits::new(Version::Normal(1));
287 assert_eq!(bits.push_eci_designator(9), Ok(()));
288 assert_eq!(bits.into_bytes(), vec![0b0111__0000, 0b1001__0000]);
289 }
290
291 #[test]
292 fn test_899() {
293 let mut bits = Bits::new(Version::Normal(1));
294 assert_eq!(bits.push_eci_designator(899), Ok(()));
295 assert_eq!(bits.into_bytes(), vec![0b0111__10_00, 0b00111000, 0b0011__0000]);
296 }
297
298 #[test]
299 fn test_999999() {
300 let mut bits = Bits::new(Version::Normal(1));
301 assert_eq!(bits.push_eci_designator(999999), Ok(()));
302 assert_eq!(bits.into_bytes(), vec![0b0111__110_0, 0b11110100, 0b00100011, 0b1111__0000]);
303 }
304
305 #[test]
306 fn test_invalid_designator() {
307 let mut bits = Bits::new(Version::Normal(1));
308 assert_eq!(bits.push_eci_designator(1000000), Err(QrError::InvalidEciDesignator));
309 }
310
311 #[test]
312 fn test_unsupported_character_set() {
313 let mut bits = Bits::new(Version::Micro(4));
314 assert_eq!(bits.push_eci_designator(9), Err(QrError::UnsupportedCharacterSet));
315 }
316}
317
318impl Bits {
323 fn push_header(&mut self, mode: Mode, raw_data_len: usize) -> QrResult<()> {
324 let length_bits = mode.length_bits_count(self.version);
325 self.reserve(length_bits + 4 + mode.data_bits_count(raw_data_len));
326 self.push_mode_indicator(ExtendedMode::Data(mode))?;
327 self.push_number_checked(length_bits, raw_data_len)?;
328 Ok(())
329 }
330
331 pub fn push_numeric_data(&mut self, data: &[u8]) -> QrResult<()> {
339 self.push_header(Mode::Numeric, data.len())?;
340 for chunk in data.chunks(3) {
341 let number = chunk.iter().map(|b| u16::from(*b - b'0')).fold(0, |a, b| a * 10 + b);
342 let length = chunk.len() * 3 + 1;
343 self.push_number(length, number);
344 }
345 Ok(())
346 }
347}
348
349#[cfg(test)]
350mod numeric_tests {
351 use crate::bits::Bits;
352 use crate::types::{QrError, Version};
353
354 #[test]
355 fn test_iso_18004_2006_example_1() {
356 let mut bits = Bits::new(Version::Normal(1));
357 assert_eq!(bits.push_numeric_data(b"01234567"), Ok(()));
358 assert_eq!(
359 bits.into_bytes(),
360 vec![0b0001_0000, 0b001000_00, 0b00001100, 0b01010110, 0b01_100001, 0b1__0000000]
361 );
362 }
363
364 #[test]
365 fn test_iso_18004_2000_example_2() {
366 let mut bits = Bits::new(Version::Normal(1));
367 assert_eq!(bits.push_numeric_data(b"0123456789012345"), Ok(()));
368 assert_eq!(
369 bits.into_bytes(),
370 vec![
371 0b0001_0000,
372 0b010000_00,
373 0b00001100,
374 0b01010110,
375 0b01_101010,
376 0b0110_1110,
377 0b000101_00,
378 0b11101010,
379 0b0101__0000,
380 ]
381 );
382 }
383
384 #[test]
385 fn test_iso_18004_2006_example_2() {
386 let mut bits = Bits::new(Version::Micro(3));
387 assert_eq!(bits.push_numeric_data(b"0123456789012345"), Ok(()));
388 assert_eq!(
389 bits.into_bytes(),
390 vec![
391 0b00_10000_0,
392 0b00000110,
393 0b0_0101011,
394 0b001_10101,
395 0b00110_111,
396 0b0000101_0,
397 0b01110101,
398 0b00101__000,
399 ]
400 );
401 }
402
403 #[test]
404 fn test_data_too_long_error() {
405 let mut bits = Bits::new(Version::Micro(1));
406 assert_eq!(bits.push_numeric_data(b"12345678"), Err(QrError::DataTooLong));
407 }
408}
409
410#[inline]
420fn alphanumeric_digit(character: u8) -> u16 {
421 match character {
422 b'0'..=b'9' => u16::from(character - b'0'),
423 b'A'..=b'Z' => u16::from(character - b'A') + 10,
424 b' ' => 36,
425 b'$' => 37,
426 b'%' => 38,
427 b'*' => 39,
428 b'+' => 40,
429 b'-' => 41,
430 b'.' => 42,
431 b'/' => 43,
432 b':' => 44,
433 _ => 0,
434 }
435}
436
437impl Bits {
438 pub fn push_alphanumeric_data(&mut self, data: &[u8]) -> QrResult<()> {
447 self.push_header(Mode::Alphanumeric, data.len())?;
448 for chunk in data.chunks(2) {
449 let number = chunk.iter().map(|b| alphanumeric_digit(*b)).fold(0, |a, b| a * 45 + b);
450 let length = chunk.len() * 5 + 1;
451 self.push_number(length, number);
452 }
453 Ok(())
454 }
455}
456
457#[cfg(test)]
458mod alphanumeric_tests {
459 use crate::bits::Bits;
460 use crate::types::{QrError, Version};
461
462 #[test]
463 fn test_iso_18004_2006_example() {
464 let mut bits = Bits::new(Version::Normal(1));
465 assert_eq!(bits.push_alphanumeric_data(b"AC-42"), Ok(()));
466 assert_eq!(
467 bits.into_bytes(),
468 vec![0b0010_0000, 0b00101_001, 0b11001110, 0b11100111, 0b001_00001, 0b0__0000000]
469 );
470 }
471
472 #[test]
473 fn test_micro_qr_unsupported() {
474 let mut bits = Bits::new(Version::Micro(1));
475 assert_eq!(bits.push_alphanumeric_data(b"A"), Err(QrError::UnsupportedCharacterSet));
476 }
477
478 #[test]
479 fn test_data_too_long() {
480 let mut bits = Bits::new(Version::Micro(2));
481 assert_eq!(bits.push_alphanumeric_data(b"ABCDEFGH"), Err(QrError::DataTooLong));
482 }
483}
484
485impl Bits {
490 pub fn push_byte_data(&mut self, data: &[u8]) -> QrResult<()> {
496 self.push_header(Mode::Byte, data.len())?;
497 for b in data {
498 self.push_number(8, u16::from(*b));
499 }
500 Ok(())
501 }
502}
503
504#[cfg(test)]
505mod byte_tests {
506 use crate::bits::Bits;
507 use crate::types::{QrError, Version};
508
509 #[test]
510 fn test() {
511 let mut bits = Bits::new(Version::Normal(1));
512 assert_eq!(bits.push_byte_data(b"\x12\x34\x56\x78\x9a\xbc\xde\xf0"), Ok(()));
513 assert_eq!(
514 bits.into_bytes(),
515 vec![
516 0b0100_0000,
517 0b1000_0001,
518 0b0010_0011,
519 0b0100_0101,
520 0b0110_0111,
521 0b1000_1001,
522 0b1010_1011,
523 0b1100_1101,
524 0b1110_1111,
525 0b0000__0000,
526 ]
527 );
528 }
529
530 #[test]
531 fn test_micro_qr_unsupported() {
532 let mut bits = Bits::new(Version::Micro(2));
533 assert_eq!(bits.push_byte_data(b"?"), Err(QrError::UnsupportedCharacterSet));
534 }
535
536 #[test]
537 fn test_data_too_long() {
538 let mut bits = Bits::new(Version::Micro(3));
539 assert_eq!(bits.push_byte_data(b"0123456701234567"), Err(QrError::DataTooLong));
540 }
541}
542
543impl Bits {
548 pub fn push_kanji_data(&mut self, data: &[u8]) -> QrResult<()> {
557 self.push_header(Mode::Kanji, data.len() / 2)?;
558 for kanji in data.chunks(2) {
559 if kanji.len() != 2 {
560 return Err(QrError::InvalidCharacter);
561 }
562 let cp = u16::from(kanji[0]) * 256 + u16::from(kanji[1]);
563 let bytes = if cp < 0xe040 { cp - 0x8140 } else { cp - 0xc140 };
564 let number = (bytes >> 8) * 0xc0 + (bytes & 0xff);
565 self.push_number(13, number);
566 }
567 Ok(())
568 }
569}
570
571#[cfg(test)]
572mod kanji_tests {
573 use crate::bits::Bits;
574 use crate::types::{QrError, Version};
575
576 #[test]
577 fn test_iso_18004_example() {
578 let mut bits = Bits::new(Version::Normal(1));
579 assert_eq!(bits.push_kanji_data(b"\x93\x5f\xe4\xaa"), Ok(()));
580 assert_eq!(bits.into_bytes(), vec![0b1000_0000, 0b0010_0110, 0b11001111, 0b1_1101010, 0b101010__00]);
581 }
582
583 #[test]
584 fn test_micro_qr_unsupported() {
585 let mut bits = Bits::new(Version::Micro(2));
586 assert_eq!(bits.push_kanji_data(b"?"), Err(QrError::UnsupportedCharacterSet));
587 }
588
589 #[test]
590 fn test_data_too_long() {
591 let mut bits = Bits::new(Version::Micro(3));
592 assert_eq!(bits.push_kanji_data(b"\x93_\x93_\x93_\x93_\x93_\x93_\x93_\x93_"), Err(QrError::DataTooLong));
593 }
594}
595
596impl Bits {
601 pub fn push_fnc1_first_position(&mut self) -> QrResult<()> {
621 self.push_mode_indicator(ExtendedMode::Fnc1First)
622 }
623
624 pub fn push_fnc1_second_position(&mut self, application_indicator: u8) -> QrResult<()> {
650 self.push_mode_indicator(ExtendedMode::Fnc1Second)?;
651 self.push_number(8, u16::from(application_indicator));
652 Ok(())
653 }
654}
655
656static DATA_LENGTHS: [[usize; 4]; 44] = [
662 [152, 128, 104, 72],
664 [272, 224, 176, 128],
665 [440, 352, 272, 208],
666 [640, 512, 384, 288],
667 [864, 688, 496, 368],
668 [1088, 864, 608, 480],
669 [1248, 992, 704, 528],
670 [1552, 1232, 880, 688],
671 [1856, 1456, 1056, 800],
672 [2192, 1728, 1232, 976],
673 [2592, 2032, 1440, 1120],
674 [2960, 2320, 1648, 1264],
675 [3424, 2672, 1952, 1440],
676 [3688, 2920, 2088, 1576],
677 [4184, 3320, 2360, 1784],
678 [4712, 3624, 2600, 2024],
679 [5176, 4056, 2936, 2264],
680 [5768, 4504, 3176, 2504],
681 [6360, 5016, 3560, 2728],
682 [6888, 5352, 3880, 3080],
683 [7456, 5712, 4096, 3248],
684 [8048, 6256, 4544, 3536],
685 [8752, 6880, 4912, 3712],
686 [9392, 7312, 5312, 4112],
687 [10208, 8000, 5744, 4304],
688 [10960, 8496, 6032, 4768],
689 [11744, 9024, 6464, 5024],
690 [12248, 9544, 6968, 5288],
691 [13048, 10136, 7288, 5608],
692 [13880, 10984, 7880, 5960],
693 [14744, 11640, 8264, 6344],
694 [15640, 12328, 8920, 6760],
695 [16568, 13048, 9368, 7208],
696 [17528, 13800, 9848, 7688],
697 [18448, 14496, 10288, 7888],
698 [19472, 15312, 10832, 8432],
699 [20528, 15936, 11408, 8768],
700 [21616, 16816, 12016, 9136],
701 [22496, 17728, 12656, 9776],
702 [23648, 18672, 13328, 10208],
703 [20, 0, 0, 0],
705 [40, 32, 0, 0],
706 [84, 68, 0, 0],
707 [128, 112, 80, 0],
708];
709
710impl Bits {
711 pub fn push_terminator(&mut self, ec_level: EcLevel) -> QrResult<()> {
721 let terminator_size = if let Version::Micro(a) = self.version { a.as_usize() * 2 + 1 } else { 4 };
722
723 let cur_length = self.len();
724 let data_length = self.max_len(ec_level)?;
725 if cur_length > data_length {
726 return Err(QrError::DataTooLong);
727 }
728
729 let terminator_size = min(terminator_size, data_length - cur_length);
730 if terminator_size > 0 {
731 self.push_number(terminator_size, 0);
732 }
733
734 if self.len() < data_length {
735 const PADDING_BYTES: &[u8] = &[0b1110_1100, 0b0001_0001];
736
737 self.bit_offset = 0;
738 let data_bytes_length = data_length / 8;
739 let padding_bytes_count = data_bytes_length - self.data.len();
740 let padding = PADDING_BYTES.iter().copied().cycle().take(padding_bytes_count);
741 self.data.extend(padding);
742 }
743
744 if self.len() < data_length {
745 self.data.push(0);
746 }
747
748 Ok(())
749 }
750}
751
752#[cfg(test)]
753mod finish_tests {
754 use crate::bits::Bits;
755 use crate::types::{EcLevel, QrError, Version};
756
757 #[test]
758 fn test_hello_world() {
759 let mut bits = Bits::new(Version::Normal(1));
760 assert_eq!(bits.push_alphanumeric_data(b"HELLO WORLD"), Ok(()));
761 assert_eq!(bits.push_terminator(EcLevel::Q), Ok(()));
762 assert_eq!(
763 bits.into_bytes(),
764 vec![
765 0b00100000, 0b01011011, 0b00001011, 0b01111000, 0b11010001, 0b01110010, 0b11011100, 0b01001101,
766 0b01000011, 0b01000000, 0b11101100, 0b00010001, 0b11101100,
767 ]
768 );
769 }
770
771 #[test]
772 fn test_too_long() {
773 let mut bits = Bits::new(Version::Micro(1));
774 assert_eq!(bits.push_numeric_data(b"9999999"), Ok(()));
775 assert_eq!(bits.push_terminator(EcLevel::L), Err(QrError::DataTooLong));
776 }
777
778 #[test]
779 fn test_no_terminator() {
780 let mut bits = Bits::new(Version::Micro(1));
781 assert_eq!(bits.push_numeric_data(b"99999"), Ok(()));
782 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
783 assert_eq!(bits.into_bytes(), vec![0b101_11111, 0b00111_110, 0b0011__0000]);
784 }
785
786 #[test]
787 fn test_no_padding() {
788 let mut bits = Bits::new(Version::Micro(1));
789 assert_eq!(bits.push_numeric_data(b"9999"), Ok(()));
790 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
791 assert_eq!(bits.into_bytes(), vec![0b100_11111, 0b00111_100, 0b1_000__0000]);
792 }
793
794 #[test]
795 fn test_micro_version_1_half_byte_padding() {
796 let mut bits = Bits::new(Version::Micro(1));
797 assert_eq!(bits.push_numeric_data(b"999"), Ok(()));
798 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
799 assert_eq!(bits.into_bytes(), vec![0b011_11111, 0b00111_000, 0b0000__0000]);
800 }
801
802 #[test]
803 fn test_micro_version_1_full_byte_padding() {
804 let mut bits = Bits::new(Version::Micro(1));
805 assert_eq!(bits.push_numeric_data(b""), Ok(()));
806 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
807 assert_eq!(bits.into_bytes(), vec![0b000_000_00, 0b11101100, 0]);
808 }
809}
810
811impl Bits {
816 pub fn push_segments<I>(&mut self, data: &[u8], segments_iter: I) -> QrResult<()>
825 where
826 I: Iterator<Item = Segment>,
827 {
828 for segment in segments_iter {
829 let slice = &data[segment.begin..segment.end];
830 match segment.mode {
831 Mode::Numeric => self.push_numeric_data(slice),
832 Mode::Alphanumeric => self.push_alphanumeric_data(slice),
833 Mode::Byte => self.push_byte_data(slice),
834 Mode::Kanji => self.push_kanji_data(slice),
835 }?;
836 }
837 Ok(())
838 }
839
840 pub fn push_optimal_data(&mut self, data: &[u8]) -> QrResult<()> {
846 let segments = Parser::new(data).optimize(self.version);
847 self.push_segments(data, segments)
848 }
849}
850
851#[cfg(test)]
852mod encode_tests {
853 use crate::bits::Bits;
854 use crate::types::{EcLevel, QrError, QrResult, Version};
855
856 fn encode(data: &[u8], version: Version, ec_level: EcLevel) -> QrResult<Vec<u8>> {
857 let mut bits = Bits::new(version);
858 bits.push_optimal_data(data)?;
859 bits.push_terminator(ec_level)?;
860 Ok(bits.into_bytes())
861 }
862
863 #[test]
864 fn test_alphanumeric() {
865 let res = encode(b"HELLO WORLD", Version::Normal(1), EcLevel::Q);
866 assert_eq!(
867 res,
868 Ok(vec![
869 0b00100000, 0b01011011, 0b00001011, 0b01111000, 0b11010001, 0b01110010, 0b11011100, 0b01001101,
870 0b01000011, 0b01000000, 0b11101100, 0b00010001, 0b11101100,
871 ])
872 );
873 }
874
875 #[test]
876 fn test_auto_mode_switch() {
877 let res = encode(b"123A", Version::Micro(2), EcLevel::L);
878 assert_eq!(res, Ok(vec![0b0_0011_000, 0b1111011_1, 0b001_00101, 0b0_00000__00, 0b11101100]));
879 }
880
881 #[test]
882 fn test_too_long() {
883 let res = encode(b">>>>>>>>", Version::Normal(1), EcLevel::H);
884 assert_eq!(res, Err(QrError::DataTooLong));
885 }
886}
887
888#[allow(clippy::missing_panics_doc)] pub fn encode_auto(data: &[u8], ec_level: EcLevel) -> QrResult<Bits> {
903 let segments = Parser::new(data).collect::<Vec<Segment>>();
904 for version in &[Version::Normal(9), Version::Normal(26), Version::Normal(40)] {
905 let opt_segments = Optimizer::new(segments.iter().copied(), *version).collect::<Vec<_>>();
906 let total_len = total_encoded_len(&opt_segments, *version);
907 let data_capacity = version.fetch(ec_level, &DATA_LENGTHS).expect("invalid DATA_LENGTHS");
908 if total_len <= data_capacity {
909 let min_version = find_min_version(total_len, ec_level);
910 let mut bits = Bits::new(min_version);
911 bits.reserve(total_len);
912 bits.push_segments(data, opt_segments.into_iter())?;
913 bits.push_terminator(ec_level)?;
914 return Ok(bits);
915 }
916 }
917 Err(QrError::DataTooLong)
918}
919
920fn find_min_version(length: usize, ec_level: EcLevel) -> Version {
923 let mut base = 0_usize;
924 let mut size = 39;
925 while size > 1 {
926 let half = size / 2;
927 let mid = base + half;
928 base = if DATA_LENGTHS[mid][ec_level as usize] > length { base } else { mid };
932 size -= half;
933 }
934 base = if DATA_LENGTHS[base][ec_level as usize] >= length { base } else { base + 1 };
936 Version::Normal((base + 1).as_i16())
937}
938
939#[cfg(test)]
940mod encode_auto_tests {
941 use crate::bits::{encode_auto, find_min_version};
942 use crate::types::{EcLevel, Version};
943
944 #[test]
945 fn test_find_min_version() {
946 assert_eq!(find_min_version(60, EcLevel::L), Version::Normal(1));
947 assert_eq!(find_min_version(200, EcLevel::L), Version::Normal(2));
948 assert_eq!(find_min_version(200, EcLevel::H), Version::Normal(3));
949 assert_eq!(find_min_version(20000, EcLevel::L), Version::Normal(37));
950 assert_eq!(find_min_version(640, EcLevel::L), Version::Normal(4));
951 assert_eq!(find_min_version(641, EcLevel::L), Version::Normal(5));
952 assert_eq!(find_min_version(999999, EcLevel::H), Version::Normal(40));
953 }
954
955 #[test]
956 fn test_alpha_q() {
957 let bits = encode_auto(b"HELLO WORLD", EcLevel::Q).unwrap();
958 assert_eq!(bits.version(), Version::Normal(1));
959 }
960
961 #[test]
962 fn test_alpha_h() {
963 let bits = encode_auto(b"HELLO WORLD", EcLevel::H).unwrap();
964 assert_eq!(bits.version(), Version::Normal(2));
965 }
966
967 #[test]
968 fn test_mixed() {
969 let bits = encode_auto(b"This is a mixed data test. 1234567890", EcLevel::H).unwrap();
970 assert_eq!(bits.version(), Version::Normal(4));
971 }
972}
973
974#[cfg(feature = "bench")]
975#[bench]
976fn bench_find_min_version(bencher: &mut test::Bencher) {
977 use test::black_box;
978
979 bencher.iter(|| {
980 black_box(find_min_version(60, EcLevel::L));
981 black_box(find_min_version(200, EcLevel::L));
982 black_box(find_min_version(200, EcLevel::H));
983 black_box(find_min_version(20000, EcLevel::L));
984 black_box(find_min_version(640, EcLevel::L));
985 black_box(find_min_version(641, EcLevel::L));
986 black_box(find_min_version(999999, EcLevel::H));
987 })
988}
989
990