mirror of
https://github.com/mbilker/kbinxml-rs.git
synced 2026-09-08 10:35:32 -05:00
ser(tuple): check types of sub-elements to only permit single sub-type tuples
This commit is contained in:
@@ -12,7 +12,7 @@ pub struct Tuple<'a> {
|
||||
ser: &'a mut Serializer,
|
||||
|
||||
size_index: u64,
|
||||
node_type: StandardType,
|
||||
node_type: Option<StandardType>,
|
||||
len: usize,
|
||||
}
|
||||
|
||||
@@ -22,23 +22,21 @@ impl<'a> Tuple<'a> {
|
||||
|
||||
ser.write_mode = WriteMode::Array;
|
||||
|
||||
let size_index = ser.data_buf.position();
|
||||
|
||||
// Estimate u32 for the total size of the tuple
|
||||
debug!("big endian length: {:02x?}", u32::to_bytes(u32::to_be(len as u32)));
|
||||
let size_index = ser.data_buf.position();
|
||||
ser.data_buf.write_u32::<BigEndian>(len as u32).expect("Unable to write size placeholder");
|
||||
|
||||
Self {
|
||||
ser,
|
||||
size_index,
|
||||
node_type: StandardType::String,
|
||||
node_type: None,
|
||||
len,
|
||||
}
|
||||
}
|
||||
|
||||
fn find_standard_type(&self) -> StandardType {
|
||||
debug!("find_standard_type => len: {}", self.len);
|
||||
self.node_type
|
||||
self.node_type.unwrap_or(StandardType::String)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +51,15 @@ impl<'a> SerializeTuple for Tuple<'a> {
|
||||
let hint = value.serialize(&mut *self.ser)?.ok_or(KbinErrorKind::MissingTypeHint)?;
|
||||
debug!("SerializeTuple: serialize_element, hint: {:?}", hint);
|
||||
|
||||
self.node_type = hint.node_type;
|
||||
// Rust tuple types can have different types per element, this is not
|
||||
// permitted by kbin
|
||||
if let Some(node_type) = self.node_type {
|
||||
if node_type != hint.node_type {
|
||||
return Err(KbinErrorKind::TypeMismatch(*node_type, *hint.node_type).into());
|
||||
}
|
||||
} else {
|
||||
self.node_type = Some(hint.node_type);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -71,15 +77,12 @@ impl<'a> SerializeTuple for Tuple<'a> {
|
||||
if size as usize != self.len {
|
||||
debug!("SerializeTuple: end, size correction: {}", size);
|
||||
|
||||
let old_pos = self.ser.data_buf.position();
|
||||
let current_pos = self.ser.data_buf.position();
|
||||
self.ser.data_buf.seek(SeekFrom::Start(self.size_index)).context(KbinErrorKind::Seek)?;
|
||||
self.ser.data_buf.write_u32::<BigEndian>(size).context(KbinErrorKind::DataWrite("node size"))?;
|
||||
self.ser.data_buf.seek(SeekFrom::Start(old_pos)).context(KbinErrorKind::Seek)?;
|
||||
self.ser.data_buf.seek(SeekFrom::Start(current_pos)).context(KbinErrorKind::Seek)?;
|
||||
}
|
||||
|
||||
// Taken care of by `SerializerStruct`
|
||||
//self.ser.node_buf.write_u8(StandardType::NodeEnd.id | ARRAY_MASK).context(KbinErrorKind::DataWrite("node end"))?;
|
||||
|
||||
Ok(Some(TypeHint { node_type, is_array: true, count: self.len }))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user