1#![no_std]
2#![forbid(unsafe_code)]
3
4#[cfg(feature = "alloc")]
5extern crate alloc;
6
7pub use int_enum::{IntEnum, IntEnumError};
8
9pub mod hash_table;
10pub mod hilbert;
11pub mod linear_table;
12
13pub const MAGIC: [u8; 4] = [b'Y', b'g', b'L', b'n'];
14
15#[derive(Clone, Copy, Debug, IntEnum)]
16#[repr(u32)]
17#[rustfmt::skip]
18pub enum FileType {
19 None = 0x0000_0000,
20 Text = 0x0000_0001,
21}
22
23#[derive(Clone, Copy, Debug)]
24pub struct FileHeader {
25 pub magic: [u8; 4],
26 pub generator: u32,
27 pub typ: u32,
28 pub version: u32,
29}
30
31impl FileHeader {
32 pub fn decode(data: [u8; 16]) -> Self {
33 Self {
34 magic: data[0..4].try_into().unwrap(),
35 generator: u32::from_be_bytes(data[4..8].try_into().unwrap()),
36 typ: u32::from_be_bytes(data[8..12].try_into().unwrap()),
37 version: u32::from_be_bytes(data[12..16].try_into().unwrap()),
38 }
39 }
40
41 pub fn encode(&self) -> [u8; 16] {
42 let mut data = [0u8; 16];
43 data[0..4].copy_from_slice(&self.magic);
44 data[4..8].copy_from_slice(&u32::to_be_bytes(self.generator));
45 data[8..12].copy_from_slice(&u32::to_be_bytes(self.typ));
46 data[12..16].copy_from_slice(&u32::to_be_bytes(self.version));
47 data
48 }
49}
50
51#[derive(Clone, Copy, Debug, IntEnum)]
52#[repr(u32)]
53#[rustfmt::skip]
54pub enum Type {
55 PlainText = 0x0000_0000,
56 NestedText = 0x0000_0001,
57
58 StringTable = 0x0000_0010,
59 LinearPlain = 0x0000_0012,
60
61 HashPlain = 0x0000_0020,
62 HashLink = 0x0000_0021,
63
64 X2dhcPlain = 0x0000_0030,
65 X2dhcLink = 0x0000_0031,
66}
67
68#[derive(Clone, Copy, Debug, IntEnum)]
69#[repr(u16)]
70#[rustfmt::skip]
71pub enum Ntt01 {
72 Div = 0x0000,
73 Group = 0x0001,
74 Header = 0x0002,
75 Quote = 0x0003,
76 Code = 0x0004,
77}
78
79pub fn trunc_key_at0(key: &[u8]) -> &[u8] {
80 memchr::memchr(0, key)
81 .map(|key_end| &key[..key_end])
82 .unwrap_or(key)
83}
84
85#[inline]
86pub fn decode_location(location: u32) -> Option<usize> {
87 usize::try_from(location).ok()?.checked_mul(16)
88}
89
90#[derive(Clone, Copy)]
92pub struct StrtabDescriptorRef<'a> {
93 pub data: &'a [u8],
94
95 pub location: u32,
97}
98
99impl core::ops::Index<u32> for StrtabDescriptorRef<'_> {
100 type Output = [u8];
101
102 fn index(&self, index: u32) -> &[u8] {
103 trunc_key_at0(&self.data[index.try_into().unwrap()..])
104 }
105}