urna_format/layout/
header.rs1use crate::error::UrnaError;
8use sha2::{Digest, Sha256};
9
10use super::{URNA_MAGIC, URNA_VERSION_MAJOR, URNA_VERSION_MINOR};
11
12#[repr(C)]
17#[derive(Clone, Copy, Debug, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
18pub struct UrnaHeader {
19 pub magic: [u8; 4],
20 pub version_major: u16,
21 pub version_minor: u16,
22 pub flags: u32,
23 pub embedding_dim: u32,
24 pub n_chunks: u64,
25 pub n_embeddings: u64,
26 pub file_size: u64,
27 pub section_table_offset: u64,
28 pub section_table_count: u64,
29 pub manifest_offset: u64,
30 pub manifest_size: u64,
31 pub header_checksum: [u8; 8],
32 pub reserved: [u8; 48],
33}
34
35impl UrnaHeader {
36 #[allow(clippy::too_many_arguments)]
37 pub fn new(
38 embedding_dim: u32,
39 n_chunks: u64,
40 n_embeddings: u64,
41 file_size: u64,
42 section_table_offset: u64,
43 section_table_count: u64,
44 manifest_offset: u64,
45 manifest_size: u64,
46 ) -> Self {
47 let mut h = Self {
48 magic: *URNA_MAGIC,
49 version_major: URNA_VERSION_MAJOR,
50 version_minor: URNA_VERSION_MINOR,
51 flags: 0,
52 embedding_dim,
53 n_chunks,
54 n_embeddings,
55 file_size,
56 section_table_offset,
57 section_table_count,
58 manifest_offset,
59 manifest_size,
60 header_checksum: [0; 8],
61 reserved: [0; 48],
62 };
63 h.compute_checksum();
64 h
65 }
66
67 pub fn compute_checksum(&mut self) {
68 let bytes = self.as_bytes_without_checksum();
69 let hash = Sha256::digest(&bytes);
70 self.header_checksum.copy_from_slice(&hash[..8]);
71 }
72
73 pub fn validate_checksum(&self) -> crate::Result<()> {
74 let mut tmp = *self;
75 tmp.header_checksum = [0; 8];
76 let bytes = tmp.as_bytes_without_checksum();
77 let hash = Sha256::digest(&bytes);
78 if hash[..8] != self.header_checksum[..] {
79 return Err(UrnaError::InvalidHeaderChecksum);
80 }
81 Ok(())
82 }
83
84 pub fn as_bytes(&self) -> &[u8] {
87 bytemuck::bytes_of(self)
88 }
89
90 pub fn as_bytes_mut(&mut self) -> &mut [u8] {
94 bytemuck::bytes_of_mut(self)
95 }
96
97 fn as_bytes_without_checksum(&self) -> Vec<u8> {
98 let bytes = self.as_bytes();
99 let mut v = bytes[..72].to_vec();
100 v.extend_from_slice(&bytes[80..]);
101 v
102 }
103}
104
105impl Default for UrnaHeader {
106 fn default() -> Self {
107 Self::new(0, 0, 0, 128, 128, 0, 128, 0)
108 }
109}