gstreamer: Directly format into a NUL-terminated C string for debug log messages

And also replace `%` with `%%` for < 1.20 inline, and for >= 1.20 use
the new `gst_debug_log_literal()` function that doesn't require this and
also reduces string allocations further.
This commit is contained in:
Sebastian Dröge 2021-11-16 18:19:03 +02:00
parent e74f54a64f
commit e68790d579

View file

@ -155,6 +155,7 @@ impl DebugCategory {
#[inline] #[inline]
#[doc(alias = "gst_debug_log")] #[doc(alias = "gst_debug_log")]
#[doc(alias = "gst_debug_log_literal")]
pub fn log<O: IsA<glib::Object>>( pub fn log<O: IsA<glib::Object>>(
self, self,
obj: Option<&O>, obj: Option<&O>,
@ -180,16 +181,70 @@ impl DebugCategory {
None => ptr::null_mut(), None => ptr::null_mut(),
}; };
unsafe { #[cfg(feature = "v1_20")]
ffi::gst_debug_log( {
cat.as_ptr(), let mut w = glib::GStringBuilder::default();
level.into_glib(),
file.to_glib_none().0, // Can't really happen but better safe than sorry
module.to_glib_none().0, if fmt::write(&mut w, args).is_err() {
line as i32, return;
obj_ptr, }
fmt::format(args).replace("%", "%%").to_glib_none().0,
); unsafe {
ffi::gst_debug_log_literal(
cat.as_ptr(),
level.into_glib(),
file.to_glib_none().0,
module.to_glib_none().0,
line as i32,
obj_ptr,
w.into_string().to_glib_none().0,
);
}
}
#[cfg(not(feature = "v1_20"))]
{
// Replace literal percentage signs with two so that they are not interpreted as printf
// format specifiers
struct Write(glib::GStringBuilder);
impl fmt::Write for Write {
fn write_str(&mut self, mut s: &str) -> Result<(), fmt::Error> {
while let Some((prefix, suffix)) = s.split_once('%') {
self.0.append(prefix);
self.0.append("%%");
s = suffix;
}
self.0.append(s);
Ok(())
}
fn write_char(&mut self, c: char) -> fmt::Result {
if c == '%' {
self.0.append("%%");
} else {
self.0.append_c(c);
}
Ok(())
}
}
let mut w = Write(glib::GStringBuilder::default());
// Can't really happen but better safe than sorry
if fmt::write(&mut w, args).is_err() {
return;
}
unsafe {
ffi::gst_debug_log(
cat.as_ptr(),
level.into_glib(),
file.to_glib_none().0,
module.to_glib_none().0,
line as i32,
obj_ptr,
w.0.into_string().to_glib_none().0,
);
}
} }
} }