feagi_data_serialization/
feagi_byte_container.rs1use byteorder::{ByteOrder, LittleEndian};
2use feagi_data_structures::FeagiDataError;
3use crate::feagi_serializable::FeagiSerializable;
4use crate::FeagiByteStructureType;
5
6type StructureIndex = usize;
7type ByteIndexReadingStart = usize;
8type NumberBytesToRead = usize;
9
10#[derive(Debug, Clone)]
32pub struct FeagiByteContainer {
33 bytes: Vec<u8>,
35 is_data_valid: bool,
37 contained_struct_references: Vec<ContainedStructReference>,
39}
40
41impl FeagiByteContainer{
42 pub const CURRENT_SUPPORTED_VERSION: u8 = 2;
43
44 pub const GLOBAL_BYTE_HEADER_BYTE_COUNT: usize = 4; pub const PER_STRUCT_HEADER_BYTE_COUNT: usize = 4; pub const STRUCT_HEADER_BYTE_COUNT: usize = 2; pub fn new_empty() -> Self {
67 Self { bytes: vec![Self::CURRENT_SUPPORTED_VERSION, 0, 0, 0], is_data_valid: true, contained_struct_references: Vec::new() }
68 }
69
70 pub fn get_byte_ref(&self) -> &[u8] {
89 &self.bytes
90 }
91
92 pub fn try_write_data_to_container_and_verify<F>(&mut self, byte_writer: &mut F) -> Result<(), FeagiDataError>
111 where F: FnMut(&mut Vec<u8>) -> Result<(), FeagiDataError> {
112 byte_writer(&mut self.bytes)?;
113 self.verify_container_valid_and_populate()
114 }
115
116 pub fn is_valid(&self) -> bool {
133 self.is_data_valid
134 }
135
136 pub fn try_get_number_contained_structures(&self) -> Result<usize, FeagiDataError> {
149 if self.is_data_valid {
150 return Ok(self.contained_struct_references.len())
151 }
152 Err(FeagiDataError::DeserializationError("Given Byte Container is invalid and thus cannot be read!".into()))
153 }
154
155 pub fn get_number_of_bytes_used(&self) -> usize {
167 self.bytes.len()
168 }
169
170 pub fn get_number_of_bytes_allocated(&self) -> usize {
182 self.bytes.capacity()
183 }
184
185 pub fn get_increment_counter(&self) -> Result<u16, FeagiDataError> {
198 if self.is_data_valid {
199 return Ok(LittleEndian::read_u16(&self.bytes[1..3]))
200 }
201 Err(FeagiDataError::DeserializationError("Given Byte Container is invalid and thus cannot be read!".into()))
202 }
203
204 pub fn try_create_new_struct_from_index(&self, index: StructureIndex) -> Result<Box<dyn FeagiSerializable>, FeagiDataError> {
222 self.verify_structure_index_valid(index)?;
223 let relevant_slice = self.contained_struct_references[index].get_as_byte_slice(&self.bytes);
224 let mut boxed_struct: Box<dyn FeagiSerializable> = self.contained_struct_references[index].structure_type.create_new_struct_of_type();
225 boxed_struct.try_update_from_byte_slice(relevant_slice)?;
226 Ok(boxed_struct)
227 }
228
229 pub fn try_create_struct_from_first_found_struct_of_type(&self, structure_type: FeagiByteStructureType) -> Result<Option<Box<dyn FeagiSerializable>>, FeagiDataError> {
230 let getting_slice = self.try_get_first_structure_slice_of_type(structure_type);
231 if getting_slice.is_none() {
232 return Ok(None);
233 }
234 let mut boxed_struct: Box<dyn FeagiSerializable> = structure_type.create_new_struct_of_type();
235 boxed_struct.try_update_from_byte_slice(getting_slice.unwrap())?;
236 Ok(Some(boxed_struct))
237 }
238
239 pub fn try_update_struct_from_index(&self, index: StructureIndex, updating_boxed_struct: &mut dyn FeagiSerializable) -> Result<(), FeagiDataError> {
240 self.verify_structure_index_valid(index)?;
241 let relevant_slice = self.contained_struct_references[index].get_as_byte_slice(&self.bytes);
242 updating_boxed_struct.verify_byte_slice_is_of_correct_type(relevant_slice)?;
243 updating_boxed_struct.try_update_from_byte_slice(relevant_slice)?;
244 Ok(())
245 }
246
247 pub fn try_update_struct_from_first_found_struct_of_type(&self, updating_boxed_struct: &mut dyn FeagiSerializable) -> Result<bool, FeagiDataError> {
248 let structure_type: FeagiByteStructureType = updating_boxed_struct.get_type();
249 let getting_slice = self.try_get_first_structure_slice_of_type(structure_type);
250 if getting_slice.is_none() {
251 return Ok(false);
252 }
253 updating_boxed_struct.try_update_from_byte_slice(getting_slice.unwrap())?;
254 Ok(true)
255 }
256
257 pub fn get_contained_struct_types(&self) -> Vec<FeagiByteStructureType> {
271 let mut output: Vec<FeagiByteStructureType> = Vec::with_capacity(self.contained_struct_references.len());
272 for contained_struct_reference in &self.contained_struct_references {
273 output.push(contained_struct_reference.structure_type);
274 };
275 output
276 }
277
278 pub fn overwrite_byte_data_with_multiple_struct_data(&mut self, incoming_structs: Vec<&dyn FeagiSerializable>, new_increment_value: u16) -> Result<(), FeagiDataError> {
283
284 self.bytes.clear();
285 self.contained_struct_references.clear();
286 self.is_data_valid = false;
287
288 let header_total_number_of_bytes: usize = Self::GLOBAL_BYTE_HEADER_BYTE_COUNT +
289 Self::PER_STRUCT_HEADER_BYTE_COUNT * incoming_structs.len();
290
291 let data_total_number_of_bytes = {
293 let mut data_start_index = header_total_number_of_bytes;
294 for incoming_struct in &incoming_structs {
295 let per_struct_number_bytes = incoming_struct.get_number_of_bytes_needed();
296 self.contained_struct_references.push(
297 ContainedStructReference{
298 structure_type: incoming_struct.get_type(),
299 byte_start_index: data_start_index,
300 number_bytes_to_read: per_struct_number_bytes,
301 }
302 );
303 data_start_index += per_struct_number_bytes;
304 }
305 data_start_index
306 };
307
308 if data_total_number_of_bytes > self.bytes.capacity() {
309 self.bytes.reserve(data_total_number_of_bytes - self.bytes.capacity());
310 }
311
312 unsafe {
314 self.bytes.set_len(data_total_number_of_bytes); }
316
317 self.bytes[0] = Self::CURRENT_SUPPORTED_VERSION;
319 LittleEndian::write_u16(&mut self.bytes[1..3], new_increment_value); self.bytes[3] = incoming_structs.len() as u8; let mut header_byte_index = Self::GLOBAL_BYTE_HEADER_BYTE_COUNT;
324 for struct_index in 0..incoming_structs.len() {
325 let incoming_struct = &incoming_structs[struct_index];
326 let contained_struct_reference = &self.contained_struct_references[struct_index];
327
328 LittleEndian::write_u32(&mut self.bytes[header_byte_index..header_byte_index + 4], contained_struct_reference.number_bytes_to_read as u32);
329 incoming_struct.try_write_to_byte_slice(contained_struct_reference.get_as_byte_slice_mut(&mut self.bytes))?;
330
331 header_byte_index += Self::PER_STRUCT_HEADER_BYTE_COUNT;
332 };
333
334 self.is_data_valid = true;
335 Ok(())
336
337 }
338
339 pub fn overwrite_byte_data_with_single_struct_data(&mut self, incoming_struct: &dyn FeagiSerializable, new_increment_value: u16) -> Result<(), FeagiDataError> {
340
341 self.bytes.clear();
342 self.contained_struct_references.clear();
343 self.is_data_valid = false;
344
345 let header_total_number_of_bytes: usize = Self::GLOBAL_BYTE_HEADER_BYTE_COUNT +
346 Self::PER_STRUCT_HEADER_BYTE_COUNT; let data_total_number_of_bytes = {
350 let data_start_index = header_total_number_of_bytes;
351 let per_struct_number_bytes = incoming_struct.get_number_of_bytes_needed();
352 self.contained_struct_references.push(
353 ContainedStructReference{
354 structure_type: incoming_struct.get_type(),
355 byte_start_index: data_start_index,
356 number_bytes_to_read: per_struct_number_bytes,
357 }
358 );
359 data_start_index + per_struct_number_bytes
360 };
361
362 if data_total_number_of_bytes > self.bytes.capacity() {
363 self.bytes.reserve(data_total_number_of_bytes - self.bytes.capacity());
364 }
365
366 unsafe {
368 self.bytes.set_len(data_total_number_of_bytes); }
370
371 self.bytes[0] = Self::CURRENT_SUPPORTED_VERSION;
373 LittleEndian::write_u16(&mut self.bytes[1..3], new_increment_value); self.bytes[3] = 1u8; let header_byte_index = Self::GLOBAL_BYTE_HEADER_BYTE_COUNT;
378 let contained_struct_reference = &self.contained_struct_references[0];
379
380 LittleEndian::write_u32(&mut self.bytes[header_byte_index..header_byte_index + 4], contained_struct_reference.number_bytes_to_read as u32);
381 incoming_struct.try_write_to_byte_slice(contained_struct_reference.get_as_byte_slice_mut(&mut self.bytes))?;
382
383 self.is_data_valid = true;
384 Ok(())
385
386 }
387
388 pub fn set_increment_counter_state(&mut self, new_increment_value: u16) -> Result<(), FeagiDataError> {
401 if !self.is_data_valid {
402 return Err(FeagiDataError::DeserializationError("Given Byte Container is invalid and thus cannot have its increment counter changed!".into()))
403 };
404 LittleEndian::write_u16(&mut self.bytes[1..3], new_increment_value);
405 Ok(())
406 }
407
408 pub fn free_unused_allocation(&mut self) {
422 self.bytes.shrink_to_fit()
423 }
424
425 fn verify_container_valid_and_populate(&mut self) -> Result<(), FeagiDataError> {
433 self.is_data_valid = false;
434 self.contained_struct_references.clear();
435 let byte_length = self.bytes.len();
436
437 if byte_length < Self::GLOBAL_BYTE_HEADER_BYTE_COUNT { return Err(FeagiDataError::DeserializationError("Given Feagi Byte Structure byte length is too short! (Less than 4!)".into()));
440 }
441 if self.bytes[0] != Self::CURRENT_SUPPORTED_VERSION {
442 return Err(FeagiDataError::DeserializationError(format!("Given FEAGI Byte Structure is using version {} when this application only supports version {}!", self.bytes[0], Self::CURRENT_SUPPORTED_VERSION)));
443 }
444 let number_contained_structs = LittleEndian::read_u16(&self.bytes[1..3]) as usize;
445 if number_contained_structs == 0 {
446 self.is_data_valid = true; return Ok(())
448 }
450
451 let minimum_count_header_size = Self::PER_STRUCT_HEADER_BYTE_COUNT * number_contained_structs;
452 let total_header_size = Self::GLOBAL_BYTE_HEADER_BYTE_COUNT + minimum_count_header_size;
453 if byte_length < total_header_size {
454 return Err(FeagiDataError::DeserializationError(format!("Feagi Byte Data specifies the existence of {} structures, but the given byte array is under the required {} byte length!", minimum_count_header_size, Self::GLOBAL_BYTE_HEADER_BYTE_COUNT + minimum_count_header_size)));
455 }
456
457 let mut structure_header_byte_index: usize = Self::GLOBAL_BYTE_HEADER_BYTE_COUNT;
458 let mut structure_data_byte_index: usize = total_header_size;
459 for contained_structure_index in 0..number_contained_structs {
460 let structure_length = LittleEndian::read_u32(&self.bytes[structure_header_byte_index..structure_header_byte_index + 4]);
461
462 if structure_data_byte_index + structure_length as usize > byte_length {
463 return Err(FeagiDataError::DeserializationError(
464 format!("Structure of index {} goes out of bound reaching position {} when given byte length is only {} long!", contained_structure_index, structure_data_byte_index + structure_length as usize, byte_length)));
465 }
466
467 let structure_type = FeagiByteStructureType::try_from(self.bytes[structure_data_byte_index])?;
468 self.contained_struct_references.push( ContainedStructReference {
469 structure_type,
470 byte_start_index: structure_data_byte_index,
471 number_bytes_to_read: structure_length as usize
472 });
473
474 structure_header_byte_index += 4; structure_data_byte_index += structure_length as usize;
476 }
477 Ok(())
478 }
479
480 fn verify_structure_index_valid(&self, structure_index: StructureIndex) -> Result<(), FeagiDataError> {
482 if structure_index >= self.contained_struct_references.len() {
483 return Err(FeagiDataError::BadParameters(format!("Structure index {} out of bounds! Feagi Byte Container only contains {} structures!", structure_index, self.contained_struct_references.len())));
484 }
485 Ok(())
486 }
487
488 fn try_get_first_structure_slice_of_type(&self, structure_type: FeagiByteStructureType) -> Option<&[u8]> {
490 for index in 0..self.contained_struct_references.len() {
491 if self.contained_struct_references[index].structure_type == structure_type {
492 return Some(self.contained_struct_references[index].get_as_byte_slice(&self.bytes));
493 }
494 };
495 None
496 }
497
498 }
501
502#[derive(Debug, Clone, Hash, PartialEq, Eq)]
506struct ContainedStructReference {
507 structure_type: FeagiByteStructureType,
508 byte_start_index: ByteIndexReadingStart,
509 number_bytes_to_read: NumberBytesToRead
510}
511
512impl ContainedStructReference {
513 pub fn get_as_byte_slice<'a>(&self, byte_source: &'a Vec<u8>) -> &'a [u8] {
514 &byte_source[self.byte_start_index ..self.byte_start_index + self.number_bytes_to_read]
515 }
516
517 pub fn get_as_byte_slice_mut<'a>(&self, byte_source: &'a mut Vec<u8>) -> &'a mut [u8] {
518 &mut byte_source[self.byte_start_index ..self.byte_start_index + self.number_bytes_to_read]
519 }
520}
521
522