hff_core/read/
hff.rs

1use super::{DepthFirstIter, TableIter};
2use crate::{Chunk, Ecc, Header, IdType, Table, Version};
3use std::{
4    fmt::Debug,
5    mem::size_of,
6    ops::{Deref, DerefMut},
7};
8
9/// The Hff structure data.  This is an immutable representation of the
10/// content of an Hff stream.
11#[derive(Debug)]
12pub struct Hff<T: Debug> {
13    /// Was the structure in native endian?
14    native: bool,
15    /// The version of the file format.
16    version: Version,
17    /// The IdType of the hff.
18    id_type: IdType,
19    /// Content type of the hff.
20    content_type: Ecc,
21    /// The tables found in the header structure.
22    tables: Vec<Table>,
23    /// The chunks found within the header structure.
24    chunks: Vec<Chunk>,
25    /// Access system for the underlying stream.
26    accessor: T,
27}
28
29impl<T: Debug> Hff<T> {
30    /// Create a new Hff wrapper.
31    pub fn new(
32        accessor: T,
33        header: Header,
34        tables: impl Into<Vec<Table>>,
35        chunks: impl Into<Vec<Chunk>>,
36    ) -> Self {
37        Self {
38            native: header.is_native_endian(),
39            version: header.version(),
40            id_type: header.id_type(),
41            content_type: header.content_type(),
42            tables: tables.into(),
43            chunks: chunks.into(),
44            accessor,
45        }
46    }
47
48    /// Return if the structure of the source was in native endian.
49    pub fn is_native_endian(&self) -> bool {
50        self.native
51    }
52
53    /// Return the version of the file structure the file was read from.
54    pub fn version(&self) -> Version {
55        self.version
56    }
57
58    /// The type of the ID's used in the hff file.
59    pub fn id_type(&self) -> IdType {
60        self.id_type
61    }
62
63    /// Get the content type of the container.
64    pub fn content_type(&self) -> Ecc {
65        self.content_type
66    }
67
68    /// Get the offset from the start of the file to the start of the chunk data.
69    pub fn offset_to_data(&self) -> usize {
70        size_of::<Header>()
71            + (size_of::<Table>() * self.tables.len())
72            + (size_of::<Chunk>() * self.chunks.len())
73    }
74
75    /// Get an iterator over the tables in depth first order.
76    pub fn depth_first(&self) -> DepthFirstIter<'_, T> {
77        DepthFirstIter::new(self)
78    }
79
80    /// Get an iterator over the child tables.
81    pub fn tables(&self) -> TableIter<'_, T> {
82        TableIter::new(self, 0)
83    }
84
85    /// Get access to the table array.
86    pub fn tables_array(&self) -> &[Table] {
87        &self.tables
88    }
89
90    /// Get access to the chunk array.
91    pub fn chunks_array(&self) -> &[Chunk] {
92        &self.chunks
93    }
94}
95
96impl<T: Debug> Deref for Hff<T> {
97    type Target = T;
98
99    fn deref(&self) -> &Self::Target {
100        &self.accessor
101    }
102}
103
104impl<T: Debug> DerefMut for Hff<T> {
105    fn deref_mut(&mut self) -> &mut Self::Target {
106        &mut self.accessor
107    }
108}