1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
use core::result; use core::fmt::Debug; use ctx::{TryIntoCtx}; use error; use endian::Endian; /// Writes into `Self` at an offset of type `I` using a `Ctx` /// /// To implement writing into an arbitrary byte buffer, implement `TryIntoCtx` /// # Example /// ```rust /// use scroll::{self, ctx}; /// #[derive(Debug, PartialEq, Eq)] /// pub struct Foo(u16); /// /// // this will use the default `DefaultCtx = scroll::Endian` and `I = usize`... /// impl ctx::TryIntoCtx for Foo { /// // you can use your own error here too, but you will then need to specify it in fn generic parameters /// type Error = scroll::Error; /// // you can write using your own context too... see `leb128.rs` /// fn try_into_ctx(self, this: &mut [u8], ctx: (usize, scroll::ctx::DefaultCtx)) -> Result<(), Self::Error> { /// use scroll::Pwrite; /// let offset = ctx.0; /// let le = ctx.1; /// if offset > 2 { return Err((scroll::Error::Custom("whatever".to_string())).into()) } /// this.pwrite_with(self.0, offset, le)?; /// Ok(()) /// } /// } /// // now we can write a `Foo` into some buffer (in this case, a byte buffer, because that's what we implemented it for above) /// use scroll::Pwrite; /// let mut bytes: [u8; 4] = [0, 0, 0, 0]; /// bytes.pwrite_with(Foo(0x7f), 1, scroll::LE).unwrap(); /// pub trait Pwrite<Ctx = Endian, E = error::Error, I = usize, TryCtx = (I, Ctx), SliceCtx = (I, I, Ctx) > where E: Debug, Ctx: Copy + Default + Debug, I: Copy + Debug, TryCtx: Copy + Default + Debug, SliceCtx: Copy + Default + Debug, { fn pwrite_unsafe<N: TryIntoCtx<TryCtx, Error = E>>(&mut self, n: N, offset: I, ctx: Ctx) { self.pwrite_with(n, offset, ctx).unwrap() } fn pwrite<N: TryIntoCtx<TryCtx, Error = E>>(&mut self, n: N, offset: I) -> result::Result<(), E> { self.pwrite_with(n, offset, Ctx::default()) } /// Write `N` at offset `I` with context `Ctx` /// # Example /// ``` /// use scroll::{Buffer, Pwrite, Pread, LE}; /// let mut bytes: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; /// bytes.pwrite_with::<u32>(0xbeefbeef, 0, LE).unwrap(); /// assert_eq!(bytes.pread_with::<u32>(0, LE).unwrap(), 0xbeefbeef); fn pwrite_with<N: TryIntoCtx<TryCtx, Error = E>>(&mut self, n: N, offset: I, ctx: Ctx) -> result::Result<(), E>; //fn pwrite_slice<N: ?Sized + TrySliceFromCtx<SliceCtx, Error = E>>(&self, offset: I, count: I) -> result::Result<&N, E>; } impl<Ctx, E> Pwrite<Ctx, E> for [u8] where E: Debug, Ctx: Copy + Default + Debug { // fn pwrite_unsafe<N: IntoCtx>(&mut self, n: N, offset: usize, le: bool) { // n.into_ctx(&mut self[offset..], le); // } fn pwrite_with<N: TryIntoCtx<(usize, Ctx), Error = E>>(&mut self, n: N, offset: usize, le: Ctx) -> result::Result<(), E> { n.try_into_ctx(self, (offset, le)) } } impl<T, Ctx, E> Pwrite<Ctx, E> for T where T: AsMut<[u8]>, E: Debug, Ctx: Copy + Debug + Default, { fn pwrite_with<N: TryIntoCtx<(usize, Ctx), Error = E>>(&mut self, n: N, offset: usize, ctx: Ctx) -> result::Result<(), E> { <[u8] as Pwrite<Ctx, E>>::pwrite_with(self.as_mut(), n, offset, ctx) } }