sqlrite/sql/pager/
header.rs1use crate::error::{Result, SQLRiteError};
7use crate::sql::pager::page::PAGE_SIZE;
8
9pub const MAGIC: &[u8; 16] = b"SQLRiteFormat\0\0\0";
12
13pub const FORMAT_VERSION: u16 = 3;
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub struct DbHeader {
30 pub page_count: u32,
31 pub schema_root_page: u32,
32}
33
34pub fn encode_header(h: &DbHeader) -> [u8; PAGE_SIZE] {
36 let mut buf = [0u8; PAGE_SIZE];
37 buf[0..16].copy_from_slice(MAGIC);
38 buf[16..18].copy_from_slice(&FORMAT_VERSION.to_le_bytes());
39 buf[18..20].copy_from_slice(&(PAGE_SIZE as u16).to_le_bytes());
40 buf[20..24].copy_from_slice(&h.page_count.to_le_bytes());
41 buf[24..28].copy_from_slice(&h.schema_root_page.to_le_bytes());
42 buf
43}
44
45pub fn decode_header(buf: &[u8]) -> Result<DbHeader> {
48 if buf.len() != PAGE_SIZE {
49 return Err(SQLRiteError::Internal(format!(
50 "header buffer length {} != PAGE_SIZE {PAGE_SIZE}",
51 buf.len()
52 )));
53 }
54 if &buf[0..16] != MAGIC {
55 return Err(SQLRiteError::General(
56 "file is not a SQLRite database (bad magic bytes)".to_string(),
57 ));
58 }
59 let version = u16::from_le_bytes(buf[16..18].try_into().unwrap());
60 if version != FORMAT_VERSION {
61 return Err(SQLRiteError::General(format!(
62 "unsupported SQLRite format version {version}; this build understands {FORMAT_VERSION}"
63 )));
64 }
65 let page_size = u16::from_le_bytes(buf[18..20].try_into().unwrap()) as usize;
66 if page_size != PAGE_SIZE {
67 return Err(SQLRiteError::General(format!(
68 "unsupported page size {page_size}; this build expects {PAGE_SIZE}"
69 )));
70 }
71 let page_count = u32::from_le_bytes(buf[20..24].try_into().unwrap());
72 let schema_root_page = u32::from_le_bytes(buf[24..28].try_into().unwrap());
73 Ok(DbHeader {
74 page_count,
75 schema_root_page,
76 })
77}