/rust/registry/src/index.crates.io-1949cf8c6b5b557f/scroll-0.10.2/src/greater.rs
Line | Count | Source |
1 | | use core::ops::{Index, IndexMut, RangeFrom}; |
2 | | |
3 | | use crate::ctx::{FromCtx, IntoCtx}; |
4 | | |
5 | | /// Core-read - core, no_std friendly trait for reading basic traits from byte buffers. Cannot fail |
6 | | /// unless the buffer is too small, in which case an assert fires and the program panics. |
7 | | /// |
8 | | /// If your type implements [FromCtx](ctx/trait.FromCtx.html) then you can `cread::<YourType>(offset)`. |
9 | | /// |
10 | | /// # Example |
11 | | /// |
12 | | /// ```rust |
13 | | /// use scroll::{ctx, Cread, LE}; |
14 | | /// |
15 | | /// #[repr(packed)] |
16 | | /// struct Bar { |
17 | | /// foo: i32, |
18 | | /// bar: u32, |
19 | | /// } |
20 | | /// |
21 | | /// impl ctx::FromCtx<scroll::Endian> for Bar { |
22 | | /// fn from_ctx(bytes: &[u8], ctx: scroll::Endian) -> Self { |
23 | | /// use scroll::Cread; |
24 | | /// Bar { foo: bytes.cread_with(0, ctx), bar: bytes.cread_with(4, ctx) } |
25 | | /// } |
26 | | /// } |
27 | | /// |
28 | | /// let bytes = [0xff, 0xff, 0xff, 0xff, 0xef,0xbe,0xad,0xde,]; |
29 | | /// let bar = bytes.cread_with::<Bar>(0, LE); |
30 | | /// // Remember that you need to copy out fields from packed structs |
31 | | /// // with a `{}` block instead of borrowing them directly |
32 | | /// // ref: https://github.com/rust-lang/rust/issues/46043 |
33 | | /// assert_eq!({bar.foo}, -1); |
34 | | /// assert_eq!({bar.bar}, 0xdeadbeef); |
35 | | /// ``` |
36 | | pub trait Cread<Ctx, I = usize> : Index<I> + Index<RangeFrom<I>> |
37 | | where |
38 | | Ctx: Copy, |
39 | | { |
40 | | /// Reads a value from `Self` at `offset` with `ctx`. Cannot fail. |
41 | | /// If the buffer is too small for the value requested, this will panic. |
42 | | /// |
43 | | /// # Example |
44 | | /// |
45 | | /// ```rust |
46 | | /// use scroll::{Cread, BE, LE}; |
47 | | /// use std::i64::MAX; |
48 | | /// |
49 | | /// let bytes = [0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xef,0xbe,0xad,0xde,]; |
50 | | /// let foo = bytes.cread_with::<i64>(0, BE); |
51 | | /// let bar = bytes.cread_with::<u32>(8, LE); |
52 | | /// assert_eq!(foo, MAX); |
53 | | /// assert_eq!(bar, 0xdeadbeef); |
54 | | /// ``` |
55 | | #[inline] |
56 | 0 | fn cread_with<N: FromCtx<Ctx, <Self as Index<RangeFrom<I>>>::Output>>(&self, offset: I, ctx: Ctx) -> N { |
57 | 0 | N::from_ctx(&self[offset..], ctx) |
58 | 0 | } |
59 | | /// Reads a value implementing `FromCtx` from `Self` at `offset`, |
60 | | /// with the **target machine**'s endianness. |
61 | | /// For the primitive types, this will be the **target machine**'s endianness. |
62 | | /// |
63 | | /// # Example |
64 | | /// |
65 | | /// ```rust |
66 | | /// use scroll::Cread; |
67 | | /// |
68 | | /// let bytes = [0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xef,0xbe,0x00,0x00,]; |
69 | | /// let foo = bytes.cread::<i64>(0); |
70 | | /// let bar = bytes.cread::<u32>(8); |
71 | | /// #[cfg(target_endian = "little")] |
72 | | /// assert_eq!(foo, 1); |
73 | | /// #[cfg(target_endian = "big")] |
74 | | /// assert_eq!(foo, 0x100_0000_0000_0000); |
75 | | /// |
76 | | /// #[cfg(target_endian = "little")] |
77 | | /// assert_eq!(bar, 0xbeef); |
78 | | /// #[cfg(target_endian = "big")] |
79 | | /// assert_eq!(bar, 0xefbe0000); |
80 | | /// ``` |
81 | | #[inline] |
82 | 0 | fn cread<N: FromCtx<Ctx, <Self as Index<RangeFrom<I>>>::Output>>(&self, offset: I) -> N where Ctx: Default { |
83 | 0 | let ctx = Ctx::default(); |
84 | 0 | N::from_ctx(&self[offset..], ctx) |
85 | 0 | } |
86 | | } |
87 | | |
88 | | impl<Ctx: Copy, I, R: ?Sized + Index<I> + Index<RangeFrom<I>>> Cread<Ctx, I> for R {} |
89 | | |
90 | | /// Core-write - core, no_std friendly trait for writing basic types into byte buffers. Cannot fail |
91 | | /// unless the buffer is too small, in which case an assert fires and the program panics. |
92 | | /// Similar to [Cread](trait.Cread.html), if your type implements [IntoCtx](ctx/trait.IntoCtx.html) |
93 | | /// then you can `cwrite(your_type, offset)`. |
94 | | /// |
95 | | /// # Example |
96 | | /// |
97 | | /// ```rust |
98 | | /// use scroll::{ctx, Cwrite}; |
99 | | /// |
100 | | /// #[repr(packed)] |
101 | | /// struct Bar { |
102 | | /// foo: i32, |
103 | | /// bar: u32, |
104 | | /// } |
105 | | /// |
106 | | /// impl ctx::IntoCtx<scroll::Endian> for Bar { |
107 | | /// fn into_ctx(self, bytes: &mut [u8], ctx: scroll::Endian) { |
108 | | /// use scroll::Cwrite; |
109 | | /// bytes.cwrite_with(self.foo, 0, ctx); |
110 | | /// bytes.cwrite_with(self.bar, 4, ctx); |
111 | | /// } |
112 | | /// } |
113 | | /// |
114 | | /// let bar = Bar { foo: -1, bar: 0xdeadbeef }; |
115 | | /// let mut bytes = [0x0; 16]; |
116 | | /// bytes.cwrite::<Bar>(bar, 0); |
117 | | /// ``` |
118 | | pub trait Cwrite<Ctx: Copy, I = usize>: Index<I> + IndexMut<RangeFrom<I>> { |
119 | | /// Writes `n` into `Self` at `offset`; uses default context. |
120 | | /// For the primitive types, this will be the **target machine**'s endianness. |
121 | | /// |
122 | | /// # Example |
123 | | /// |
124 | | /// ``` |
125 | | /// use scroll::{Cwrite, Cread}; |
126 | | /// let mut bytes = [0x0; 16]; |
127 | | /// bytes.cwrite::<i64>(42, 0); |
128 | | /// bytes.cwrite::<u32>(0xdeadbeef, 8); |
129 | | /// |
130 | | /// assert_eq!(bytes.cread::<i64>(0), 42); |
131 | | /// assert_eq!(bytes.cread::<u32>(8), 0xdeadbeef); |
132 | | #[inline] |
133 | 0 | fn cwrite<N: IntoCtx<Ctx, <Self as Index<RangeFrom<I>>>::Output>>(&mut self, n: N, offset: I) where Ctx: Default { |
134 | 0 | let ctx = Ctx::default(); |
135 | 0 | n.into_ctx(self.index_mut(offset..), ctx) |
136 | 0 | } |
137 | | /// Writes `n` into `Self` at `offset` with `ctx` |
138 | | /// |
139 | | /// # Example |
140 | | /// |
141 | | /// ``` |
142 | | /// use scroll::{Cwrite, Cread, LE, BE}; |
143 | | /// let mut bytes = [0x0; 0x10]; |
144 | | /// bytes.cwrite_with::<i64>(42, 0, LE); |
145 | | /// bytes.cwrite_with::<u32>(0xdeadbeef, 8, BE); |
146 | | /// assert_eq!(bytes.cread_with::<i64>(0, LE), 42); |
147 | | /// assert_eq!(bytes.cread_with::<u32>(8, LE), 0xefbeadde); |
148 | | #[inline] |
149 | 0 | fn cwrite_with<N: IntoCtx<Ctx, <Self as Index<RangeFrom<I>>>::Output>>(&mut self, n: N, offset: I, ctx: Ctx) { |
150 | 0 | n.into_ctx(self.index_mut(offset..), ctx) |
151 | 0 | } |
152 | | } |
153 | | |
154 | | impl<Ctx: Copy, I, W: ?Sized + Index<I> + IndexMut<RangeFrom<I>>> Cwrite<Ctx, I> for W {} |