sq3_rs/file_header/reserved_bytes_per_page.rs
1use std::ops::Deref;
2
3use sq3_derive::Name;
4use sq3_parser::TypeName;
5
6use crate::{field_parsing_error, result::SqliteResult, traits::ParseBytes};
7
8/// # Reserved bytes per page (1 Byte)
9///
10/// Sqlite has the ability to set aside a small number of extra bytes at the
11/// end of every page for use by extensions. These extra bytes are used, for
12/// example, by the Sqlite Encryption Extension to store a nonce and/or
13/// cryptographic checksum associated with each page. The "reserved space" size
14/// in the 1-byte integer at offset 20 is the number of bytes of space at the
15/// end of each page to reserve for extensions. **This value is usually 0.** *The
16/// value can be odd.*
17///
18/// The **"usable size"** of a database page is the page size specified by the
19/// 2-byte integer at offset 16 in the header less the "reserved" space size
20/// recorded in the 1-byte integer at offset 20 in the header. The usable size
21/// of a page might be an odd number.
22///
23/// However, *the usable size is not allowed to be less than `480`*. In other words, if the page size is 512, then the
24/// reserved space size cannot exceed 32.
25///
26/// "This value is usually 0."
27///
28/// Reference: https://www.sqlite.org/fileformat2.html#resbyte
29#[derive(Debug, Default, Name, PartialEq, Eq)]
30pub struct ReservedBytesPerPage(u8);
31impl Deref for ReservedBytesPerPage {
32 type Target = u8;
33
34 fn deref(&self) -> &Self::Target {
35 &self.0
36 }
37}
38
39impl ParseBytes for ReservedBytesPerPage {
40 const LENGTH_BYTES: usize = 1;
41
42 fn parsing_handler(bytes: &[u8]) -> SqliteResult<Self> {
43 let reserved_bytes_per_page = *bytes
44 .first()
45 .ok_or(field_parsing_error! {Self::NAME.into()})?;
46
47 Ok(Self(reserved_bytes_per_page))
48 }
49}