ds_rom/rom/
overlay_table.rs

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