1use byteorder::{ByteOrder, NetworkEndian};
2
3use crate::base::header::{offsets, Header};
4use crate::types::{Flags, ImmutableData, Kind, MutableData};
5
6pub struct WireHeader<T: ImmutableData> {
9 pub(crate) buff: T,
10}
11
12impl<T: ImmutableData> From<&WireHeader<T>> for Header {
13 fn from(wh: &WireHeader<T>) -> Header {
15 Header::new(wh.application_id(), wh.kind(), wh.index(), wh.flags())
16 }
17}
18
19impl<T: ImmutableData> WireHeader<T> {
20 pub fn new(buff: T) -> Self {
22 Self { buff }
23 }
24
25 pub fn protocol_version(&self) -> u16 {
26 NetworkEndian::read_u16(&self.buff.as_ref()[offsets::PROTO_VERSION..])
27 }
28
29 pub fn application_id(&self) -> u16 {
30 NetworkEndian::read_u16(&self.buff.as_ref()[offsets::APPLICATION_ID..])
31 }
32
33 pub fn kind(&self) -> Kind {
34 let raw = NetworkEndian::read_u16(&self.buff.as_ref()[offsets::OBJECT_KIND..]);
35 Kind::from(raw)
36 }
37
38 pub fn flags(&self) -> Flags {
39 let raw = NetworkEndian::read_u16(&self.buff.as_ref()[offsets::FLAGS..]);
40 unsafe { Flags::from_bits_unchecked(raw) }
41 }
42
43 pub fn index(&self) -> u16 {
44 NetworkEndian::read_u16(&self.buff.as_ref()[offsets::INDEX..])
45 }
46
47 pub fn data_len(&self) -> usize {
48 NetworkEndian::read_u16(&self.buff.as_ref()[offsets::DATA_LEN..]) as usize
49 }
50
51 pub fn private_options_len(&self) -> usize {
52 NetworkEndian::read_u16(&self.buff.as_ref()[offsets::PRIVATE_OPTIONS_LEN..]) as usize
53 }
54
55 pub fn public_options_len(&self) -> usize {
56 NetworkEndian::read_u16(&self.buff.as_ref()[offsets::PUBLIC_OPTIONS_LEN..]) as usize
57 }
58}
59
60impl<T: MutableData> WireHeader<T> {
61 pub fn encode(&mut self, h: &Header) {
63 self.set_protocol_version(h.protocol_version());
64 self.set_application_id(h.application_id());
65 self.set_kind(h.kind());
66 self.set_flags(h.flags());
67 self.set_index(h.index());
68 }
69
70 pub fn set_protocol_version(&mut self, version: u16) {
72 NetworkEndian::write_u16(&mut self.buff.as_mut()[offsets::PROTO_VERSION..], version)
73 }
74
75 pub fn set_application_id(&mut self, application_id: u16) {
77 NetworkEndian::write_u16(
78 &mut self.buff.as_mut()[offsets::APPLICATION_ID..],
79 application_id,
80 )
81 }
82
83 pub fn set_flags(&mut self, flags: Flags) {
85 NetworkEndian::write_u16(&mut self.buff.as_mut()[offsets::FLAGS..], flags.bits())
86 }
87
88 pub fn set_kind(&mut self, kind: Kind) {
90 NetworkEndian::write_u16(&mut self.buff.as_mut()[offsets::OBJECT_KIND..], kind.into())
91 }
92
93 pub fn set_index(&mut self, index: u16) {
95 NetworkEndian::write_u16(&mut self.buff.as_mut()[offsets::INDEX..], index)
96 }
97
98 pub fn set_data_len(&mut self, data_len: usize) {
100 NetworkEndian::write_u16(
101 &mut self.buff.as_mut()[offsets::DATA_LEN..],
102 data_len as u16,
103 )
104 }
105
106 pub fn set_private_options_len(&mut self, private_options_len: usize) {
108 NetworkEndian::write_u16(
109 &mut self.buff.as_mut()[offsets::PRIVATE_OPTIONS_LEN..],
110 private_options_len as u16,
111 )
112 }
113
114 pub fn set_public_options_len(&mut self, public_options_len: usize) {
116 NetworkEndian::write_u16(
117 &mut self.buff.as_mut()[offsets::PUBLIC_OPTIONS_LEN..],
118 public_options_len as u16,
119 )
120 }
121}
122
123#[cfg(test)]
124mod tests {
125
126 use super::*;
127
128 use crate::base::header::{Header, HEADER_LEN};
129
130 use crate::types::PageKind;
131
132 #[test]
133 fn test_encode_wire_header() {
134 let h = Header::new(0, PageKind::Generic.into(), 1, Flags::SECONDARY);
136
137 let mut h1 = WireHeader::new([0u8; HEADER_LEN]);
139
140 h1.encode(&h);
142
143 let h2 = Header::from(&h1);
145
146 assert_eq!(h, h2);
148 }
149}