(args: MbcsEncodeArgs, vm: &VirtualMachine)
| 387 | |
| 388 | #[pyfunction] |
| 389 | fn mbcs_encode(args: MbcsEncodeArgs, vm: &VirtualMachine) -> PyResult<(Vec<u8>, usize)> { |
| 390 | use crate::common::windows::ToWideString; |
| 391 | use windows_sys::Win32::Globalization::{ |
| 392 | CP_ACP, WC_NO_BEST_FIT_CHARS, WideCharToMultiByte, |
| 393 | }; |
| 394 | |
| 395 | let errors = args.errors.as_ref().map(|s| s.as_str()).unwrap_or("strict"); |
| 396 | let s = match args.s.to_str() { |
| 397 | Some(s) => s, |
| 398 | None => { |
| 399 | // String contains surrogates - not encodable with mbcs |
| 400 | return Err(vm.new_unicode_encode_error( |
| 401 | "'mbcs' codec can't encode character: surrogates not allowed", |
| 402 | )); |
| 403 | } |
| 404 | }; |
| 405 | let char_len = args.s.char_len(); |
| 406 | |
| 407 | if s.is_empty() { |
| 408 | return Ok((Vec::new(), char_len)); |
| 409 | } |
| 410 | |
| 411 | // Convert UTF-8 string to UTF-16 |
| 412 | let wide: Vec<u16> = std::ffi::OsStr::new(s).to_wide(); |
| 413 | |
| 414 | // Get the required buffer size |
| 415 | let size = unsafe { |
| 416 | WideCharToMultiByte( |
| 417 | CP_ACP, |
| 418 | WC_NO_BEST_FIT_CHARS, |
| 419 | wide.as_ptr(), |
| 420 | wide.len() as i32, |
| 421 | core::ptr::null_mut(), |
| 422 | 0, |
| 423 | core::ptr::null(), |
| 424 | core::ptr::null_mut(), |
| 425 | ) |
| 426 | }; |
| 427 | |
| 428 | if size == 0 { |
| 429 | let err = std::io::Error::last_os_error(); |
| 430 | return Err(vm.new_os_error(format!("mbcs_encode failed: {}", err))); |
| 431 | } |
| 432 | |
| 433 | let mut buffer = vec![0u8; size as usize]; |
| 434 | let mut used_default_char: i32 = 0; |
| 435 | |
| 436 | let result = unsafe { |
| 437 | WideCharToMultiByte( |
| 438 | CP_ACP, |
| 439 | WC_NO_BEST_FIT_CHARS, |
| 440 | wide.as_ptr(), |
| 441 | wide.len() as i32, |
| 442 | buffer.as_mut_ptr().cast(), |
| 443 | size, |
| 444 | core::ptr::null(), |
| 445 | if errors == "strict" { |
| 446 | &mut used_default_char |
nothing calls this directly
no test coverage detected