use crate::buffer::ByteBuffer; use alloc::vec::Vec; use mammoth::zion::z_cap_t; use mammoth::zion::ZError; pub const MESSAGE_IDENT: u32 = 0x33441122; pub const MESSAGE_HEADER_SIZE: usize = 24; // 4x uint32, 1x uint64 const SENTINEL: u32 = 0xBEEFDEAD; const SERIALIZE_HEADER_SIZE: u32 = 0x10; pub fn field_offset(offset: usize, field_index: usize) -> usize { offset + MESSAGE_HEADER_SIZE + (8 * field_index) } pub fn parse_repeated( buf: &ByteBuffer, offset: usize, len: usize, ) -> Result, ZError> { let mut repeated = Vec::new(); for i in 0..len { repeated.push(buf.at::(offset + (i * size_of::()))?); } Ok(repeated) } pub fn parse_repeated_message( buf: &ByteBuffer, mut offset: usize, len: usize, caps: &Vec, ) -> Result, ZError> { let mut repeated = Vec::new(); for _ in 0..len { // FIXME: This is a bad way to get the length. let msg_len = buf.at::(offset + 8)? as usize; repeated.push(T::parse(buf, offset, caps)?); offset += msg_len; } Ok(repeated) } pub fn serialize_repeated( buf: &mut ByteBuffer, offset: usize, data: &Vec, ) -> Result { for i in 0..data.len() { buf.write_at(offset + (i * size_of::()), data[i])?; } Ok(offset + (data.len() * size_of::())) } pub fn serialize_repeated_message( buf: &mut ByteBuffer, mut offset: usize, data: &Vec, caps: &mut Vec, ) -> Result { for item in data { offset += item.serialize(buf, offset, caps)?; } Ok(offset) } pub fn serialize_error(buf: &mut ByteBuffer, err: ZError) { buf.write_at(0, SENTINEL) .expect("Failed to serialize SENTINEL"); buf.write_at(4, SERIALIZE_HEADER_SIZE) .expect("Failed to serialize size"); buf.write_at(8, err as u64) .expect("Failed to serialize error"); } pub trait YunqMessage { fn parse( buf: &ByteBuffer, offset: usize, caps: &Vec, ) -> Result where Self: Sized; fn parse_from_request( buf: &ByteBuffer, caps: &Vec, ) -> Result where Self: Sized, { if buf.at::(0)? != SENTINEL { return Err(ZError::INVALID_RESPONSE); } Ok(Self::parse(&buf, 16, &caps)?) } fn serialize( &self, buf: &mut ByteBuffer, offset: usize, caps: &mut Vec, ) -> Result; fn serialize_as_request( &self, request_id: u64, buf: &mut ByteBuffer, caps: &mut Vec, ) -> Result { buf.write_at(0, SENTINEL)?; buf.write_at(8, request_id as u64)?; let length = self.serialize(buf, 16, caps)?; buf.write_at(4, (16 + length) as u32)?; Ok(length + 16) } } pub struct Empty {} impl YunqMessage for Empty { fn parse( _buf: &ByteBuffer, _offset: usize, _caps: &Vec, ) -> Result where Self: Sized, { Ok(Self {}) } fn serialize( &self, _buf: &mut ByteBuffer, _offset: usize, _caps: &mut Vec, ) -> Result { Ok(0) } }