use flate2::read::GzDecoder;
use std::io::Read;
use tar::Archive;
use super::WorkflowRegistryImpl;
use crate::registry::error::RegistryError;
use crate::registry::traits::RegistryStorage;
impl<S: RegistryStorage> WorkflowRegistryImpl<S> {
pub(super) fn is_cloacina_package(data: &[u8]) -> bool {
data.len() >= 3 && data[0] == 0x1f && data[1] == 0x8b && data[2] == 0x08
}
pub(super) async fn extract_so_from_cloacina(
package_data: &[u8],
) -> Result<Vec<u8>, RegistryError> {
let cursor = std::io::Cursor::new(package_data);
let gz_decoder = GzDecoder::new(cursor);
let mut archive = Archive::new(gz_decoder);
for entry in archive
.entries()
.map_err(|e| RegistryError::ValidationError {
reason: format!("Failed to read archive entries: {}", e),
})?
{
let mut entry = entry.map_err(|e| RegistryError::ValidationError {
reason: format!("Failed to read archive entry: {}", e),
})?;
let path = entry.path().map_err(|e| RegistryError::ValidationError {
reason: format!("Failed to get entry path: {}", e),
})?;
if let Some(extension) = path.extension() {
if extension == "so" || extension == "dylib" || extension == "dll" {
let mut library_data = Vec::new();
entry.read_to_end(&mut library_data).map_err(|e| {
RegistryError::ValidationError {
reason: format!("Failed to read library file from archive: {}", e),
}
})?;
return Ok(library_data);
}
}
}
Err(RegistryError::ValidationError {
reason: "No dynamic library file (.so/.dylib/.dll) found in .cloacina package"
.to_string(),
})
}
}