From e68790d579316e52d660f0f56a32e9117a0c8dd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 16 Nov 2021 18:19:03 +0200 Subject: [PATCH] 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. --- gstreamer/src/log.rs | 75 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/gstreamer/src/log.rs b/gstreamer/src/log.rs index cb0099692..297ca0332 100644 --- a/gstreamer/src/log.rs +++ b/gstreamer/src/log.rs @@ -155,6 +155,7 @@ impl DebugCategory { #[inline] #[doc(alias = "gst_debug_log")] + #[doc(alias = "gst_debug_log_literal")] pub fn log>( self, obj: Option<&O>, @@ -180,16 +181,70 @@ impl DebugCategory { None => ptr::null_mut(), }; - 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, - fmt::format(args).replace("%", "%%").to_glib_none().0, - ); + #[cfg(feature = "v1_20")] + { + let mut w = 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_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, + ); + } } }