/* * Copyright (C) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ //! compress use std::{ fs, io::{self, Error}, path::{Path, PathBuf}, }; use crate::tar::entry::Entry; #[allow(unused)] use crate::utils::hdc_log::*; /// Compress tar #[derive(Default)] pub struct Compress { entrys: Vec, prefix: PathBuf, max_count: usize, } impl Compress { /// new Compress pub fn new() -> Self { Self { entrys: Vec::new(), prefix: PathBuf::new(), max_count: 0, } } /// updata prefix pub fn updata_prefix(&mut self, prefix: PathBuf) { self.prefix = prefix; } /// updata max conunt /// default: 0, no limit /// other: Maximum number of entries allowed to be saved pub fn updata_max_count(&mut self, count: usize) { self.max_count = count; } fn add_path_recursion(&mut self, path: &Path) -> io::Result<()> { if !path.is_dir() { self.add_entry(&path.display().to_string())?; return Ok(()); } self.add_entry(&path.display().to_string())?; for entry in fs::read_dir(path)? { let entry = entry?; let entry_path = entry.path(); self.add_path_recursion(&entry_path)?; } Ok(()) } /// Add a path that needs to be packaged pub fn add_path(&mut self, path: &Path) -> io::Result<()> { self.add_path_recursion(path) } fn add_entry(&mut self, file: &str) -> io::Result<()> { if self.max_count > 0 && self.entrys.len() > self.max_count { return Err(Error::new( io::ErrorKind::Other, format!( "Exceeded the set maximum value, the maximum value is set to {}", self.max_count ), )); } if let Some(prefix) = self.prefix.to_str() { if prefix == file { crate::debug!("Ignoring compressed root directory"); return Ok(()); } } let entry = Entry::new(self.prefix.clone(), file); self.entrys.push(entry); Ok(()) } /// 开始将数据写入压缩包 pub fn compress(&mut self, file_path: PathBuf) -> io::Result<()> { if file_path.exists() && file_path.is_dir() { return Err(io::Error::new( io::ErrorKind::InvalidInput, format!("{} is not a file", file_path.display()), )); } let mut f = fs::OpenOptions::new() .read(true) .write(true) .create(true) .truncate(true) .open(file_path)?; for entry in &mut self.entrys { entry.read_data_to_file(&mut f)?; } Ok(()) } }