rmpv/decode/
value_ref.rs

1use std;
2use std::io::{self, Cursor, ErrorKind, Read};
3use std::str;
4
5use rmp::decode::{read_marker, RmpRead};
6use rmp::Marker;
7
8use super::Error;
9use crate::{Utf8StringRef, ValueRef};
10
11fn read_str_data<'a, R>(rd: &mut R, len: usize, depth: u16) -> Result<Utf8StringRef<'a>, Error>
12    where R: BorrowRead<'a>
13{
14    let depth = super::decrement_depth(depth)?;
15    let buf = read_bin_data(rd, len, depth)?;
16    match str::from_utf8(buf) {
17        Ok(s) => Ok(Utf8StringRef::from(s)),
18        Err(err) => {
19            let s = Utf8StringRef {
20                s: Err((buf, err)),
21            };
22            Ok(s)
23        }
24    }
25}
26
27fn read_bin_data<'a, R>(rd: &mut R, len: usize, depth: u16) -> Result<&'a [u8], Error>
28    where R: BorrowRead<'a>
29{
30    let _depth = super::decrement_depth(depth)?;
31    let buf = rd.fill_buf();
32
33    if len > buf.len() {
34        return Err(Error::InvalidDataRead(io::Error::new(ErrorKind::UnexpectedEof, "unexpected EOF")));
35    }
36
37    // Take a slice.
38    let buf = &buf[..len];
39    rd.consume(len);
40
41    Ok(buf)
42}
43
44fn read_ext_body<'a, R>(rd: &mut R, len: usize, depth: u16) -> Result<(i8, &'a [u8]), Error>
45    where R: BorrowRead<'a>
46{
47    let depth = super::decrement_depth(depth)?;
48    let ty = rd.read_data_i8()?;
49    let buf = read_bin_data(rd, len, depth)?;
50
51    Ok((ty, buf))
52}
53
54fn read_array_data<'a, R>(rd: &mut R, mut len: usize, depth: u16) -> Result<Vec<ValueRef<'a>>, Error>
55    where R: BorrowRead<'a>
56{
57    let depth = super::decrement_depth(depth)?;
58    // Note: Do not preallocate a Vec of size `len`.
59    // See https://github.com/3Hren/msgpack-rust/issues/151
60    let mut vec = Vec::new();
61
62    while len > 0 {
63        vec.push(read_value_ref_inner(rd, depth)?);
64        len -= 1;
65    }
66
67    Ok(vec)
68}
69
70fn read_map_data<'a, R>(rd: &mut R, mut len: usize, depth: u16) -> Result<Vec<(ValueRef<'a>, ValueRef<'a>)>, Error>
71    where R: BorrowRead<'a>
72{
73    let depth = super::decrement_depth(depth)?;
74    // Note: Do not preallocate a Vec of size `len`.
75    // See https://github.com/3Hren/msgpack-rust/issues/151
76    let mut vec = Vec::new();
77
78    while len > 0 {
79        vec.push((read_value_ref_inner(rd, depth)?, read_value_ref_inner(rd, depth)?));
80        len -= 1;
81    }
82
83    Ok(vec)
84}
85
86/// A `BorrowRead` is a type of Reader which has an internal buffer.
87///
88/// This magic trait acts like a standard `BufRead` but unlike the standard this has an explicit
89/// internal buffer lifetime, which allows to borrow from underlying buffer while consuming bytes.
90pub trait BorrowRead<'a>: Read {
91    /// Returns the buffer contents.
92    ///
93    /// This function is a lower-level call. It needs to be paired with the consume method to
94    /// function properly. When calling this method, none of the contents will be "read" in the
95    /// sense that later calling read may return the same contents. As such, consume must be called
96    /// with the number of bytes that are consumed from this buffer to ensure that the bytes are
97    /// never returned twice.
98    ///
99    /// An empty buffer returned indicates that the stream has reached EOF.
100    fn fill_buf(&self) -> &'a [u8];
101
102    /// Tells this buffer that len bytes have been consumed from the buffer, so they should no
103    /// longer be returned in calls to read.
104    fn consume(&mut self, len: usize);
105}
106
107impl<'a> BorrowRead<'a> for &'a [u8] {
108    fn fill_buf(&self) -> &'a [u8] {
109        self
110    }
111
112    fn consume(&mut self, len: usize) {
113        *self = &(*self)[len..];
114    }
115}
116
117/// Useful when you want to know how much bytes has been consumed during `ValueRef` decoding.
118impl<'a> BorrowRead<'a> for Cursor<&'a [u8]> {
119    fn fill_buf(&self) -> &'a [u8] {
120        let len = std::cmp::min(self.position(), self.get_ref().len() as u64);
121        &self.get_ref()[len as usize..]
122    }
123
124    fn consume(&mut self, len: usize) {
125        let pos = self.position();
126        self.set_position(pos + len as u64);
127    }
128}
129
130fn read_value_ref_inner<'a, R>(rd: &mut R, depth: u16) -> Result<ValueRef<'a>, Error>
131    where R: BorrowRead<'a>
132{
133    let depth = super::decrement_depth(depth)?;
134
135    // Reading the marker involves either 1 byte read or nothing. On success consumes strictly
136    // 1 byte from the `rd`.
137    let val = match read_marker(rd)? {
138        Marker::Null => ValueRef::Nil,
139        Marker::True => ValueRef::Boolean(true),
140        Marker::False => ValueRef::Boolean(false),
141        Marker::FixPos(val) => ValueRef::from(val),
142        Marker::FixNeg(val) => ValueRef::from(val),
143        Marker::U8 => ValueRef::from(rd.read_data_u8()?),
144        Marker::U16 => ValueRef::from(rd.read_data_u16()?),
145        Marker::U32 => ValueRef::from(rd.read_data_u32()?),
146        Marker::U64 => ValueRef::from(rd.read_data_u64()?),
147        Marker::I8 => ValueRef::from(rd.read_data_i8()?),
148        Marker::I16 => ValueRef::from(rd.read_data_i16()?),
149        Marker::I32 => ValueRef::from(rd.read_data_i32()?),
150        Marker::I64 => ValueRef::from(rd.read_data_i64()?),
151        Marker::F32 => ValueRef::F32(rd.read_data_f32()?),
152        Marker::F64 => ValueRef::F64(rd.read_data_f64()?),
153        Marker::FixStr(len) => {
154            let res = read_str_data(rd, len as usize, depth)?;
155            ValueRef::String(res)
156        }
157        Marker::Str8 => {
158            let len = rd.read_data_u8()?;
159            let res = read_str_data(rd, len as usize, depth)?;
160            ValueRef::String(res)
161        }
162        Marker::Str16 => {
163            let len = rd.read_data_u16()?;
164            let res = read_str_data(rd, len as usize, depth)?;
165            ValueRef::String(res)
166        }
167        Marker::Str32 => {
168            let len = rd.read_data_u32()?;
169            let res = read_str_data(rd, len as usize, depth)?;
170            ValueRef::String(res)
171        }
172        Marker::Bin8 => {
173            let len = rd.read_data_u8()?;
174            let res = read_bin_data(rd, len as usize, depth)?;
175            ValueRef::Binary(res)
176        }
177        Marker::Bin16 => {
178            let len = rd.read_data_u16()?;
179            let res = read_bin_data(rd, len as usize, depth)?;
180            ValueRef::Binary(res)
181        }
182        Marker::Bin32 => {
183            let len = rd.read_data_u32()?;
184            let res = read_bin_data(rd, len as usize, depth)?;
185            ValueRef::Binary(res)
186        }
187        Marker::FixArray(len) => {
188            let vec = read_array_data(rd, len as usize, depth)?;
189            ValueRef::Array(vec)
190        }
191        Marker::Array16 => {
192            let len = rd.read_data_u16()?;
193            let vec = read_array_data(rd, len as usize, depth)?;
194            ValueRef::Array(vec)
195        }
196        Marker::Array32 => {
197            let len = rd.read_data_u32()?;
198            let vec = read_array_data(rd, len as usize, depth)?;
199            ValueRef::Array(vec)
200        }
201        Marker::FixMap(len) => {
202            let map = read_map_data(rd, len as usize, depth)?;
203            ValueRef::Map(map)
204        }
205        Marker::Map16 => {
206            let len = rd.read_data_u16()?;
207            let map = read_map_data(rd, len as usize, depth)?;
208            ValueRef::Map(map)
209        }
210        Marker::Map32 => {
211            let len = rd.read_data_u32()?;
212            let map = read_map_data(rd, len as usize, depth)?;
213            ValueRef::Map(map)
214        }
215        Marker::FixExt1 => {
216            let len = 1;
217            let (ty, vec) = read_ext_body(rd, len as usize, depth)?;
218            ValueRef::Ext(ty, vec)
219        }
220        Marker::FixExt2 => {
221            let len = 2;
222            let (ty, vec) = read_ext_body(rd, len as usize, depth)?;
223            ValueRef::Ext(ty, vec)
224        }
225        Marker::FixExt4 => {
226            let len = 4;
227            let (ty, vec) = read_ext_body(rd, len as usize, depth)?;
228            ValueRef::Ext(ty, vec)
229        }
230        Marker::FixExt8 => {
231            let len = 8;
232            let (ty, vec) = read_ext_body(rd, len as usize, depth)?;
233            ValueRef::Ext(ty, vec)
234        }
235        Marker::FixExt16 => {
236            let len = 16;
237            let (ty, vec) = read_ext_body(rd, len as usize, depth)?;
238            ValueRef::Ext(ty, vec)
239        }
240        Marker::Ext8 => {
241            let len = rd.read_data_u8()?;
242            let (ty, vec) = read_ext_body(rd, len as usize, depth)?;
243            ValueRef::Ext(ty, vec)
244        }
245        Marker::Ext16 => {
246            let len = rd.read_data_u16()?;
247            let (ty, vec) = read_ext_body(rd, len as usize, depth)?;
248            ValueRef::Ext(ty, vec)
249        }
250        Marker::Ext32 => {
251            let len = rd.read_data_u32()?;
252            let (ty, vec) = read_ext_body(rd, len as usize, depth)?;
253            ValueRef::Ext(ty, vec)
254        }
255        Marker::Reserved => ValueRef::Nil,
256    };
257
258    Ok(val)
259}
260
261/// Attempts to read the data from the given reader until either a complete MessagePack value
262/// decoded or an error detected.
263///
264/// Returns either a non-owning `ValueRef`, which borrows the buffer from the given reader or an
265/// error.
266///
267/// The reader should meet the requirement of a special `BorrowRead` trait, which allows to mutate
268/// itself but permits to mutate the buffer it contains. It allows to perform a completely
269/// zero-copy reading without a data loss fear in case of an error.
270///
271/// Currently only two types fit in this requirement: `&[u8]` and `Cursor<&[u8]>`. Using Cursor is
272/// helpful, when you need to know how exactly many bytes the decoded `ValueRef` consumes. A `Vec<u8>`
273/// type doesn't fit in the `BorrowRead` requirement, because its mut reference can mutate the
274/// underlying buffer - use `Vec::as_slice()` if you need to decode a value from the vector.
275///
276/// # Errors
277///
278/// Returns an `Error` value if unable to continue the decoding operation either because of read
279/// failure or any other circumstances. See `Error` documentation for more information.
280///
281/// This function enforces a maximum recursion depth of [`MAX_DEPTH`](super::MAX_DEPTH) and returns
282/// [`Error::DepthLimitExceeded`] if the maximum is hit. If you run into stack overflows despite
283/// this, use [`read_value_ref_with_max_depth`] with a custom maximum depth.
284///
285/// # Examples
286/// ```
287/// use rmpv::ValueRef;
288/// use rmpv::decode::read_value_ref;
289///
290/// let buf = [0xaa, 0x6c, 0x65, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65];
291/// let mut rd = &buf[..];
292///
293/// assert_eq!(ValueRef::from("le message"), read_value_ref(&mut rd).unwrap());
294/// ```
295#[inline(never)]
296pub fn read_value_ref<'a, R>(rd: &mut R) -> Result<ValueRef<'a>, Error>
297    where R: BorrowRead<'a>
298{
299    read_value_ref_inner(rd, super::MAX_DEPTH as _)
300}
301
302/// Attempts to read the data from the given reader until either a complete MessagePack value
303/// decoded or an error detected.
304///
305/// Returns either a non-owning `ValueRef`, which borrows the buffer from the given reader or an
306/// error.
307///
308/// See [`read_value_ref`] for more information on how to use this function. This variant allows
309/// you to specify the maximum recursion depth, if [`MAX_DEPTH`](super::MAX_DEPTH) is too high.
310///
311/// # Errors
312///
313/// Same as [`read_value_ref`], using the `max_depth` parameter in place of
314/// [`MAX_DEPTH`](super::MAX_DEPTH).
315#[inline(never)]
316pub fn read_value_ref_with_max_depth<'a, R>(rd: &mut R, max_depth: usize) -> Result<ValueRef<'a>, Error>
317    where R: BorrowRead<'a>
318{
319    read_value_ref_inner(rd, max_depth.min(u16::MAX as _) as u16)
320}