117 lines
3.6 KiB
Rust
117 lines
3.6 KiB
Rust
use crate::Signature;
|
|
use androscalpel_serializer::{ReadSeek, Result, Serializable};
|
|
use std::io::{SeekFrom, Write};
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub enum DataDescriptor {
|
|
Zip32(DataDescriptor32),
|
|
Zip64(DataDescriptor64),
|
|
}
|
|
|
|
/// DataDescriptor for 32bit zip format.
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub struct DataDescriptor32 {
|
|
// signature: Option<Signature(0x08074b50)>
|
|
pub crc_32: u32,
|
|
pub compressed_size: u32,
|
|
pub uncompressed_size: u32,
|
|
/// For reproducibility. This should be true when writting a zip, but can be false when
|
|
/// reading one. If we want to stick to the original, we need to keep this information.
|
|
pub use_signature: bool,
|
|
}
|
|
|
|
/// DataDescriptor for 64bit zip format.
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub struct DataDescriptor64 {
|
|
// signature: Option<Signature(0x08074b50)>
|
|
pub crc_32: u32,
|
|
pub compressed_size: u64,
|
|
pub uncompressed_size: u64,
|
|
/// For reproducibility. This should be true when writting a zip, but can be false when
|
|
/// reading one. If we want to stick to the original, we need to keep this information.
|
|
pub use_signature: bool,
|
|
}
|
|
|
|
impl DataDescriptor32 {
|
|
const SIGNATURE: Signature = Signature(0x02014b50);
|
|
}
|
|
|
|
impl Serializable for DataDescriptor32 {
|
|
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
|
if self.use_signature {
|
|
Self::SIGNATURE.serialize(output)?;
|
|
}
|
|
self.crc_32.serialize(output)?;
|
|
self.compressed_size.serialize(output)?;
|
|
self.uncompressed_size.serialize(output)
|
|
}
|
|
|
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
|
let pos = input.stream_position().unwrap(); //TODO
|
|
let signature = Signature::deserialize(input)?;
|
|
let use_signature = if signature != Self::SIGNATURE {
|
|
input.seek(SeekFrom::Start(pos)).unwrap(); //TODO
|
|
false
|
|
} else {
|
|
true
|
|
};
|
|
let crc_32 = u32::deserialize(input)?;
|
|
let compressed_size = u32::deserialize(input)?;
|
|
let uncompressed_size = u32::deserialize(input)?;
|
|
Ok(Self {
|
|
crc_32,
|
|
compressed_size,
|
|
uncompressed_size,
|
|
use_signature,
|
|
})
|
|
}
|
|
fn size(&self) -> usize {
|
|
12 + if self.use_signature {
|
|
Self::SIGNATURE.size()
|
|
} else {
|
|
0
|
|
}
|
|
}
|
|
}
|
|
|
|
impl DataDescriptor64 {
|
|
const SIGNATURE: Signature = Signature(0x02014b50);
|
|
}
|
|
|
|
impl Serializable for DataDescriptor64 {
|
|
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
|
if self.use_signature {
|
|
Self::SIGNATURE.serialize(output)?;
|
|
}
|
|
self.crc_32.serialize(output)?;
|
|
self.compressed_size.serialize(output)?;
|
|
self.uncompressed_size.serialize(output)
|
|
}
|
|
|
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
|
let pos = input.stream_position().unwrap(); //TODO
|
|
let signature = Signature::deserialize(input)?;
|
|
let use_signature = if signature != Self::SIGNATURE {
|
|
input.seek(SeekFrom::Start(pos)).unwrap(); //TODO
|
|
false
|
|
} else {
|
|
true
|
|
};
|
|
let crc_32 = u32::deserialize(input)?;
|
|
let compressed_size = u64::deserialize(input)?;
|
|
let uncompressed_size = u64::deserialize(input)?;
|
|
Ok(Self {
|
|
crc_32,
|
|
compressed_size,
|
|
uncompressed_size,
|
|
use_signature,
|
|
})
|
|
}
|
|
fn size(&self) -> usize {
|
|
20 + if self.use_signature {
|
|
Self::SIGNATURE.size()
|
|
} else {
|
|
0
|
|
}
|
|
}
|
|
}
|