rtvm_primitives/bytecode/eof/
body.rs1use super::{Eof, EofDecodeError, EofHeader, TypesSection};
2use crate::Bytes;
3use std::vec::Vec;
4
5#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10pub struct EofBody {
11 pub types_section: Vec<TypesSection>,
12 pub code_section: Vec<Bytes>,
13 pub container_section: Vec<Bytes>,
14 pub data_section: Bytes,
15 pub is_data_filled: bool,
16}
17
18impl EofBody {
19 pub fn code(&self, index: usize) -> Option<&Bytes> {
21 self.code_section.get(index)
22 }
23
24 pub fn into_eof(self) -> Eof {
26 let header = EofHeader {
28 types_size: self.types_section.len() as u16 * 4,
29 code_sizes: self.code_section.iter().map(|x| x.len() as u16).collect(),
30 container_sizes: self
31 .container_section
32 .iter()
33 .map(|x| x.len() as u16)
34 .collect(),
35 data_size: self.data_section.len() as u16,
36 sum_code_sizes: self.code_section.iter().map(|x| x.len()).sum(),
37 sum_container_sizes: self.container_section.iter().map(|x| x.len()).sum(),
38 };
39 let mut buffer = Vec::new();
40 header.encode(&mut buffer);
41 self.encode(&mut buffer);
42 Eof {
43 header,
44 body: self,
45 raw: buffer.into(),
46 }
47 }
48
49 pub fn encode(&self, buffer: &mut Vec<u8>) {
51 for types_section in &self.types_section {
52 types_section.encode(buffer);
53 }
54
55 for code_section in &self.code_section {
56 buffer.extend_from_slice(code_section);
57 }
58
59 for container_section in &self.container_section {
60 buffer.extend_from_slice(container_section);
61 }
62
63 buffer.extend_from_slice(&self.data_section);
64 }
65
66 pub fn decode(input: &Bytes, header: &EofHeader) -> Result<Self, EofDecodeError> {
68 let header_len = header.size();
69 let partial_body_len =
70 header.sum_code_sizes + header.sum_container_sizes + header.types_size as usize;
71 let full_body_len = partial_body_len + header.data_size as usize;
72
73 if input.len() < header_len + partial_body_len {
74 return Err(EofDecodeError::MissingBodyWithoutData);
75 }
76
77 if input.len() > header_len + full_body_len {
78 return Err(EofDecodeError::DanglingData);
79 }
80
81 let mut body = EofBody::default();
82
83 let mut types_input = &input[header_len..];
84 for _ in 0..header.types_count() {
85 let (types_section, local_input) = TypesSection::decode(types_input)?;
86 types_input = local_input;
87 body.types_section.push(types_section);
88 }
89
90 let mut start = header_len + header.types_size as usize;
92 for size in header.code_sizes.iter().map(|x| *x as usize) {
93 body.code_section.push(input.slice(start..start + size));
94 start += size;
95 }
96
97 for size in header.container_sizes.iter().map(|x| *x as usize) {
99 body.container_section
100 .push(input.slice(start..start + size));
101 start += size;
102 }
103
104 body.data_section = input.slice(start..);
105 body.is_data_filled = body.data_section.len() == header.data_size as usize;
106
107 Ok(body)
108 }
109}