open_dis_rust/synthetic_environment/
gridded_data_pdu.rs1use bytes::{Buf, BufMut, BytesMut};
8use std::any::Any;
9
10use crate::common::{
11 dis_error::DISError,
12 entity_id::EntityId,
13 entity_type::EntityType,
14 enums::{GriddedDataConstantGrid, GriddedDataCoordinateSystem},
15 euler_angles::EulerAngles,
16 pdu::Pdu,
17 pdu_header::{PduHeader, PduType, ProtocolFamily},
18};
19
20use super::data_types::{
21 grid_axis_descriptor::GridAxisDescriptor, grid_data_record::GridDataRecord,
22};
23
24#[derive(Clone, Debug)]
25pub struct GriddedDataPdu {
27 pub pdu_header: PduHeader,
28 pub environmental_simulation_id: EntityId,
29 pub field_number: u16,
30 pub pdu_number: u16,
31 pub pdu_total: u16,
32 pub coordinate_system: GriddedDataCoordinateSystem,
33 pub number_of_grid_axes: u8,
34 pub constant_grid: GriddedDataConstantGrid,
35 pub environment_type: EntityType,
36 pub orientation: EulerAngles,
37 pub sample_time: u64,
38 pub total_values: u32,
39 pub vector_dimension: u8,
40 pub padding1: u8,
41 pub padding2: u16,
42 pub grid_axis_descriptors: Vec<GridAxisDescriptor>,
43 pub grid_data_list: Vec<GridDataRecord>,
44}
45
46impl Default for GriddedDataPdu {
47 fn default() -> Self {
58 GriddedDataPdu {
59 pdu_header: PduHeader::default(
60 PduType::GriddedData,
61 ProtocolFamily::SyntheticEnvironment,
62 112,
63 ),
64 environmental_simulation_id: EntityId::default(0),
65 field_number: 0,
66 pdu_number: 0,
67 pdu_total: 0,
68 coordinate_system: GriddedDataCoordinateSystem::default(),
69 number_of_grid_axes: 0,
70 constant_grid: GriddedDataConstantGrid::default(),
71 environment_type: EntityType::default(),
72 orientation: EulerAngles::default(),
73 sample_time: 0,
74 total_values: 0,
75 vector_dimension: 0,
76 padding1: 0,
77 padding2: 0,
78 grid_axis_descriptors: vec![],
79 grid_data_list: vec![],
80 }
81 }
82}
83
84impl Pdu for GriddedDataPdu {
85 fn serialize(&mut self, buf: &mut BytesMut) {
86 self.pdu_header.length = u16::try_from(std::mem::size_of_val(self))
87 .expect("The length of the PDU should fit in a u16.");
88 self.pdu_header.serialize(buf);
89 self.environmental_simulation_id.serialize(buf);
90 buf.put_u16(self.field_number);
91 buf.put_u16(self.pdu_number);
92 buf.put_u16(self.pdu_total);
93 buf.put_u16(self.coordinate_system as u16);
94 buf.put_u8(self.number_of_grid_axes);
95 buf.put_u8(self.constant_grid as u8);
96 self.environment_type.serialize(buf);
97 self.orientation.serialize(buf);
98 buf.put_u64(self.sample_time);
99 buf.put_u32(self.total_values);
100 buf.put_u8(self.vector_dimension);
101 buf.put_u8(self.padding1);
102 buf.put_u16(self.padding2);
103 for i in 0..self.grid_axis_descriptors.len() {
104 self.grid_axis_descriptors[i].serialize(buf);
105 }
106 for i in 0..self.grid_data_list.len() {
107 self.grid_data_list[i].serialize(buf);
108 }
109 }
110
111 fn deserialize(mut buffer: BytesMut) -> Result<Self, DISError>
112 where
113 Self: Sized,
114 {
115 let pdu_header = PduHeader::deserialize(&mut buffer);
116 if pdu_header.pdu_type == PduType::GriddedData {
117 let environmental_simulation_id = EntityId::deserialize(&mut buffer);
118 let field_number = buffer.get_u16();
119 let pdu_number = buffer.get_u16();
120 let pdu_total = buffer.get_u16();
121 let coordinate_system = GriddedDataCoordinateSystem::deserialize(&mut buffer);
122 let number_of_grid_axes = buffer.get_u8();
123 let constant_grid = GriddedDataConstantGrid::deserialize(&mut buffer);
124 let environment_type = EntityType::deserialize(&mut buffer);
125 let orientation = EulerAngles::deserialize(&mut buffer);
126 let sample_time = buffer.get_u64();
127 let total_values = buffer.get_u32();
128 let vector_dimension = buffer.get_u8();
129 let padding1 = buffer.get_u8();
130 let padding2 = buffer.get_u16();
131 let mut grid_axis_descriptors: Vec<GridAxisDescriptor> = vec![];
132 for _ in 0..number_of_grid_axes {
133 grid_axis_descriptors.push(GridAxisDescriptor::deserialize(&mut buffer));
134 }
135 let mut grid_data_list: Vec<GridDataRecord> = vec![];
136 while buffer.has_remaining() {
137 grid_data_list.push(GridDataRecord::deserialize(&mut buffer));
138 }
139
140 Ok(GriddedDataPdu {
141 pdu_header,
142 environmental_simulation_id,
143 field_number,
144 pdu_number,
145 pdu_total,
146 coordinate_system,
147 number_of_grid_axes,
148 constant_grid,
149 environment_type,
150 orientation,
151 sample_time,
152 total_values,
153 vector_dimension,
154 padding1,
155 padding2,
156 grid_axis_descriptors,
157 grid_data_list,
158 })
159 } else {
160 Err(DISError::invalid_header(
161 format!(
162 "Expected PDU type GriddedData, got {:?}",
163 pdu_header.pdu_type
164 ),
165 None,
166 ))
167 }
168 }
169
170 fn as_any(&self) -> &dyn Any {
171 self
172 }
173
174 fn deserialize_without_header(
175 mut buffer: BytesMut,
176 pdu_header: PduHeader,
177 ) -> Result<Self, DISError>
178 where
179 Self: Sized,
180 {
181 let environmental_simulation_id = EntityId::deserialize(&mut buffer);
182 let field_number = buffer.get_u16();
183 let pdu_number = buffer.get_u16();
184 let pdu_total = buffer.get_u16();
185 let coordinate_system = GriddedDataCoordinateSystem::deserialize(&mut buffer);
186 let number_of_grid_axes = buffer.get_u8();
187 let constant_grid = GriddedDataConstantGrid::deserialize(&mut buffer);
188 let environment_type = EntityType::deserialize(&mut buffer);
189 let orientation = EulerAngles::deserialize(&mut buffer);
190 let sample_time = buffer.get_u64();
191 let total_values = buffer.get_u32();
192 let vector_dimension = buffer.get_u8();
193 let padding1 = buffer.get_u8();
194 let padding2 = buffer.get_u16();
195 let mut grid_axis_descriptors: Vec<GridAxisDescriptor> = vec![];
196 for _ in 0..number_of_grid_axes {
197 grid_axis_descriptors.push(GridAxisDescriptor::deserialize(&mut buffer));
198 }
199 let mut grid_data_list: Vec<GridDataRecord> = vec![];
200 while buffer.has_remaining() {
201 grid_data_list.push(GridDataRecord::deserialize(&mut buffer));
202 }
203 Ok(GriddedDataPdu {
204 pdu_header,
205 environmental_simulation_id,
206 field_number,
207 pdu_number,
208 pdu_total,
209 coordinate_system,
210 number_of_grid_axes,
211 constant_grid,
212 environment_type,
213 orientation,
214 sample_time,
215 total_values,
216 vector_dimension,
217 padding1,
218 padding2,
219 grid_axis_descriptors,
220 grid_data_list,
221 })
222 }
223}
224
225#[cfg(test)]
226mod tests {
227 use super::GriddedDataPdu;
228 use crate::common::{
229 pdu::Pdu,
230 pdu_header::{PduHeader, PduType, ProtocolFamily},
231 };
232 use bytes::BytesMut;
233
234 #[test]
235 fn create_header() {
236 let gridded_data_pdu = GriddedDataPdu::default();
237 let pdu_header = PduHeader::default(
238 PduType::GriddedData,
239 ProtocolFamily::SyntheticEnvironment,
240 112,
241 );
242
243 assert_eq!(
244 pdu_header.protocol_version,
245 gridded_data_pdu.pdu_header.protocol_version
246 );
247 assert_eq!(
248 pdu_header.exercise_id,
249 gridded_data_pdu.pdu_header.exercise_id
250 );
251 assert_eq!(pdu_header.pdu_type, gridded_data_pdu.pdu_header.pdu_type);
252 assert_eq!(
253 pdu_header.protocol_family,
254 gridded_data_pdu.pdu_header.protocol_family
255 );
256 assert_eq!(pdu_header.length, gridded_data_pdu.pdu_header.length);
257 assert_eq!(
258 pdu_header.status_record,
259 gridded_data_pdu.pdu_header.status_record
260 );
261 }
262
263 #[test]
264 fn deserialize_header() {
265 let mut gridded_data_pdu = GriddedDataPdu::default();
266 let mut buffer = BytesMut::new();
267 gridded_data_pdu.serialize(&mut buffer);
268
269 let new_gridded_data_pdu = GriddedDataPdu::deserialize(buffer).unwrap();
270 assert_eq!(new_gridded_data_pdu.pdu_header, gridded_data_pdu.pdu_header);
271 }
272
273 #[test]
274 fn check_pdu_size() {
275 let gridded_data_pdu = GriddedDataPdu::default();
276
277 assert_eq!(
278 gridded_data_pdu.pdu_header.length,
279 gridded_data_pdu.pdu_header.length
280 );
281 }
282}