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), "{} is too big as a {}-bit number", number, n);
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 = match self.version {
722 Version::Micro(a) => a.as_usize() * 2 + 1,
723 _ => 4,
724 };
725
726 let cur_length = self.len();
727 let data_length = self.max_len(ec_level)?;
728 if cur_length > data_length {
729 return Err(QrError::DataTooLong);
730 }
731
732 let terminator_size = min(terminator_size, data_length - cur_length);
733 if terminator_size > 0 {
734 self.push_number(terminator_size, 0);
735 }
736
737 if self.len() < data_length {
738 const PADDING_BYTES: &[u8] = &[0b1110_1100, 0b0001_0001];
739
740 self.bit_offset = 0;
741 let data_bytes_length = data_length / 8;
742 let padding_bytes_count = data_bytes_length - self.data.len();
743 let padding = PADDING_BYTES.iter().cloned().cycle().take(padding_bytes_count);
744 self.data.extend(padding);
745 }
746
747 if self.len() < data_length {
748 self.data.push(0);
749 }
750
751 Ok(())
752 }
753}
754
755#[cfg(test)]
756mod finish_tests {
757 use crate::bits::Bits;
758 use crate::types::{EcLevel, QrError, Version};
759
760 #[test]
761 fn test_hello_world() {
762 let mut bits = Bits::new(Version::Normal(1));
763 assert_eq!(bits.push_alphanumeric_data(b"HELLO WORLD"), Ok(()));
764 assert_eq!(bits.push_terminator(EcLevel::Q), Ok(()));
765 assert_eq!(
766 bits.into_bytes(),
767 vec![
768 0b00100000, 0b01011011, 0b00001011, 0b01111000, 0b11010001, 0b01110010, 0b11011100, 0b01001101,
769 0b01000011, 0b01000000, 0b11101100, 0b00010001, 0b11101100,
770 ]
771 );
772 }
773
774 #[test]
775 fn test_too_long() {
776 let mut bits = Bits::new(Version::Micro(1));
777 assert_eq!(bits.push_numeric_data(b"9999999"), Ok(()));
778 assert_eq!(bits.push_terminator(EcLevel::L), Err(QrError::DataTooLong));
779 }
780
781 #[test]
782 fn test_no_terminator() {
783 let mut bits = Bits::new(Version::Micro(1));
784 assert_eq!(bits.push_numeric_data(b"99999"), Ok(()));
785 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
786 assert_eq!(bits.into_bytes(), vec![0b101_11111, 0b00111_110, 0b0011__0000]);
787 }
788
789 #[test]
790 fn test_no_padding() {
791 let mut bits = Bits::new(Version::Micro(1));
792 assert_eq!(bits.push_numeric_data(b"9999"), Ok(()));
793 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
794 assert_eq!(bits.into_bytes(), vec![0b100_11111, 0b00111_100, 0b1_000__0000]);
795 }
796
797 #[test]
798 fn test_micro_version_1_half_byte_padding() {
799 let mut bits = Bits::new(Version::Micro(1));
800 assert_eq!(bits.push_numeric_data(b"999"), Ok(()));
801 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
802 assert_eq!(bits.into_bytes(), vec![0b011_11111, 0b00111_000, 0b0000__0000]);
803 }
804
805 #[test]
806 fn test_micro_version_1_full_byte_padding() {
807 let mut bits = Bits::new(Version::Micro(1));
808 assert_eq!(bits.push_numeric_data(b""), Ok(()));
809 assert_eq!(bits.push_terminator(EcLevel::L), Ok(()));
810 assert_eq!(bits.into_bytes(), vec![0b000_000_00, 0b11101100, 0]);
811 }
812}
813
814impl Bits {
819 pub fn push_segments<I>(&mut self, data: &[u8], segments_iter: I) -> QrResult<()>
828 where
829 I: Iterator<Item = Segment>,
830 {
831 for segment in segments_iter {
832 let slice = &data[segment.begin..segment.end];
833 match segment.mode {
834 Mode::Numeric => self.push_numeric_data(slice),
835 Mode::Alphanumeric => self.push_alphanumeric_data(slice),
836 Mode::Byte => self.push_byte_data(slice),
837 Mode::Kanji => self.push_kanji_data(slice),
838 }?;
839 }
840 Ok(())
841 }
842
843 pub fn push_optimal_data(&mut self, data: &[u8]) -> QrResult<()> {
849 let segments = Parser::new(data).optimize(self.version);
850 self.push_segments(data, segments)
851 }
852}
853
854#[cfg(test)]
855mod encode_tests {
856 use crate::bits::Bits;
857 use crate::types::{EcLevel, QrError, QrResult, Version};
858
859 fn encode(data: &[u8], version: Version, ec_level: EcLevel) -> QrResult<Vec<u8>> {
860 let mut bits = Bits::new(version);
861 bits.push_optimal_data(data)?;
862 bits.push_terminator(ec_level)?;
863 Ok(bits.into_bytes())
864 }
865
866 #[test]
867 fn test_alphanumeric() {
868 let res = encode(b"HELLO WORLD", Version::Normal(1), EcLevel::Q);
869 assert_eq!(
870 res,
871 Ok(vec![
872 0b00100000, 0b01011011, 0b00001011, 0b01111000, 0b11010001, 0b01110010, 0b11011100, 0b01001101,
873 0b01000011, 0b01000000, 0b11101100, 0b00010001, 0b11101100,
874 ])
875 );
876 }
877
878 #[test]
879 fn test_auto_mode_switch() {
880 let res = encode(b"123A", Version::Micro(2), EcLevel::L);
881 assert_eq!(res, Ok(vec![0b0_0011_000, 0b1111011_1, 0b001_00101, 0b0_00000__00, 0b11101100]));
882 }
883
884 #[test]
885 fn test_too_long() {
886 let res = encode(b">>>>>>>>", Version::Normal(1), EcLevel::H);
887 assert_eq!(res, Err(QrError::DataTooLong));
888 }
889}
890
891pub fn encode_auto(data: &[u8], ec_level: EcLevel) -> QrResult<Bits> {
905 let segments = Parser::new(data).collect::<Vec<Segment>>();
906 for version in &[Version::Normal(9), Version::Normal(26), Version::Normal(40)] {
907 let opt_segments = Optimizer::new(segments.iter().cloned(), *version).collect::<Vec<_>>();
908 let total_len = total_encoded_len(&*opt_segments, *version);
909 let data_capacity = version.fetch(ec_level, &DATA_LENGTHS).expect("invalid DATA_LENGTHS");
910 if total_len <= data_capacity {
911 let min_version = find_min_version(total_len, ec_level);
912 let mut bits = Bits::new(min_version);
913 bits.reserve(total_len);
914 bits.push_segments(data, opt_segments.into_iter())?;
915 bits.push_terminator(ec_level)?;
916 return Ok(bits);
917 }
918 }
919 Err(QrError::DataTooLong)
920}
921
922fn find_min_version(length: usize, ec_level: EcLevel) -> Version {
925 let mut base = 0_usize;
926 let mut size = 39;
927 while size > 1 {
928 let half = size / 2;
929 let mid = base + half;
930 base = if DATA_LENGTHS[mid][ec_level as usize] > length { base } else { mid };
934 size -= half;
935 }
936 base = if DATA_LENGTHS[base][ec_level as usize] >= length { base } else { base + 1 };
938 Version::Normal((base + 1).as_i16())
939}
940
941#[cfg(test)]
942mod encode_auto_tests {
943 use crate::bits::{encode_auto, find_min_version};
944 use crate::types::{EcLevel, Version};
945
946 #[test]
947 fn test_find_min_version() {
948 assert_eq!(find_min_version(60, EcLevel::L), Version::Normal(1));
949 assert_eq!(find_min_version(200, EcLevel::L), Version::Normal(2));
950 assert_eq!(find_min_version(200, EcLevel::H), Version::Normal(3));
951 assert_eq!(find_min_version(20000, EcLevel::L), Version::Normal(37));
952 assert_eq!(find_min_version(640, EcLevel::L), Version::Normal(4));
953 assert_eq!(find_min_version(641, EcLevel::L), Version::Normal(5));
954 assert_eq!(find_min_version(999999, EcLevel::H), Version::Normal(40));
955 }
956
957 #[test]
958 fn test_alpha_q() {
959 let bits = encode_auto(b"HELLO WORLD", EcLevel::Q).unwrap();
960 assert_eq!(bits.version(), Version::Normal(1));
961 }
962
963 #[test]
964 fn test_alpha_h() {
965 let bits = encode_auto(b"HELLO WORLD", EcLevel::H).unwrap();
966 assert_eq!(bits.version(), Version::Normal(2));
967 }
968
969 #[test]
970 fn test_mixed() {
971 let bits = encode_auto(b"This is a mixed data test. 1234567890", EcLevel::H).unwrap();
972 assert_eq!(bits.version(), Version::Normal(4));
973 }
974}
975
976#[cfg(feature = "bench")]
977#[bench]
978fn bench_find_min_version(bencher: &mut test::Bencher) {
979 use test::black_box;
980
981 bencher.iter(|| {
982 black_box(find_min_version(60, EcLevel::L));
983 black_box(find_min_version(200, EcLevel::L));
984 black_box(find_min_version(200, EcLevel::H));
985 black_box(find_min_version(20000, EcLevel::L));
986 black_box(find_min_version(640, EcLevel::L));
987 black_box(find_min_version(641, EcLevel::L));
988 black_box(find_min_version(999999, EcLevel::H));
989 })
990}
991
992