libpijul_compat/backend/
file_header.rs1#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd)]
4pub struct FileMetadata(u16);
5const DIR_BIT: u16 = 0x200;
6use byteorder::ByteOrder;
7impl FileMetadata {
8 pub fn from_contents(p: &[u8]) -> Self {
11 debug_assert!(p.len() == 2);
12 FileMetadata(BigEndian::read_u16(p))
13 }
14
15 pub fn new(perm: usize, is_dir: bool) -> Self {
18 let mut m = FileMetadata(0);
19 m.set_permissions(perm as u16);
20 if is_dir {
21 m.set_dir()
22 } else {
23 m.unset_dir()
24 }
25 m
26 }
27
28 pub fn permissions(&self) -> u16 {
30 u16::from_le(self.0) & 0x1ff
31 }
32
33 pub fn set_permissions(&mut self, perm: u16) {
35 let bits = u16::from_le(self.0);
36 let perm = (bits & !0x1ff) | perm;
37 self.0 = perm.to_le()
38 }
39
40 pub fn is_dir(&self) -> bool {
42 u16::from_le(self.0) & DIR_BIT != 0
43 }
44
45 pub fn set_dir(&mut self) {
47 let bits = u16::from_le(self.0);
48 self.0 = (bits | DIR_BIT).to_le()
49 }
50
51 pub fn unset_dir(&mut self) {
53 let bits = u16::from_le(self.0);
54 self.0 = (bits & !DIR_BIT).to_le()
55 }
56}
57
58use byteorder::{BigEndian, WriteBytesExt};
59
60pub trait WriteMetadata: std::io::Write {
61 fn write_metadata(&mut self, m: FileMetadata) -> std::io::Result<()> {
62 self.write_u16::<BigEndian>(m.0)
63 }
64}
65impl<W: std::io::Write> WriteMetadata for W {}
66
67use super::key::*;
68use super::patch_id::*;
69use sanakirja::{Alignment, Representable};
70use std;
71#[repr(u8)]
72#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
73pub enum FileStatus {
74 Ok = 0,
75 Moved = 1,
76 Deleted = 2,
77 Zombie = 3,
78}
79
80#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord)]
82pub struct FileHeader {
83 pub metadata: FileMetadata,
84 pub status: FileStatus,
85 pub key: Key<PatchId>,
86}
87
88#[test]
89fn test_fileheader_alignment() {
90 assert_eq!(std::mem::size_of::<FileHeader>(), 2 + 1 + 16)
91}
92
93impl Representable for FileHeader {
94 fn alignment() -> Alignment {
95 Alignment::B1
96 }
97 fn onpage_size(&self) -> u16 {
98 std::mem::size_of::<FileHeader>() as u16
99 }
100 unsafe fn write_value(&self, p: *mut u8) {
101 let meta = self.metadata.0;
102 *p = (meta & 255) as u8;
103 *(p.offset(1)) = (meta >> 8) as u8;
104 *(p.offset(2)) = self.status as u8;
105 self.key.write_value(p.offset(3))
106 }
107 unsafe fn read_value(p: *const u8) -> Self {
108 let metadata = {
109 let x0 = (*p) as u16;
110 let x1 = (*(p.offset(1))) as u16;
111 std::mem::transmute((x1 << 8) | x0)
112 };
113 let status = std::mem::transmute(*(p.offset(2)));
114 let key: Key<PatchId> = Representable::read_value(p.offset(3));
115 FileHeader {
116 metadata,
117 status,
118 key,
119 }
120 }
121 unsafe fn cmp_value<T>(&self, _: &T, x: Self) -> std::cmp::Ordering {
122 self.cmp(&x)
123 }
124 type PageOffsets = std::iter::Empty<u64>;
125 fn page_offsets(&self) -> Self::PageOffsets {
126 std::iter::empty()
127 }
128}