rtvm_primitives/bytecode/
eof.rs1mod body;
2mod decode_helpers;
3mod header;
4mod types_section;
5
6pub use body::EofBody;
7pub use header::EofHeader;
8pub use types_section::TypesSection;
9
10use crate::Bytes;
11use core::cmp::min;
12use std::{vec, vec::Vec};
13
14#[derive(Clone, Debug, PartialEq, Eq, Hash)]
22#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
23pub struct Eof {
24 pub header: EofHeader,
25 pub body: EofBody,
26 pub raw: Bytes,
27}
28
29impl Default for Eof {
30 fn default() -> Self {
31 let body = EofBody {
32 types_section: vec![TypesSection::default()],
34 code_section: vec![[0x00].into()],
36 container_section: vec![],
37 data_section: Bytes::new(),
38 is_data_filled: true,
39 };
40 body.into_eof()
41 }
42}
43
44impl Eof {
45 pub fn size(&self) -> usize {
47 self.header.size() + self.header.body_size()
48 }
49
50 pub fn raw(&self) -> &Bytes {
52 &self.raw
53 }
54
55 pub fn data_slice(&self, offset: usize, len: usize) -> &[u8] {
59 self.body
60 .data_section
61 .get(offset..)
62 .and_then(|bytes| bytes.get(..min(len, bytes.len())))
63 .unwrap_or(&[])
64 }
65
66 pub fn data(&self) -> &[u8] {
68 &self.body.data_section
69 }
70
71 pub fn encode_slow(&self) -> Bytes {
73 let mut buffer: Vec<u8> = Vec::with_capacity(self.size());
74 self.header.encode(&mut buffer);
75 self.body.encode(&mut buffer);
76 buffer.into()
77 }
78
79 pub fn decode(raw: Bytes) -> Result<Self, EofDecodeError> {
81 let (header, _) = EofHeader::decode(&raw)?;
82 let body = EofBody::decode(&raw, &header)?;
83 Ok(Self { header, body, raw })
84 }
85}
86
87#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
89pub enum EofDecodeError {
90 MissingInput,
92 MissingBodyWithoutData,
94 DanglingData,
96 InvalidTypesSection,
98 InvalidTypesSectionSize,
100 InvalidEOFMagicNumber,
102 InvalidEOFVersion,
104 InvalidTypesKind,
106 InvalidCodeKind,
108 InvalidTerminalByte,
110 InvalidDataKind,
112 InvalidKindAfterCode,
114 MismatchCodeAndTypesSize,
116 NonSizes,
118 ShortInputForSizes,
120 ZeroSize,
122 TooManyCodeSections,
124 ZeroCodeSections,
126 TooManyContainerSections,
128}
129
130#[cfg(test)]
131mod test {
132
133 use super::*;
134 use crate::bytes;
135
136 #[test]
137 fn decode_eof() {
138 let bytes = bytes!("ef000101000402000100010400000000800000fe");
139 let eof = Eof::decode(bytes.clone()).unwrap();
140 assert_eq!(bytes, eof.encode_slow());
141 }
142
143 #[test]
144 fn data_slice() {
145 let bytes = bytes!("ef000101000402000100010400000000800000fe");
146 let mut eof = Eof::decode(bytes.clone()).unwrap();
147 eof.body.data_section = bytes!("01020304");
148 assert_eq!(eof.data_slice(0, 1), &[0x01]);
149 assert_eq!(eof.data_slice(0, 4), &[0x01, 0x02, 0x03, 0x04]);
150 assert_eq!(eof.data_slice(0, 5), &[0x01, 0x02, 0x03, 0x04]);
151 assert_eq!(eof.data_slice(1, 2), &[0x02, 0x03]);
152 assert_eq!(eof.data_slice(10, 2), &[]);
153 assert_eq!(eof.data_slice(1, 0), &[]);
154 assert_eq!(eof.data_slice(10, 0), &[]);
155 }
156}