hff_core/
chunk.rs

1use crate::{Identifier, Result};
2use byteorder::{ByteOrder, ReadBytesExt, WriteBytesExt};
3use std::{
4    fmt::Debug,
5    io::{Read, Write},
6};
7
8/// Specifies a chunk of data within the file.
9#[repr(C, align(16))]
10#[derive(Copy, Clone, PartialEq, Hash)]
11pub struct Chunk {
12    /// The identifier for the chunk.
13    identifier: Identifier,
14    /// Length of the chunk data.  (Not rounded to 16 bytes.)
15    length: u64,
16    /// Offset of the data from the start of the file.
17    offset: u64,
18}
19
20impl Debug for Chunk {
21    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22        write!(
23            f,
24            "({:X}) - {}, {}",
25            *self.identifier, self.length, self.offset
26        )
27    }
28}
29
30impl Chunk {
31    /// Size of the chunk entry.
32    pub const SIZE: usize = std::mem::size_of::<Self>();
33
34    /// Create a new chunk instance.
35    pub fn new(identifier: impl Into<Identifier>, length: u64, offset: u64) -> Self {
36        Self {
37            identifier: identifier.into(),
38            length,
39            offset,
40        }
41    }
42
43    /// Get the identifier.
44    pub fn identifier(&self) -> Identifier {
45        self.identifier
46    }
47
48    /// Get the length of the content.
49    pub fn length(&self) -> u64 {
50        self.length
51    }
52
53    /// Get the length mutably.
54    pub fn length_mut(&mut self) -> &mut u64 {
55        &mut self.length
56    }
57
58    /// Get the offset of the content.
59    pub fn offset(&self) -> u64 {
60        self.offset
61    }
62
63    /// Get the offset mutably.
64    pub fn offset_mut(&mut self) -> &mut u64 {
65        &mut self.offset
66    }
67
68    /// Read a table from the given stream.
69    pub fn read<E: ByteOrder>(reader: &mut dyn Read) -> Result<Self> {
70        Ok(Self {
71            identifier: reader.read_u128::<E>()?.try_into()?,
72            length: reader.read_u64::<E>()?,
73            offset: reader.read_u64::<E>()?,
74        })
75    }
76
77    /// Write a table to the given stream.
78    pub fn write<E: ByteOrder>(self, writer: &mut dyn Write) -> Result<()> {
79        writer.write_u128::<E>(*self.identifier)?;
80        writer.write_u64::<E>(self.length)?;
81        writer.write_u64::<E>(self.offset)?;
82
83        Ok(())
84    }
85}