Skip to content

Commit d758f31

Browse files
authored
fix(windows): Prevent CEA-708 output file truncation on Windows
2 parents da802a0 + 49b6982 commit d758f31

File tree

1 file changed

+34
-14
lines changed

1 file changed

+34
-14
lines changed

src/rust/src/decoder/tv_screen.rs

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ use std::os::unix::prelude::IntoRawFd;
1010
use std::os::windows::io::IntoRawHandle;
1111
use std::{ffi::CStr, fs::File};
1212

13+
#[cfg(windows)]
14+
use crate::bindings::_get_osfhandle;
15+
1316
use super::output::{color_to_hex, write_char, Writer};
1417
use super::timing::{get_scc_time_str, get_time_str};
1518
use super::{CCX_DTVCC_SCREENGRID_COLUMNS, CCX_DTVCC_SCREENGRID_ROWS};
@@ -82,21 +85,38 @@ impl dtvcc_tv_screen {
8285
}
8386

8487
#[cfg(windows)]
85-
if writer.writer_ctx.filename.is_null() && writer.writer_ctx.fhandle.is_null() {
86-
return Err("Filename missing".to_owned())?;
87-
} else if writer.writer_ctx.fhandle.is_null() {
88-
let filename = unsafe {
89-
CStr::from_ptr(writer.writer_ctx.filename)
90-
.to_str()
91-
.map_err(|err| err.to_string())
92-
}?;
93-
debug!("dtvcc_writer_output: creating {}", filename);
94-
let file = File::create(filename).map_err(|err| err.to_string())?;
95-
writer.writer_ctx.fhandle = file.into_raw_handle();
88+
if writer.writer_ctx.fhandle.is_null() {
89+
// Check if fd is valid (file was already opened by C code)
90+
// If so, convert fd to fhandle to avoid creating a new file (which would truncate)
91+
if writer.writer_ctx.fd >= 0 {
92+
let handle = unsafe { _get_osfhandle(writer.writer_ctx.fd) };
93+
if handle != -1 {
94+
debug!(
95+
"dtvcc_writer_output: converting fd {} to fhandle",
96+
writer.writer_ctx.fd
97+
);
98+
writer.writer_ctx.fhandle = handle as *mut _;
99+
}
100+
}
96101

97-
if is_false(writer.no_bom) {
98-
let BOM = [0xef, 0xbb, 0xbf];
99-
writer.write_to_file(&BOM)?;
102+
// If fhandle is still null, we need to create a new file
103+
if writer.writer_ctx.fhandle.is_null() {
104+
if writer.writer_ctx.filename.is_null() {
105+
return Err("Filename missing".to_owned())?;
106+
}
107+
let filename = unsafe {
108+
CStr::from_ptr(writer.writer_ctx.filename)
109+
.to_str()
110+
.map_err(|err| err.to_string())
111+
}?;
112+
debug!("dtvcc_writer_output: creating {}", filename);
113+
let file = File::create(filename).map_err(|err| err.to_string())?;
114+
writer.writer_ctx.fhandle = file.into_raw_handle();
115+
116+
if is_false(writer.no_bom) {
117+
let BOM = [0xef, 0xbb, 0xbf];
118+
writer.write_to_file(&BOM)?;
119+
}
100120
}
101121
}
102122
self.write(writer);

0 commit comments

Comments
 (0)