(s: ArgAsciiBuffer, vm: &VirtualMachine)
| 745 | |
| 746 | #[pyfunction] |
| 747 | fn a2b_uu(s: ArgAsciiBuffer, vm: &VirtualMachine) -> PyResult<Vec<u8>> { |
| 748 | s.with_ref(|b| { |
| 749 | // First byte: binary data length (in bytes) |
| 750 | let length = if b.is_empty() { |
| 751 | ((-0x20i32) & 0x3fi32) as usize |
| 752 | } else { |
| 753 | ((b[0] - b' ') & 0x3f) as usize |
| 754 | }; |
| 755 | |
| 756 | // Allocate the buffer |
| 757 | let mut res = Vec::<u8>::with_capacity(length); |
| 758 | let trailing_garbage_error = |
| 759 | || Err(super::new_binascii_error("Trailing garbage".to_owned(), vm)); |
| 760 | |
| 761 | for chunk in b.get(1..).unwrap_or_default().chunks(4) { |
| 762 | let (char_a, char_b, char_c, char_d) = { |
| 763 | let mut chunk = chunk |
| 764 | .iter() |
| 765 | .map(|x| uu_a2b_read(x, vm)) |
| 766 | .collect::<Result<Vec<_>, _>>()?; |
| 767 | while chunk.len() < 4 { |
| 768 | chunk.push(0); |
| 769 | } |
| 770 | (chunk[0], chunk[1], chunk[2], chunk[3]) |
| 771 | }; |
| 772 | |
| 773 | if res.len() < length { |
| 774 | res.push((char_a << 2) | (char_b >> 4)); |
| 775 | } else if char_a != 0 || char_b != 0 { |
| 776 | return trailing_garbage_error(); |
| 777 | } |
| 778 | |
| 779 | if res.len() < length { |
| 780 | res.push(((char_b & 0xf) << 4) | (char_c >> 2)); |
| 781 | } else if char_c != 0 { |
| 782 | return trailing_garbage_error(); |
| 783 | } |
| 784 | |
| 785 | if res.len() < length { |
| 786 | res.push(((char_c & 0x3) << 6) | char_d); |
| 787 | } else if char_d != 0 { |
| 788 | return trailing_garbage_error(); |
| 789 | } |
| 790 | } |
| 791 | |
| 792 | let remaining_length = length - res.len(); |
| 793 | if remaining_length > 0 { |
| 794 | res.extend(vec![0; remaining_length]); |
| 795 | } |
| 796 | Ok(res) |
| 797 | }) |
| 798 | } |
| 799 | |
| 800 | #[derive(FromArgs)] |
| 801 | struct BacktickArg { |
nothing calls this directly
no test coverage detected