[−][src]Module scroll::ctx
Generic context-aware conversion traits, for automatic downstream extension of Pread, et. al
Discussion
Implementors of TryFromCtx automatically grant any client user of pread, pwrite, gread, gwrite the ability to parse their structure out of the source it has been implemented for, typically &[u8].
The implementor only needs to specify the error type, and the type of their size, and then implement the parsing/marshalling logic given a byte sequence, starting at the offset pread, et. al was called at, with the context you have implemented it for.
Returning the size allows dynamic content (e.g., &strs) to be parsed alongside fixed size content (e.g., u64). The parsing context is any information you the implementor need to correctly parse out your datatype - this could be the endianness of the type, more offsets, or other complex data. The only requirement is that your Ctx be Copy, and hence encourages lightweight contexts (but this isn't required of course).
Example
Suppose we have a datatype and we want to specify how to parse or serialize this datatype out of some arbitrary
byte buffer. In order to do this, we need to provide a TryFromCtx impl for our datatype. In particular, if we
do this for the [u8] target, with a "parsing contex", YourCtx, you will automatically get access to
calling pread_with::<YourDatatype>(offset, your_ctx) on arrays of bytes.
In the example below, we implement TryFromCtx using the Endian parsing context provided by scroll, which is used to specifying the endianness at which numbers should be parsed, but you could provide anything, as long as it implements Copy.
use scroll::{self, ctx, Endian, Pread, BE}; struct Data<'a> { name: &'a str, id: u32, } impl<'a> ctx::TryFromCtx<'a, Endian> for Data<'a> { type Error = scroll::Error; type Size = usize; fn try_from_ctx (src: &'a [u8], ctx: Endian) -> Result<(Self, Self::Size), Self::Error> { let name = src.pread::<&str>(0)?; let id = src.pread_with(name.len() + 1, ctx)?; Ok((Data { name: name, id: id }, name.len() + 1 + 4)) } } let bytes = b"UserName\x00\x01\x02\x03\x04"; let data = bytes.pread_with::<Data>(0, BE).unwrap(); assert_eq!(data.id, 0x01020304); assert_eq!(data.name.to_string(), "UserName".to_string());
Enums
| StrCtx | The parsing context for converting a byte sequence to a |
Constants
| NULL | A C-style, null terminator based delimiter |
| RET | A newline-based delimiter |
| SPACE | A space-based delimiter |
| TAB | A tab-based delimiter |
Traits
| FromCtx | Reads |
| IntoCtx | Writes |
| MeasureWith | A trait for measuring how large something is; for a byte sequence, it will be its length. |
| SizeWith | Gets the size of |
| TryFromCtx | Tries to read |
| TryIntoCtx | Tries to write |