pub struct StreamParser<V: Version> { /* private fields */ }Expand description
Like Parser but for incremental parsing of streamed data. Useful when data is being
received over a network.
Unlike Parser, a StreamParser should only be used to parse a single replay stream at a
time.
§Example
use faf_replay_parser::{StreamParser, ReplayReadError, SCFA};
use std::io::Read;
use std::fs::File;
let mut file = File::open("tests/data/6176549.scfareplay").unwrap();
let mut stream = StreamParser::<SCFA>::new();
while stream.feed_reader(&mut file, 8192).unwrap() != 0 {
match stream.parse() {
Err(ReplayReadError::IO(_)) => continue,
res => res.expect("Replay file ok")
}
}
let replay = stream.finalize().unwrap();Implementations§
Source§impl<V: Version> StreamParser<V>
impl<V: Version> StreamParser<V>
Sourcepub fn new() -> StreamParser<V>
pub fn new() -> StreamParser<V>
Constructs a new StreamParser with default settings.
See ParserBuilder::commands_default.
Sourcepub fn with_options(options: ParserOptions<V>) -> StreamParser<V>
pub fn with_options(options: ParserOptions<V>) -> StreamParser<V>
Constructs a new StreamParser with given ParserOptions.
Sourcepub fn header(&self) -> Option<&ReplayHeader>
pub fn header(&self) -> Option<&ReplayHeader>
Returns a reference to the stored ReplayHeader.
Sourcepub fn body(&self) -> Option<&ReplayBody<V>>
pub fn body(&self) -> Option<&ReplayBody<V>>
Returns a reference to the stored ReplayBody.
Sourcepub fn feed(&mut self, data: &[u8])
pub fn feed(&mut self, data: &[u8])
Adds some replay data to the buffer from an existing slice.
If data is coming from a std::io::Read, then
feed_reader should be used instead to
avoid double allocation and double copying.
§Examples
use faf_replay_parser::{StreamParser, SCFA};
let mut stream = StreamParser::<SCFA>::new();
stream.feed(&[0u8; 10]);Sourcepub fn feed_reader(
&mut self,
reader: &mut impl Read,
max: usize,
) -> Result<usize>
pub fn feed_reader( &mut self, reader: &mut impl Read, max: usize, ) -> Result<usize>
Pulls data from a std::io::Read and adds it directly to the buffer. This will only make
one call to read reading up to max bytes. Calling this in a loop acts similar to a
std::io::BufReader with a buffer size of max. Setting max to a small number could
cause excessive calls to read.
§Returns
The number of bytes read.
§Examples
use faf_replay_parser::{StreamParser, SCFA};
use std::io::Cursor;
let mut stream = StreamParser::<SCFA>::new();
let mut reader = Cursor::new(vec![0u8; 10]);
assert_eq!(stream.feed_reader(&mut reader, 3).unwrap(), 3);
assert_eq!(stream.feed_reader(&mut reader, 10).unwrap(), 7);Sourcepub fn parse(&mut self) -> ReplayResult<()>
pub fn parse(&mut self) -> ReplayResult<()>
Parse as much of the data in the buffer as possible and advance the internal state. Calling
this function a second time without calling feed
or feed_reader will return an error.
§Errors
Returns a ReplayReadError::IO if there is not enough data available, and other variants
of ReplayReadError if the data stream is corrupt.
Sourcepub fn parse_header(&mut self) -> ReplayResult<()>
pub fn parse_header(&mut self) -> ReplayResult<()>
Parse a ReplayHeader from the buffer and advance the internal state. If Ok(()) is
returned, the header can be accessed by calling
header.
§Errors
Returns a ReplayReadError::IO if there is not enough data available, and other variants
of ReplayReadError if the data stream is corrupt.
Sourcepub fn parse_body(&mut self) -> ReplayResult<()>
pub fn parse_body(&mut self) -> ReplayResult<()>
Parse as many commands as possible from the buffer and add them to the internal
ReplayBody command stream. The ReplayBody can be accessed by calling
body.
§Errors
Returns a ReplayReadError::IO if there is not enough data available, and other variants
of ReplayReadError if the data stream is corrupt.
Sourcepub fn parse_body_with_callback(
&mut self,
callback: impl Fn(&mut SimData, &V::Command) -> ReplayResult<()>,
) -> ReplayResult<()>
pub fn parse_body_with_callback( &mut self, callback: impl Fn(&mut SimData, &V::Command) -> ReplayResult<()>, ) -> ReplayResult<()>
Like parse_body but applying a custom
processing function to each parsed command.
Sourcepub fn has_frame(&self) -> ReplayResult<bool>
pub fn has_frame(&self) -> ReplayResult<bool>
Checks if there is enough data available to parse an additional command from the replay body.
§Errors
If the command ID or the frame size are invalid, a ReplayReadError::Malformed is
returned.
§Examples
use faf_replay_parser::{StreamParser, SCFA};
let mut stream = StreamParser::<SCFA>::new();
assert!(!stream.has_frame().unwrap());
stream.feed(&[0, 3, 0]);
assert!(stream.has_frame().unwrap());
stream.reset();
stream.feed(&[100]); // Not a valid command id
stream.has_frame().unwrap_err();Sourcepub fn parse_command(&mut self) -> ReplayResult<Option<V::Command>>
pub fn parse_command(&mut self) -> ReplayResult<Option<V::Command>>
Parses a command from the buffer and consumes the read data. If the command type is not
present in the parser options then returns Ok(None).
It is recommended to call has_frame first to
ensure that enough data is available.
§Errors
If an error occurrs, it may be that the replay data is corrupted or there is not enough
data available to fully parse a command. In case of missing data, the error will always
be a ReplayReadError::IO and the inner error will be a std::io::Error with kind
std::io::ErrorKind::UnexpectedEof. Any other error likely means that the stream became
corrupted and that future calls to parse_command are unlikely to succeed.
§Examples
use faf_replay_parser::{StreamParser, SCFA};
use faf_replay_parser::scfa::ReplayCommand;
let mut stream = StreamParser::<SCFA>::new();
stream.feed(&[0x00, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00]);
assert_eq!(
stream.parse_command().unwrap(),
Some(ReplayCommand::Advance { ticks: 1 })
);Sourcepub fn parse_command_frame(&mut self) -> ReplayResult<ReplayCommandFrame<V>>
pub fn parse_command_frame(&mut self) -> ReplayResult<ReplayCommandFrame<V>>
Parses a command frame, but doesn’t parse the command data.
§Errors
Returns a ReplayReadError::IO if there is not enough data available, and other variants
of ReplayReadError if either the command id or the frame size are invalid.
Sourcepub fn can_finalize(&self) -> bool
pub fn can_finalize(&self) -> bool
Returns whether or not a call to finalize
will succeed.
Sourcepub fn finalize(&mut self) -> ReplayResult<StreamReplay<V>>
pub fn finalize(&mut self) -> ReplayResult<StreamReplay<V>>
Signals that the stream has ended and returns the parsed StreamReplay.
§Errors
Returns a ReplayReadError::IO if there is any unparsed data in the buffer.
Sourcepub fn force_finalize(&mut self) -> StreamReplay<V>
pub fn force_finalize(&mut self) -> StreamReplay<V>
Returns the currently parsed replay, and discards any excess data from the buffer.
Sourcepub fn reset(&mut self)
pub fn reset(&mut self)
Throws away all internal state. After resetting, self can be used to start parsing a new
data stream.
Note that this will not deallocate the internal buffer, so it is slightly more efficient to
reset and reuse a StreamParser than to create a new one.