mirror of
https://codeberg.org/demostf/parser.git
synced 2026-06-03 18:24:05 +02:00
writing string table packet
This commit is contained in:
parent
62026515d7
commit
208ab1240d
1 changed files with 175 additions and 2 deletions
|
|
@ -1,8 +1,9 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use bitbuffer::{BitRead, BitWrite, LittleEndian};
|
use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
|
||||||
|
|
||||||
use crate::demo::message::stringtable::StringTableMeta;
|
use crate::demo::message::stringtable::StringTableMeta;
|
||||||
|
use crate::demo::parser::Encode;
|
||||||
use crate::{Parse, ParseError, ParserState, ReadResult, Result, Stream};
|
use crate::{Parse, ParseError, ParserState, ReadResult, Result, Stream};
|
||||||
use std::borrow::{Borrow, Cow};
|
use std::borrow::{Borrow, Cow};
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
|
|
@ -62,6 +63,76 @@ impl<'a> BitRead<'a, LittleEndian> for StringTable<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BitWrite<LittleEndian> for StringTable<'_> {
|
||||||
|
fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
|
||||||
|
self.name.as_ref().write(stream)?;
|
||||||
|
(self.entries.len() as u16).write(stream)?;
|
||||||
|
for (_, entry) in self.entries.iter() {
|
||||||
|
entry.write(stream)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.client_entries.is_some().write(stream)?;
|
||||||
|
if let Some(client_entries) = self.client_entries.as_ref() {
|
||||||
|
(client_entries.len() as u16).write(stream)?;
|
||||||
|
client_entries.write(stream)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_string_table_roundtrip() {
|
||||||
|
crate::test_roundtrip_write(StringTable {
|
||||||
|
name: "foo".into(),
|
||||||
|
entries: vec![],
|
||||||
|
max_entries: 0,
|
||||||
|
fixed_user_data_size: None,
|
||||||
|
client_entries: None,
|
||||||
|
compressed: false,
|
||||||
|
});
|
||||||
|
crate::test_roundtrip_write(StringTable {
|
||||||
|
name: "foo".into(),
|
||||||
|
entries: vec![(
|
||||||
|
0,
|
||||||
|
StringTableEntry {
|
||||||
|
text: Some("bar".into()),
|
||||||
|
extra_data: None,
|
||||||
|
},
|
||||||
|
)],
|
||||||
|
max_entries: 1,
|
||||||
|
fixed_user_data_size: None,
|
||||||
|
client_entries: None,
|
||||||
|
compressed: false,
|
||||||
|
});
|
||||||
|
crate::test_roundtrip_write(StringTable {
|
||||||
|
name: "foo".into(),
|
||||||
|
entries: vec![
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
StringTableEntry {
|
||||||
|
text: Some("bar".into()),
|
||||||
|
extra_data: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
1,
|
||||||
|
StringTableEntry {
|
||||||
|
text: Some("asd".into()),
|
||||||
|
extra_data: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
max_entries: 2,
|
||||||
|
fixed_user_data_size: None,
|
||||||
|
client_entries: Some(vec![StringTableEntry {
|
||||||
|
text: Some("client".into()),
|
||||||
|
extra_data: None,
|
||||||
|
}]),
|
||||||
|
compressed: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(BitRead, BitWrite, Clone, Debug, PartialEq)]
|
#[derive(BitRead, BitWrite, Clone, Debug, PartialEq)]
|
||||||
#[endianness = "LittleEndian"]
|
#[endianness = "LittleEndian"]
|
||||||
pub struct ExtraData<'a> {
|
pub struct ExtraData<'a> {
|
||||||
|
|
@ -101,6 +172,17 @@ impl<'a> BitRead<'a, LittleEndian> for StringTableEntry<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BitWrite<LittleEndian> for StringTableEntry<'_> {
|
||||||
|
fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
|
||||||
|
self.text.as_deref().unwrap_or_default().write(stream)?;
|
||||||
|
self.extra_data.is_some().write(stream)?;
|
||||||
|
if let Some(extra_data) = self.extra_data.as_ref() {
|
||||||
|
extra_data.write(stream)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Debug for StringTableEntry<'_> {
|
impl fmt::Debug for StringTableEntry<'_> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match &self.extra_data {
|
match &self.extra_data {
|
||||||
|
|
@ -115,7 +197,7 @@ impl fmt::Debug for StringTableEntry<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct StringTablePacket<'a> {
|
pub struct StringTablePacket<'a> {
|
||||||
pub tick: u32,
|
pub tick: u32,
|
||||||
pub tables: Vec<StringTable<'a>>,
|
pub tables: Vec<StringTable<'a>>,
|
||||||
|
|
@ -136,3 +218,94 @@ impl<'a> Parse<'a> for StringTablePacket<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Encode for StringTablePacket<'_> {
|
||||||
|
fn encode(
|
||||||
|
&self,
|
||||||
|
stream: &mut BitWriteStream<LittleEndian>,
|
||||||
|
_state: &ParserState,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.tick.write(stream)?;
|
||||||
|
stream.reserve_byte_length(32, |stream| {
|
||||||
|
(self.tables.len() as u8).write(stream)?;
|
||||||
|
self.tables.write(stream)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_string_table_packet_roundtrip() {
|
||||||
|
let state = ParserState::new(|_| false, false);
|
||||||
|
crate::test_roundtrip_encode(
|
||||||
|
StringTablePacket {
|
||||||
|
tick: 1,
|
||||||
|
tables: vec![],
|
||||||
|
},
|
||||||
|
&state,
|
||||||
|
);
|
||||||
|
crate::test_roundtrip_encode(
|
||||||
|
StringTablePacket {
|
||||||
|
tick: 1,
|
||||||
|
tables: vec![StringTable {
|
||||||
|
name: "table1".into(),
|
||||||
|
entries: vec![],
|
||||||
|
max_entries: 0,
|
||||||
|
fixed_user_data_size: None,
|
||||||
|
client_entries: None,
|
||||||
|
compressed: false,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
&state,
|
||||||
|
);
|
||||||
|
crate::test_roundtrip_encode(
|
||||||
|
StringTablePacket {
|
||||||
|
tick: 1,
|
||||||
|
tables: vec![
|
||||||
|
StringTable {
|
||||||
|
name: "table1".into(),
|
||||||
|
entries: vec![(
|
||||||
|
0,
|
||||||
|
StringTableEntry {
|
||||||
|
text: Some("bar".into()),
|
||||||
|
extra_data: None,
|
||||||
|
},
|
||||||
|
)],
|
||||||
|
max_entries: 1,
|
||||||
|
fixed_user_data_size: None,
|
||||||
|
client_entries: None,
|
||||||
|
compressed: false,
|
||||||
|
},
|
||||||
|
StringTable {
|
||||||
|
name: "table2".into(),
|
||||||
|
entries: vec![
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
StringTableEntry {
|
||||||
|
text: Some("bar".into()),
|
||||||
|
extra_data: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
1,
|
||||||
|
StringTableEntry {
|
||||||
|
text: Some("asd".into()),
|
||||||
|
extra_data: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
max_entries: 2,
|
||||||
|
fixed_user_data_size: None,
|
||||||
|
client_entries: Some(vec![StringTableEntry {
|
||||||
|
text: Some("client".into()),
|
||||||
|
extra_data: None,
|
||||||
|
}]),
|
||||||
|
compressed: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
&state,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue