use crate::common::is_binary::is_binary; use crate::common::PIPESIZE; use crate::meta_plugin::{MetaPlugin, MetaPluginResponse}; #[derive(Debug, Clone, Default)] pub struct BinaryMetaPlugin { buffer: Vec, max_buffer_size: usize, is_finalized: bool, base: crate::meta_plugin::BaseMetaPlugin, } impl BinaryMetaPlugin { pub fn new( options: Option>, outputs: Option>, ) -> BinaryMetaPlugin { let mut base = crate::meta_plugin::BaseMetaPlugin::new(); base.meta_name = "binary".to_string(); // Initialize with helper function base.initialize_plugin( &["binary"], options, outputs, ); let max_buffer_size = base.options.get("max_buffer_size") .and_then(|v| v.as_u64()) .unwrap_or(PIPESIZE as u64) as usize; BinaryMetaPlugin { buffer: Vec::new(), max_buffer_size, is_finalized: false, base, } } } impl MetaPlugin for BinaryMetaPlugin { fn is_finalized(&self) -> bool { self.is_finalized } fn set_finalized(&mut self, finalized: bool) { self.is_finalized = finalized; } fn update(&mut self, data: &[u8]) -> MetaPluginResponse { // If already finalized, don't process more data if self.is_finalized { return MetaPluginResponse { metadata: Vec::new(), is_finalized: true, }; } // Calculate how much data we can still accept let remaining_capacity = self.max_buffer_size.saturating_sub(self.buffer.len()); if remaining_capacity > 0 { // Determine how much data to copy let bytes_to_take = std::cmp::min(data.len(), remaining_capacity); // Add data to our buffer self.buffer.extend_from_slice(&data[..bytes_to_take]); } // If we've reached our buffer limit, return metadata let mut metadata = Vec::new(); if self.buffer.len() >= self.max_buffer_size { let is_binary_result = is_binary(&self.buffer); let value = if is_binary_result { "true".to_string() } else { "false".to_string() }; // Use process_metadata_outputs to handle output mapping if let Some(meta_data) = crate::meta_plugin::process_metadata_outputs( "binary", serde_yaml::Value::String(value), self.base.outputs() ) { metadata.push(meta_data); } // Mark as finalized self.is_finalized = true; } let is_finalized = !metadata.is_empty(); MetaPluginResponse { metadata, is_finalized, } } fn finalize(&mut self) -> MetaPluginResponse { // If already finalized, don't process again if self.is_finalized { return MetaPluginResponse { metadata: Vec::new(), is_finalized: true, }; } let mut metadata = Vec::new(); // Save the binary detection result when finalizing let is_binary_result = is_binary(&self.buffer); let value = if is_binary_result { "true".to_string() } else { "false".to_string() }; // Use process_metadata_outputs to handle output mapping if let Some(meta_data) = crate::meta_plugin::process_metadata_outputs( "binary", serde_yaml::Value::String(value), self.base.outputs() ) { metadata.push(meta_data); } // Mark as finalized self.is_finalized = true; MetaPluginResponse { metadata, is_finalized: true, } } fn meta_name(&self) -> String { self.base.meta_name.clone() } fn outputs(&self) -> &std::collections::HashMap { self.base.outputs() } fn outputs_mut(&mut self) -> &mut std::collections::HashMap { self.base.outputs_mut() } fn default_outputs(&self) -> Vec { vec!["binary".to_string()] } fn options(&self) -> &std::collections::HashMap { self.base.options() } fn options_mut(&mut self) -> &mut std::collections::HashMap { self.base.options_mut() } }