(args: MbcsDecodeArgs, vm: &VirtualMachine)
| 478 | |
| 479 | #[pyfunction] |
| 480 | fn mbcs_decode(args: MbcsDecodeArgs, vm: &VirtualMachine) -> PyResult<(String, usize)> { |
| 481 | use windows_sys::Win32::Globalization::{ |
| 482 | CP_ACP, MB_ERR_INVALID_CHARS, MultiByteToWideChar, |
| 483 | }; |
| 484 | |
| 485 | let _errors = args.errors.as_ref().map(|s| s.as_str()).unwrap_or("strict"); |
| 486 | let data = args.data.borrow_buf(); |
| 487 | let len = data.len(); |
| 488 | |
| 489 | if data.is_empty() { |
| 490 | return Ok((String::new(), 0)); |
| 491 | } |
| 492 | |
| 493 | // Get the required buffer size for UTF-16 |
| 494 | let size = unsafe { |
| 495 | MultiByteToWideChar( |
| 496 | CP_ACP, |
| 497 | MB_ERR_INVALID_CHARS, |
| 498 | data.as_ptr().cast(), |
| 499 | len as i32, |
| 500 | core::ptr::null_mut(), |
| 501 | 0, |
| 502 | ) |
| 503 | }; |
| 504 | |
| 505 | if size == 0 { |
| 506 | // Try without MB_ERR_INVALID_CHARS for non-strict mode (replacement behavior) |
| 507 | let size = unsafe { |
| 508 | MultiByteToWideChar( |
| 509 | CP_ACP, |
| 510 | 0, |
| 511 | data.as_ptr().cast(), |
| 512 | len as i32, |
| 513 | core::ptr::null_mut(), |
| 514 | 0, |
| 515 | ) |
| 516 | }; |
| 517 | if size == 0 { |
| 518 | let err = std::io::Error::last_os_error(); |
| 519 | return Err(vm.new_os_error(format!("mbcs_decode failed: {}", err))); |
| 520 | } |
| 521 | |
| 522 | let mut buffer = vec![0u16; size as usize]; |
| 523 | let result = unsafe { |
| 524 | MultiByteToWideChar( |
| 525 | CP_ACP, |
| 526 | 0, |
| 527 | data.as_ptr().cast(), |
| 528 | len as i32, |
| 529 | buffer.as_mut_ptr(), |
| 530 | size, |
| 531 | ) |
| 532 | }; |
| 533 | if result == 0 { |
| 534 | let err = std::io::Error::last_os_error(); |
| 535 | return Err(vm.new_os_error(format!("mbcs_decode failed: {}", err))); |
| 536 | } |
| 537 | buffer.truncate(result as usize); |
nothing calls this directly
no test coverage detected