Try to encode the entire wide string at once (fast/strict path). Returns Ok(Some(bytes)) on success, Ok(None) if there are unencodable chars, or Err on OS error.
(
code_page: u32,
wide: &[u16],
vm: &VirtualMachine,
)
| 787 | /// Returns Ok(Some(bytes)) on success, Ok(None) if there are unencodable chars, |
| 788 | /// or Err on OS error. |
| 789 | fn try_encode_code_page_strict( |
| 790 | code_page: u32, |
| 791 | wide: &[u16], |
| 792 | vm: &VirtualMachine, |
| 793 | ) -> PyResult<Option<Vec<u8>>> { |
| 794 | use windows_sys::Win32::Globalization::WideCharToMultiByte; |
| 795 | |
| 796 | let flags = encode_code_page_flags(code_page, "strict"); |
| 797 | |
| 798 | let use_default_char = code_page != 65001 && code_page != 65000; |
| 799 | let mut used_default_char: i32 = 0; |
| 800 | let pused = if use_default_char { |
| 801 | &mut used_default_char as *mut i32 |
| 802 | } else { |
| 803 | core::ptr::null_mut() |
| 804 | }; |
| 805 | |
| 806 | let size = unsafe { |
| 807 | WideCharToMultiByte( |
| 808 | code_page, |
| 809 | flags, |
| 810 | wide.as_ptr(), |
| 811 | wide.len() as i32, |
| 812 | core::ptr::null_mut(), |
| 813 | 0, |
| 814 | core::ptr::null(), |
| 815 | pused, |
| 816 | ) |
| 817 | }; |
| 818 | |
| 819 | if size <= 0 { |
| 820 | let err_code = std::io::Error::last_os_error().raw_os_error().unwrap_or(0); |
| 821 | if err_code == 1113 { |
| 822 | // ERROR_NO_UNICODE_TRANSLATION |
| 823 | return Ok(None); |
| 824 | } |
| 825 | let err = std::io::Error::last_os_error(); |
| 826 | return Err(vm.new_os_error(format!("code_page_encode: {err}"))); |
| 827 | } |
| 828 | |
| 829 | if use_default_char && used_default_char != 0 { |
| 830 | return Ok(None); |
| 831 | } |
| 832 | |
| 833 | let mut buffer = vec![0u8; size as usize]; |
| 834 | used_default_char = 0; |
| 835 | let pused = if use_default_char { |
| 836 | &mut used_default_char as *mut i32 |
| 837 | } else { |
| 838 | core::ptr::null_mut() |
| 839 | }; |
| 840 | |
| 841 | let result = unsafe { |
| 842 | WideCharToMultiByte( |
| 843 | code_page, |
| 844 | flags, |
| 845 | wide.as_ptr(), |
| 846 | wide.len() as i32, |
no test coverage detected