implement file insertion

This commit is contained in:
Jean-Marie Mineau 2024-01-22 14:22:28 +01:00
parent 7b6a5980c8
commit 0f5764c340
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
4 changed files with 98 additions and 17 deletions

View file

@ -1,10 +1,9 @@
use std::io::{SeekFrom, Write};
use crate::compression::CompressionMethod;
use crate::cp437::string_to_cp437;
use crate::error::Error;
use crate::extra_fields::{ExtraField, GenericExtraField, Zip64ExtraField};
use crate::{cp437, general_purpose_flags, Encoding, Signature};
use crate::{cp437, external_file_attributes, general_purpose_flags, Encoding, Signature};
use androscalpel_serializer::{ReadSeek, Result, Serializable};
#[derive(Debug, Clone, PartialEq, Eq)]
@ -191,18 +190,10 @@ impl FileHeader {
const MIN_SIZE: usize = 4 + 6 * 2 + 4 * 3 + 5 * 2 + 4 * 2;
pub fn new_default(name: &str) -> Self {
let mut general_purpose_flags = 0;
let file_name = match string_to_cp437(name) {
Ok(name) => name,
Err(Error::NotCp437) => {
general_purpose_flags |= general_purpose_flags::MASK_UTF8_FILENAME;
name.as_bytes().into()
}
};
FileHeader {
let mut header = FileHeader {
version_made_by: 768,
version_needed_to_extract: 0,
general_purpose_flags,
general_purpose_flags: 0,
compression_method: CompressionMethod::Deflated,
last_mod_file_time: 0,
last_mod_file_data: 0,
@ -211,13 +202,20 @@ impl FileHeader {
uncompressed_size: 0,
disk_number_start: 0,
internal_file_attributes: 0,
external_file_attributes: 0b1000000110100100 << 16, // TODO
// TODO: why 0b10000000 ?
external_file_attributes: external_file_attributes::REGULAR_FILE
| external_file_attributes::PERM_UR
| external_file_attributes::PERM_UW
| external_file_attributes::PERM_GR
| external_file_attributes::PERM_OR, // TODO
offset_local_header: 0,
file_name,
file_name: vec![],
extra_field: vec![],
malformed_extra_field: vec![],
file_comment: vec![],
}
};
header.set_name(name);
header
}
pub fn get_name_encoding(&self) -> Encoding {
@ -227,13 +225,36 @@ impl FileHeader {
Encoding::CP437
}
}
pub fn get_name(&self) -> String {
match self.get_name_encoding() {
Encoding::UTF8 => std::str::from_utf8(&self.file_name).unwrap().into(),
Encoding::CP437 => cp437::cp437_to_string(&self.file_name),
}
}
pub fn external_file_attributes_set_flag(&mut self, flag: u32) {
self.external_file_attributes |= flag;
}
pub fn external_file_attributes_unset_flag(&mut self, flag: u32) {
self.external_file_attributes &= !flag;
}
pub fn set_file_type(&mut self, file_type: u32) {
self.external_file_attributes &= !external_file_attributes::MASK_FILE_TYPE;
self.external_file_attributes |= file_type;
}
pub fn set_name(&mut self, name: &str) {
let file_name = match cp437::string_to_cp437(name) {
Ok(name) => {
self.general_purpose_flags &= !general_purpose_flags::MASK_UTF8_FILENAME;
name
}
Err(Error::NotCp437) => {
self.general_purpose_flags |= general_purpose_flags::MASK_UTF8_FILENAME;
name.as_bytes().into()
}
};
self.file_name = file_name;
}
pub fn get_uncompressed_size(&self) -> u64 {
if self.uncompressed_size != u32::MAX {