* 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.
*/
use std::{
fs,
io::{self, Error},
path::{Path, PathBuf},
};
use crate::tar::entry::Entry;
#[allow(unused)]
use crate::utils::hdc_log::*;
#[derive(Default)]
pub struct Compress {
entrys: Vec<Entry>,
prefix: PathBuf,
max_count: usize,
}
impl Compress {
pub fn new() -> Self {
Self {
entrys: Vec::new(),
prefix: PathBuf::new(),
max_count: 0,
}
}
pub fn updata_prefix(&mut self, prefix: PathBuf) {
self.prefix = prefix;
}
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(())
}
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(())
}
}