This commit is contained in:
2022-05-27 11:55:07 +00:00
committed by GitHub
parent 194f964e91
commit 106cb7347e

View File

@@ -7,6 +7,8 @@ use modular_bitfield::bitfield;
use modular_bitfield::prelude::B30;
use std::fmt::Debug;
use std::fmt::Display;
use std::io::Read;
use std::io::Write;
use std::sync::RwLock;
/// The data is out of bounds.
@@ -62,11 +64,28 @@ impl PdFilePartStatus {
Self { status: RwLock::new(status) }
}
#[inline]
/// Returns the downloaded size of this part
pub fn downloaded_size(&self) -> u32 {
self.status.get_ref().downloaded_size()
}
#[inline]
/// Returns the status of this part
pub fn status(&self) -> PdFilePartStatus2 {
self.status.get_ref().status()
}
/// Set the new downloaded size
pub fn set_downloaded_size(&self, new_size: u32) -> Result<(), PdFileError> {
match self.status.get_mut().set_downloaded_size_checked(new_size) {
Ok(_) => { Ok(()) }
Err(_) => {
Err(PdFileError::from(OutOfBoundsError::new("u32", new_size)))
}
}
}
/// Set the status of this part
pub fn set_status(&self, status: PdFilePartStatus2) -> Result<(), PdFileError> {
match self.status.get_mut().set_status_checked(status) {
@@ -107,12 +126,48 @@ impl PdFilePartStatus {
if (value.len() - offset) < 4 {
Err(gettext("At least 4 bytes is needed."))?;
}
let st = (value[offset] & 0xC0) / 0x20;
let st = (value[offset] & 0xC0) / 0x40;
let mut status = PdFilePartStatusInternal::new();
status.set_status(PdFilePartStatus2::from_int(st)?);
// #TODO
// Downloaded size
let mut ds: u32 = (value[offset] & 0x3f) as u32;
ds += (value[offset + 1] as u32) * 0x40;
ds += (value[offset + 2] as u32) * 0x40_00;
ds += (value[offset + 3] as u32) * 0x40_00_00;
status.set_downloaded_size(ds);
Ok(Self { status: RwLock::new(status) })
}
/// Get bytes
pub fn to_bytes(&self) -> Vec<u8> {
let mut data = Vec::new();
let mut tmp: u8 = self.status().int_value() * 0x40;
let ds = self.downloaded_size();
tmp += (ds & 0x3f) as u8;
data.push(tmp);
data.push(((ds & 0x3fc0) / 0x40) as u8);
data.push(((ds & 0x3f_c0_00) / 0x40_00) as u8);
data.push(((ds & 0x3f_c0_00_00) / 0x40_00_00) as u8);
data
}
/// Create a new instance of the [PdFilePartStatus] from reader
/// * `reader` - The reader which implement the [Read] trait
///
/// Returns Error or [PdFilePartStatus] instance.
pub fn read_from<R: Read>(reader: &mut R) -> Result<Self, PdFileError> {
let mut buf = [0u8; 4];
reader.read_exact(&mut buf)?;
Self::from_bytes(&buf, 0)
}
/// Write version bytes to writer.
/// * `writer` - The writer which implement the [Write] trait
///
/// Returns io Result.
pub fn write_to<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
writer.write_all(&self.to_bytes())
}
}
#[test]
@@ -121,6 +176,11 @@ fn test_part_status() {
let status = PdFilePartStatus::new();
assert_eq!(status.status(), PdFilePartStatus2::Waited);
assert_eq!(status.is_waited(), true);
let status = PdFilePartStatus::from_bytes(&[80u8, 0, 0, 0], 0).unwrap();
let status = PdFilePartStatus::from_bytes(&[132u8, 23, 3, 2], 0).unwrap();
assert_eq!(status.is_downloaded(), true);
assert_eq!(status.downloaded_size(), 0x80c5c4);
assert_eq!(status.to_bytes(), vec![132, 23, 3, 2]);
status.set_downloaded_size(0x323133).unwrap();
assert_eq!(status.downloaded_size(), 0x323133);
assert_eq!(status.to_bytes(), vec![179, 196, 200, 0]);
}