1use std::fmt::Debug;
4
5use super::{block_ref::*, byte_index::*, read_write::*, *};
6use crate::{AnsiPstFile, PstFile, UnicodePstFile};
7
8#[repr(u8)]
13#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)]
14pub enum AmapStatus {
15 #[default]
17 Invalid = 0x00,
18 Valid1 = 0x01,
20 Valid2 = 0x02,
22}
23
24impl TryFrom<u8> for AmapStatus {
25 type Error = NdbError;
26
27 fn try_from(value: u8) -> Result<Self, Self::Error> {
28 match value {
29 0x00 => Ok(AmapStatus::Invalid),
30 0x01 => Ok(AmapStatus::Valid1),
31 0x02 => Ok(AmapStatus::Valid2),
32 _ => Err(NdbError::InvalidAmapStatus(value)),
33 }
34 }
35}
36
37impl From<AmapStatus> for bool {
38 fn from(status: AmapStatus) -> bool {
39 status != AmapStatus::Invalid
40 }
41}
42
43pub trait Root<Pst>
44where
45 Pst: PstFile,
46{
47 fn file_eof_index(&self) -> &<Pst as PstFile>::ByteIndex;
48 fn amap_last_index(&self) -> &<Pst as PstFile>::ByteIndex;
49 fn amap_free_size(&self) -> &<Pst as PstFile>::ByteIndex;
50 fn pmap_free_size(&self) -> &<Pst as PstFile>::ByteIndex;
51 fn node_btree(&self) -> &<Pst as PstFile>::PageRef;
52 fn block_btree(&self) -> &<Pst as PstFile>::PageRef;
53 fn amap_is_valid(&self) -> AmapStatus;
54}
55
56#[derive(Clone, Debug)]
57pub struct UnicodeRoot {
58 reserved1: u32,
59 file_eof_index: UnicodeByteIndex,
60 amap_last_index: UnicodeByteIndex,
61 amap_free_size: UnicodeByteIndex,
62 pmap_free_size: UnicodeByteIndex,
63 node_btree: UnicodePageRef,
64 block_btree: UnicodePageRef,
65 amap_is_valid: AmapStatus,
66 reserved2: u8,
67 reserved3: u16,
68}
69
70impl UnicodeRoot {
71 pub fn new(
72 file_eof_index: UnicodeByteIndex,
73 amap_last_index: UnicodeByteIndex,
74 amap_free_size: UnicodeByteIndex,
75 pmap_free_size: UnicodeByteIndex,
76 node_btree: UnicodePageRef,
77 block_btree: UnicodePageRef,
78 amap_is_valid: AmapStatus,
79 ) -> Self {
80 Self {
81 reserved1: Default::default(),
82 file_eof_index,
83 amap_last_index,
84 amap_free_size,
85 pmap_free_size,
86 node_btree,
87 block_btree,
88 amap_is_valid,
89 reserved2: Default::default(),
90 reserved3: Default::default(),
91 }
92 }
93}
94
95impl Root<UnicodePstFile> for UnicodeRoot {
96 fn file_eof_index(&self) -> &UnicodeByteIndex {
97 &self.file_eof_index
98 }
99
100 fn amap_last_index(&self) -> &UnicodeByteIndex {
101 &self.amap_last_index
102 }
103
104 fn amap_free_size(&self) -> &UnicodeByteIndex {
105 &self.amap_free_size
106 }
107
108 fn pmap_free_size(&self) -> &UnicodeByteIndex {
109 &self.pmap_free_size
110 }
111
112 fn node_btree(&self) -> &UnicodePageRef {
113 &self.node_btree
114 }
115
116 fn block_btree(&self) -> &UnicodePageRef {
117 &self.block_btree
118 }
119
120 fn amap_is_valid(&self) -> AmapStatus {
121 self.amap_is_valid
122 }
123}
124
125impl RootReadWrite<UnicodePstFile> for UnicodeRoot {
126 fn new(
127 file_eof_index: UnicodeByteIndex,
128 amap_last_index: UnicodeByteIndex,
129 amap_free_size: UnicodeByteIndex,
130 pmap_free_size: UnicodeByteIndex,
131 node_btree: UnicodePageRef,
132 block_btree: UnicodePageRef,
133 amap_is_valid: AmapStatus,
134 ) -> Self {
135 Self::new(
136 file_eof_index,
137 amap_last_index,
138 amap_free_size,
139 pmap_free_size,
140 node_btree,
141 block_btree,
142 amap_is_valid,
143 )
144 }
145
146 fn load_reserved(&mut self, reserved1: u32, reserved2: u8, reserved3: u16) {
147 self.reserved1 = reserved1;
148 self.reserved2 = reserved2;
149 self.reserved3 = reserved3;
150 }
151
152 fn reserved1(&self) -> u32 {
153 self.reserved1
154 }
155
156 fn reserved2(&self) -> u8 {
157 self.reserved2
158 }
159
160 fn reserved3(&self) -> u16 {
161 self.reserved3
162 }
163
164 fn set_amap_status(&mut self, status: AmapStatus) {
165 self.amap_is_valid = status;
166 }
167
168 fn reset_free_size(&mut self, free_bytes: UnicodeByteIndex) -> NdbResult<()> {
169 self.amap_free_size = free_bytes;
170 self.pmap_free_size = 0.into();
171 Ok(())
172 }
173}
174
175#[derive(Clone, Debug)]
176pub struct AnsiRoot {
177 file_eof_index: AnsiByteIndex,
178 amap_last_index: AnsiByteIndex,
179 amap_free_size: AnsiByteIndex,
180 pmap_free_size: AnsiByteIndex,
181 node_btree: AnsiPageRef,
182 block_btree: AnsiPageRef,
183 amap_is_valid: AmapStatus,
184 reserved1: u32,
185 reserved2: u8,
186 reserved3: u16,
187}
188
189impl AnsiRoot {
190 pub fn new(
191 file_eof_index: AnsiByteIndex,
192 amap_last_index: AnsiByteIndex,
193 amap_free_size: AnsiByteIndex,
194 pmap_free_size: AnsiByteIndex,
195 node_btree: AnsiPageRef,
196 block_btree: AnsiPageRef,
197 amap_is_valid: AmapStatus,
198 ) -> Self {
199 Self {
200 reserved1: Default::default(),
201 file_eof_index,
202 amap_last_index,
203 amap_free_size,
204 pmap_free_size,
205 node_btree,
206 block_btree,
207 amap_is_valid,
208 reserved2: Default::default(),
209 reserved3: Default::default(),
210 }
211 }
212}
213
214impl Root<AnsiPstFile> for AnsiRoot {
215 fn file_eof_index(&self) -> &AnsiByteIndex {
216 &self.file_eof_index
217 }
218
219 fn amap_last_index(&self) -> &AnsiByteIndex {
220 &self.amap_last_index
221 }
222
223 fn amap_free_size(&self) -> &AnsiByteIndex {
224 &self.amap_free_size
225 }
226
227 fn pmap_free_size(&self) -> &AnsiByteIndex {
228 &self.pmap_free_size
229 }
230
231 fn node_btree(&self) -> &AnsiPageRef {
232 &self.node_btree
233 }
234
235 fn block_btree(&self) -> &AnsiPageRef {
236 &self.block_btree
237 }
238
239 fn amap_is_valid(&self) -> AmapStatus {
240 self.amap_is_valid
241 }
242}
243
244impl RootReadWrite<AnsiPstFile> for AnsiRoot {
245 fn new(
246 file_eof_index: AnsiByteIndex,
247 amap_last_index: AnsiByteIndex,
248 amap_free_size: AnsiByteIndex,
249 pmap_free_size: AnsiByteIndex,
250 node_btree: AnsiPageRef,
251 block_btree: AnsiPageRef,
252 amap_is_valid: AmapStatus,
253 ) -> Self {
254 Self::new(
255 file_eof_index,
256 amap_last_index,
257 amap_free_size,
258 pmap_free_size,
259 node_btree,
260 block_btree,
261 amap_is_valid,
262 )
263 }
264
265 fn load_reserved(&mut self, reserved1: u32, reserved2: u8, reserved3: u16) {
266 self.reserved1 = reserved1;
267 self.reserved2 = reserved2;
268 self.reserved3 = reserved3;
269 }
270
271 fn reserved1(&self) -> u32 {
272 self.reserved1
273 }
274
275 fn reserved2(&self) -> u8 {
276 self.reserved2
277 }
278
279 fn reserved3(&self) -> u16 {
280 self.reserved3
281 }
282
283 fn set_amap_status(&mut self, status: AmapStatus) {
284 self.amap_is_valid = status;
285 }
286
287 fn reset_free_size(&mut self, free_bytes: AnsiByteIndex) -> NdbResult<()> {
288 self.amap_free_size = free_bytes;
289 self.pmap_free_size = 0.into();
290 Ok(())
291 }
292}