(args: OemEncodeArgs, vm: &VirtualMachine)
| 573 | |
| 574 | #[pyfunction] |
| 575 | fn oem_encode(args: OemEncodeArgs, vm: &VirtualMachine) -> PyResult<(Vec<u8>, usize)> { |
| 576 | use crate::common::windows::ToWideString; |
| 577 | use windows_sys::Win32::Globalization::{ |
| 578 | CP_OEMCP, WC_NO_BEST_FIT_CHARS, WideCharToMultiByte, |
| 579 | }; |
| 580 | |
| 581 | let errors = args.errors.as_ref().map(|s| s.as_str()).unwrap_or("strict"); |
| 582 | let s = match args.s.to_str() { |
| 583 | Some(s) => s, |
| 584 | None => { |
| 585 | // String contains surrogates - not encodable with oem |
| 586 | return Err(vm.new_unicode_encode_error( |
| 587 | "'oem' codec can't encode character: surrogates not allowed", |
| 588 | )); |
| 589 | } |
| 590 | }; |
| 591 | let char_len = args.s.char_len(); |
| 592 | |
| 593 | if s.is_empty() { |
| 594 | return Ok((Vec::new(), char_len)); |
| 595 | } |
| 596 | |
| 597 | // Convert UTF-8 string to UTF-16 |
| 598 | let wide: Vec<u16> = std::ffi::OsStr::new(s).to_wide(); |
| 599 | |
| 600 | // Get the required buffer size |
| 601 | let size = unsafe { |
| 602 | WideCharToMultiByte( |
| 603 | CP_OEMCP, |
| 604 | WC_NO_BEST_FIT_CHARS, |
| 605 | wide.as_ptr(), |
| 606 | wide.len() as i32, |
| 607 | core::ptr::null_mut(), |
| 608 | 0, |
| 609 | core::ptr::null(), |
| 610 | core::ptr::null_mut(), |
| 611 | ) |
| 612 | }; |
| 613 | |
| 614 | if size == 0 { |
| 615 | let err = std::io::Error::last_os_error(); |
| 616 | return Err(vm.new_os_error(format!("oem_encode failed: {}", err))); |
| 617 | } |
| 618 | |
| 619 | let mut buffer = vec![0u8; size as usize]; |
| 620 | let mut used_default_char: i32 = 0; |
| 621 | |
| 622 | let result = unsafe { |
| 623 | WideCharToMultiByte( |
| 624 | CP_OEMCP, |
| 625 | WC_NO_BEST_FIT_CHARS, |
| 626 | wide.as_ptr(), |
| 627 | wide.len() as i32, |
| 628 | buffer.as_mut_ptr().cast(), |
| 629 | size, |
| 630 | core::ptr::null(), |
| 631 | if errors == "strict" { |
| 632 | &mut used_default_char |
no test coverage detected