Skip to main content

ds_rom/rom/
overlay_table.rs

1use super::{
2    raw::{self, HmacSha1Signature},
3    Arm9, Overlay, OverlayError,
4};
5use crate::crypto::hmac_sha1::HmacSha1;
6
7/// An overlay table, used for both ARM9 and ARM7 overlays. This is the plain struct, see the raw one [here](super::raw::OverlayTable).
8#[derive(Clone, Default)]
9pub struct OverlayTable<'a> {
10    overlays: Vec<Overlay<'a>>,
11    signature: Option<HmacSha1Signature>,
12}
13
14impl<'a> OverlayTable<'a> {
15    /// Creates a new [`OverlayTable`].
16    pub fn new(overlays: Vec<Overlay<'a>>) -> Self {
17        Self { overlays, signature: None }
18    }
19
20    /// Returns a reference to the overlays of this [`OverlayTable`].
21    pub fn overlays(&self) -> &[Overlay<'a>] {
22        &self.overlays
23    }
24
25    /// Returns a mutable reference to the overlays of this [`OverlayTable`].
26    pub fn overlays_mut(&mut self) -> &mut [Overlay<'a>] {
27        &mut self.overlays
28    }
29
30    /// Returns the length of this [`OverlayTable`].
31    pub fn len(&self) -> usize {
32        self.overlays.len()
33    }
34
35    /// Returns `true` if this [`OverlayTable`] is empty.
36    pub fn is_empty(&self) -> bool {
37        self.overlays.is_empty()
38    }
39
40    /// Parses an [`OverlayTable`] from the given raw ARM9 overlay table.
41    ///
42    /// # Errors
43    ///
44    /// See [`Overlay::parse_arm9`].
45    pub fn parse_arm9(raw: raw::OverlayTable, rom: &'a raw::Rom, arm9: &Arm9) -> Result<Self, OverlayError> {
46        let overlays =
47            raw.overlays().iter().map(|overlay| Overlay::parse_arm9(overlay, rom, arm9)).collect::<Result<Vec<_>, _>>()?;
48        let signature = raw.signature();
49        Ok(Self { overlays, signature })
50    }
51
52    /// Parses an [`OverlayTable`] from the given raw ARM7 overlay table.
53    ///
54    /// # Errors
55    ///
56    /// See [`Overlay::parse_arm7`].
57    pub fn parse_arm7(raw: raw::OverlayTable, rom: &'a raw::Rom) -> Result<Self, OverlayError> {
58        let overlays =
59            raw.overlays().iter().map(|overlay| Overlay::parse_arm7(overlay, rom)).collect::<Result<Vec<_>, _>>()?;
60        let signature = raw.signature();
61        Ok(Self { overlays, signature })
62    }
63
64    /// Builds a raw overlay table.
65    pub fn build(&self) -> raw::OverlayTable<'a> {
66        let overlays: Vec<raw::Overlay> = self.overlays.iter().map(|overlay| overlay.build()).collect();
67        let signature = self.signature;
68        raw::OverlayTable::new(overlays, signature)
69    }
70
71    /// Computes the HMAC-SHA1 signature of this overlay table using the given HMAC-SHA1 instance.
72    pub fn compute_signature(&self, hmac_sha1: &HmacSha1) -> HmacSha1Signature {
73        self.build().compute_signature(hmac_sha1)
74    }
75
76    /// Verifies the HMAC-SHA1 signature of this overlay table using the given HMAC-SHA1 instance.
77    pub fn verify_signature(&self, hmac_sha1: &HmacSha1) -> bool {
78        self.build().verify_signature(hmac_sha1)
79    }
80
81    /// Returns the HMAC-SHA1 signature of this overlay table, if it exists.
82    pub fn signature(&self) -> Option<HmacSha1Signature> {
83        self.signature
84    }
85
86    /// Computes and sets the HMAC-SHA1 signature of this overlay table.
87    pub fn sign(&mut self, hmac_sha1: &HmacSha1) {
88        self.signature = Some(self.compute_signature(hmac_sha1));
89    }
90
91    /// Returns `true` if this overlay table has an HMAC-SHA1 signature.
92    pub fn is_signed(&self) -> bool {
93        self.signature.is_some()
94    }
95
96    /// Sets the signature of this overlay table.
97    pub fn set_signature(&mut self, signature: HmacSha1Signature) {
98        self.signature = Some(signature);
99    }
100}