StreamParser

Struct StreamParser 

Source
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>

Source

pub fn new() -> StreamParser<V>

Constructs a new StreamParser with default settings. See ParserBuilder::commands_default.

Source

pub fn with_options(options: ParserOptions<V>) -> StreamParser<V>

Constructs a new StreamParser with given ParserOptions.

Source

pub fn header(&self) -> Option<&ReplayHeader>

Returns a reference to the stored ReplayHeader.

Source

pub fn body(&self) -> Option<&ReplayBody<V>>

Returns a reference to the stored ReplayBody.

Source

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]);
Source

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);
Source

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.

Source

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.

Source

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.

Source

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.

Source

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();
Source

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 })
);
Source

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.

Source

pub fn can_finalize(&self) -> bool

Returns whether or not a call to finalize will succeed.

Source

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.

Source

pub fn force_finalize(&mut self) -> StreamReplay<V>

Returns the currently parsed replay, and discards any excess data from the buffer.

Source

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.

Trait Implementations§

Source§

impl<V: Debug + Version> Debug for StreamParser<V>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<V> Freeze for StreamParser<V>

§

impl<V> RefUnwindSafe for StreamParser<V>

§

impl<V> Send for StreamParser<V>
where <V as Version>::Command: Send, <V as Version>::CommandId: Send,

§

impl<V> Sync for StreamParser<V>
where <V as Version>::Command: Sync, <V as Version>::CommandId: Sync,

§

impl<V> Unpin for StreamParser<V>
where <V as Version>::Command: Unpin, <V as Version>::CommandId: Unpin,

§

impl<V> UnwindSafe for StreamParser<V>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.