/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rmp-0.8.15/src/decode/mod.rs
Line | Count | Source |
1 | | //! Provides various functions and structs for MessagePack decoding. |
2 | | //! |
3 | | //! Most of the function defined in this module will silently handle interruption error (EINTR) |
4 | | //! received from the given `Read` to be in consistent state with the `Write::write_all` method in |
5 | | //! the standard library. |
6 | | //! |
7 | | //! Any other error would immediately interrupt the parsing process. If your reader can results in |
8 | | //! I/O error and simultaneously be a recoverable state (for example, when reading from |
9 | | //! non-blocking socket and it returns EWOULDBLOCK) be sure that you buffer the data externally |
10 | | //! to avoid data loss (using `BufRead` readers with manual consuming or some other way). |
11 | | |
12 | | mod dec; |
13 | | mod ext; |
14 | | mod sint; |
15 | | mod str; |
16 | | mod uint; |
17 | | |
18 | | #[cfg(feature = "std")] |
19 | | mod est; |
20 | | #[cfg(feature = "std")] |
21 | | pub use est::{MessageLen, LenError}; |
22 | | |
23 | | pub use self::dec::{read_f32, read_f64}; |
24 | | pub use self::ext::{ |
25 | | read_ext_meta, read_fixext1, read_fixext16, read_fixext2, read_fixext4, read_fixext8, ExtMeta, |
26 | | }; |
27 | | pub use self::sint::{read_i16, read_i32, read_i64, read_i8, read_nfix}; |
28 | | #[allow(deprecated)] |
29 | | // While we re-export deprecated items, we don't want to trigger warnings while compiling this crate |
30 | | pub use self::str::{read_str, read_str_from_slice, read_str_len, read_str_ref, DecodeStringError}; |
31 | | pub use self::uint::{read_pfix, read_u16, read_u32, read_u64, read_u8}; |
32 | | |
33 | | use core::fmt::{self, Debug, Display, Formatter}; |
34 | | #[cfg(feature = "std")] |
35 | | use std::error; |
36 | | |
37 | | use num_traits::cast::FromPrimitive; |
38 | | |
39 | | use crate::Marker; |
40 | | |
41 | | pub mod bytes; |
42 | | pub use bytes::Bytes; |
43 | | |
44 | | #[doc(inline)] |
45 | | #[allow(deprecated)] |
46 | | pub use crate::errors::Error; |
47 | | |
48 | | /// The error type for I/O operations on `RmpRead` and associated traits. |
49 | | /// |
50 | | /// For [`std::io::Read`], this is [`std::io::Error`] |
51 | | pub trait RmpReadErr: Display + Debug + crate::errors::MaybeErrBound + 'static {} |
52 | | #[cfg(feature = "std")] |
53 | | impl RmpReadErr for std::io::Error {} |
54 | | impl RmpReadErr for core::convert::Infallible {} |
55 | | |
56 | | macro_rules! read_byteorder_utils { |
57 | | ($($name:ident => $tp:ident),* $(,)?) => { |
58 | | $( |
59 | | #[inline] |
60 | | #[doc(hidden)] |
61 | 0 | fn $name(&mut self) -> Result<$tp, ValueReadError<Self::Error>> where Self: Sized { |
62 | | const SIZE: usize = core::mem::size_of::<$tp>(); |
63 | 0 | let mut buf: [u8; SIZE] = [0u8; SIZE]; |
64 | 0 | self.read_exact_buf(&mut buf).map_err(ValueReadError::InvalidDataRead)?; |
65 | 0 | Ok($tp::from_be_bytes(buf)) |
66 | 0 | } Unexecuted instantiation: <rmp::decode::bytes::Bytes as rmp::decode::RmpRead>::read_data_u16 Unexecuted instantiation: <rmp::decode::bytes::Bytes as rmp::decode::RmpRead>::read_data_u32 Unexecuted instantiation: <_ as rmp::decode::RmpRead>::read_data_f32 Unexecuted instantiation: <_ as rmp::decode::RmpRead>::read_data_f64 Unexecuted instantiation: <_ as rmp::decode::RmpRead>::read_data_i16 Unexecuted instantiation: <_ as rmp::decode::RmpRead>::read_data_i32 Unexecuted instantiation: <_ as rmp::decode::RmpRead>::read_data_i64 Unexecuted instantiation: <_ as rmp::decode::RmpRead>::read_data_u64 |
67 | | )* |
68 | | }; |
69 | | } |
70 | | mod sealed { |
71 | | pub trait Sealed {} |
72 | | #[cfg(feature = "std")] |
73 | | impl<T: ?Sized + std::io::Read> Sealed for T {} |
74 | | #[cfg(not(feature = "std"))] |
75 | | impl<'a> Sealed for &'a [u8] {} |
76 | | impl Sealed for super::Bytes<'_> {} |
77 | | } |
78 | | |
79 | | /// A type that `rmp` supports reading from. |
80 | | /// |
81 | | /// The methods of this trait should be considered an implementation detail (for now). |
82 | | /// It is currently sealed (can not be implemented by the user). |
83 | | /// |
84 | | /// Its primary implementations are [`std::io::Read`] and [Bytes]. |
85 | | pub trait RmpRead: sealed::Sealed { |
86 | | type Error: RmpReadErr; |
87 | | /// Read a single (unsigned) byte from this stream |
88 | | #[inline] |
89 | 0 | fn read_u8(&mut self) -> Result<u8, Self::Error> { |
90 | 0 | let mut buf = [0; 1]; |
91 | 0 | self.read_exact_buf(&mut buf)?; |
92 | 0 | Ok(buf[0]) |
93 | 0 | } |
94 | | |
95 | | /// Read the exact number of bytes needed to fill the specified buffer. |
96 | | /// |
97 | | /// If there are not enough bytes, this will return an error. |
98 | | /// |
99 | | /// See also [`std::io::Read::read_exact`] |
100 | | fn read_exact_buf(&mut self, buf: &mut [u8]) -> Result<(), Self::Error>; |
101 | | |
102 | | // Internal helper functions to map I/O error into the `InvalidDataRead` error. |
103 | | |
104 | | /// Read a single (unsigned) byte from this stream. |
105 | | #[inline] |
106 | | #[doc(hidden)] |
107 | 0 | fn read_data_u8(&mut self) -> Result<u8, ValueReadError<Self::Error>> { |
108 | 0 | self.read_u8().map_err(ValueReadError::InvalidDataRead) |
109 | 0 | } |
110 | | /// Read a single (signed) byte from this stream. |
111 | | #[inline] |
112 | | #[doc(hidden)] |
113 | 0 | fn read_data_i8(&mut self) -> Result<i8, ValueReadError<Self::Error>> { |
114 | 0 | self.read_data_u8().map(|b| b as i8) |
115 | 0 | } |
116 | | |
117 | | read_byteorder_utils!( |
118 | | read_data_u16 => u16, |
119 | | read_data_u32 => u32, |
120 | | read_data_u64 => u64, |
121 | | read_data_i16 => i16, |
122 | | read_data_i32 => i32, |
123 | | read_data_i64 => i64, |
124 | | read_data_f32 => f32, |
125 | | read_data_f64 => f64 |
126 | | ); |
127 | | } |
128 | | |
129 | | #[cfg(feature = "std")] |
130 | | impl<T: std::io::Read> RmpRead for T { |
131 | | type Error = std::io::Error; |
132 | | |
133 | | #[inline] |
134 | 0 | fn read_exact_buf(&mut self, buf: &mut [u8]) -> Result<(), Self::Error> { |
135 | 0 | std::io::Read::read_exact(self, buf) |
136 | 0 | } |
137 | | } |
138 | | |
139 | | /// An error that can occur when attempting to read a MessagePack marker from the reader. |
140 | | #[derive(Debug)] |
141 | | #[allow(deprecated)] // Needed for backwards compat |
142 | | pub struct MarkerReadError<E: RmpReadErr = Error>(pub E); |
143 | | |
144 | | /// An error which can occur when attempting to read a MessagePack value from the reader. |
145 | | #[derive(Debug)] |
146 | | #[allow(deprecated)] // Needed for backwards compat |
147 | | pub enum ValueReadError<E: RmpReadErr = Error> { |
148 | | /// Failed to read the marker. |
149 | | InvalidMarkerRead(E), |
150 | | /// Failed to read the data. |
151 | | InvalidDataRead(E), |
152 | | /// The type decoded isn't match with the expected one. |
153 | | TypeMismatch(Marker), |
154 | | } |
155 | | |
156 | | #[cfg(feature = "std")] |
157 | | impl error::Error for ValueReadError { |
158 | | #[cold] |
159 | 0 | fn source(&self) -> Option<&(dyn error::Error + 'static)> { |
160 | 0 | match *self { |
161 | 0 | Self::InvalidMarkerRead(ref err) | |
162 | 0 | Self::InvalidDataRead(ref err) => Some(err), |
163 | 0 | Self::TypeMismatch(..) => None, |
164 | | } |
165 | 0 | } |
166 | | } |
167 | | |
168 | | impl Display for ValueReadError { |
169 | | #[cold] |
170 | 0 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { |
171 | | // TODO: This should probably use formatting |
172 | 0 | f.write_str(match *self { |
173 | 0 | Self::InvalidMarkerRead(..) => "failed to read MessagePack marker", |
174 | 0 | Self::InvalidDataRead(..) => "failed to read MessagePack data", |
175 | 0 | Self::TypeMismatch(..) => "the type decoded isn't match with the expected one", |
176 | | }) |
177 | 0 | } |
178 | | } |
179 | | |
180 | | impl<E: RmpReadErr> From<MarkerReadError<E>> for ValueReadError<E> { |
181 | | #[cold] |
182 | 0 | fn from(err: MarkerReadError<E>) -> Self { |
183 | 0 | match err { |
184 | 0 | MarkerReadError(err) => Self::InvalidMarkerRead(err), |
185 | | } |
186 | 0 | } |
187 | | } |
188 | | |
189 | | impl<E: RmpReadErr> From<E> for MarkerReadError<E> { |
190 | | #[cold] |
191 | 0 | fn from(err: E) -> Self { |
192 | 0 | Self(err) |
193 | 0 | } |
194 | | } |
195 | | |
196 | | /// Attempts to read a single byte from the given reader and to decode it as a MessagePack marker. |
197 | | #[inline] |
198 | 0 | pub fn read_marker<R: RmpRead>(rd: &mut R) -> Result<Marker, MarkerReadError<R::Error>> { |
199 | 0 | Ok(Marker::from_u8(rd.read_u8()?)) |
200 | 0 | } |
201 | | |
202 | | /// Attempts to read a single byte from the given reader and to decode it as a nil value. |
203 | | /// |
204 | | /// According to the MessagePack specification, a nil value is represented as a single `0xc0` byte. |
205 | | /// |
206 | | /// # Errors |
207 | | /// |
208 | | /// This function will return `ValueReadError` on any I/O error while reading the nil marker, |
209 | | /// except the EINTR, which is handled internally. |
210 | | /// |
211 | | /// It also returns `ValueReadError::TypeMismatch` if the actual type is not equal with the |
212 | | /// expected one, indicating you with the actual type. |
213 | | /// |
214 | | /// # Note |
215 | | /// |
216 | | /// This function will silently retry on every EINTR received from the underlying `Read` until |
217 | | /// successful read. |
218 | 0 | pub fn read_nil<R: RmpRead>(rd: &mut R) -> Result<(), ValueReadError<R::Error>> { |
219 | 0 | match read_marker(rd)? { |
220 | 0 | Marker::Null => Ok(()), |
221 | 0 | marker => Err(ValueReadError::TypeMismatch(marker)), |
222 | | } |
223 | 0 | } |
224 | | |
225 | | /// Attempts to read a single byte from the given reader and to decode it as a boolean value. |
226 | | /// |
227 | | /// According to the MessagePack specification, an encoded boolean value is represented as a single |
228 | | /// byte. |
229 | | /// |
230 | | /// # Errors |
231 | | /// |
232 | | /// This function will return `ValueReadError` on any I/O error while reading the bool marker, |
233 | | /// except the EINTR, which is handled internally. |
234 | | /// |
235 | | /// It also returns `ValueReadError::TypeMismatch` if the actual type is not equal with the |
236 | | /// expected one, indicating you with the actual type. |
237 | | /// |
238 | | /// # Note |
239 | | /// |
240 | | /// This function will silently retry on every EINTR received from the underlying `Read` until |
241 | | /// successful read. |
242 | 0 | pub fn read_bool<R: RmpRead>(rd: &mut R) -> Result<bool, ValueReadError<R::Error>> { |
243 | 0 | match read_marker(rd)? { |
244 | 0 | Marker::True => Ok(true), |
245 | 0 | Marker::False => Ok(false), |
246 | 0 | marker => Err(ValueReadError::TypeMismatch(marker)), |
247 | | } |
248 | 0 | } |
249 | | |
250 | | /// An error which can occur when attempting to read a MessagePack numeric value from the reader. |
251 | | #[derive(Debug)] |
252 | | #[allow(deprecated)] // Used for compatibility |
253 | | pub enum NumValueReadError<E: RmpReadErr = Error> { |
254 | | /// Failed to read the marker. |
255 | | InvalidMarkerRead(E), |
256 | | /// Failed to read the data. |
257 | | InvalidDataRead(E), |
258 | | /// The type decoded isn't match with the expected one. |
259 | | TypeMismatch(Marker), |
260 | | /// Out of range integral type conversion attempted. |
261 | | OutOfRange, |
262 | | } |
263 | | |
264 | | #[cfg(feature = "std")] |
265 | | impl error::Error for NumValueReadError { |
266 | 0 | fn source(&self) -> Option<&(dyn error::Error + 'static)> { |
267 | 0 | match *self { |
268 | 0 | Self::InvalidMarkerRead(ref err) | |
269 | 0 | Self::InvalidDataRead(ref err) => Some(err), |
270 | 0 | Self::TypeMismatch(..) | |
271 | 0 | Self::OutOfRange => None, |
272 | | } |
273 | 0 | } |
274 | | } |
275 | | |
276 | | impl<E: RmpReadErr> Display for NumValueReadError<E> { |
277 | 0 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { |
278 | 0 | f.write_str(match *self { |
279 | 0 | Self::InvalidMarkerRead(..) => "failed to read MessagePack marker", |
280 | 0 | Self::InvalidDataRead(..) => "failed to read MessagePack data", |
281 | 0 | Self::TypeMismatch(..) => "the type decoded isn't match with the expected one", |
282 | 0 | Self::OutOfRange => "out of range integral type conversion attempted", |
283 | | }) |
284 | 0 | } |
285 | | } |
286 | | |
287 | | impl<E: RmpReadErr> From<MarkerReadError<E>> for NumValueReadError<E> { |
288 | | #[cold] |
289 | 0 | fn from(err: MarkerReadError<E>) -> Self { |
290 | 0 | match err { |
291 | 0 | MarkerReadError(err) => Self::InvalidMarkerRead(err), |
292 | | } |
293 | 0 | } |
294 | | } |
295 | | |
296 | | impl<E: RmpReadErr> From<ValueReadError<E>> for NumValueReadError<E> { |
297 | | #[cold] |
298 | 0 | fn from(err: ValueReadError<E>) -> Self { |
299 | 0 | match err { |
300 | 0 | ValueReadError::InvalidMarkerRead(err) => Self::InvalidMarkerRead(err), |
301 | 0 | ValueReadError::InvalidDataRead(err) => Self::InvalidDataRead(err), |
302 | 0 | ValueReadError::TypeMismatch(err) => Self::TypeMismatch(err), |
303 | | } |
304 | 0 | } |
305 | | } |
306 | | |
307 | | /// Attempts to read up to 9 bytes from the given reader and to decode them as integral `T` value. |
308 | | /// |
309 | | /// This function will try to read up to 9 bytes from the reader (1 for marker and up to 8 for data) |
310 | | /// and interpret them as a big-endian `T`. |
311 | | /// |
312 | | /// Unlike `read_*`, this function weakens type restrictions, allowing you to safely decode packed |
313 | | /// values even if you aren't sure about the actual integral type. |
314 | | /// |
315 | | /// # Errors |
316 | | /// |
317 | | /// This function will return `NumValueReadError` on any I/O error while reading either the marker |
318 | | /// or the data. |
319 | | /// |
320 | | /// It also returns `NumValueReadError::OutOfRange` if the actual type is not an integer or it does |
321 | | /// not fit in the given numeric range. |
322 | | /// |
323 | | /// # Examples |
324 | | /// |
325 | | /// ``` |
326 | | /// let buf = [0xcd, 0x1, 0x2c]; |
327 | | /// |
328 | | /// assert_eq!(300u16, rmp::decode::read_int(&mut &buf[..]).unwrap()); |
329 | | /// assert_eq!(300i16, rmp::decode::read_int(&mut &buf[..]).unwrap()); |
330 | | /// assert_eq!(300u32, rmp::decode::read_int(&mut &buf[..]).unwrap()); |
331 | | /// assert_eq!(300i32, rmp::decode::read_int(&mut &buf[..]).unwrap()); |
332 | | /// assert_eq!(300u64, rmp::decode::read_int(&mut &buf[..]).unwrap()); |
333 | | /// assert_eq!(300i64, rmp::decode::read_int(&mut &buf[..]).unwrap()); |
334 | | /// assert_eq!(300usize, rmp::decode::read_int(&mut &buf[..]).unwrap()); |
335 | | /// assert_eq!(300isize, rmp::decode::read_int(&mut &buf[..]).unwrap()); |
336 | | /// ``` |
337 | 0 | pub fn read_int<T: FromPrimitive, R: RmpRead>(rd: &mut R) -> Result<T, NumValueReadError<R::Error>> { |
338 | 0 | let val = match read_marker(rd)? { |
339 | 0 | Marker::FixPos(val) => T::from_u8(val), |
340 | 0 | Marker::FixNeg(val) => T::from_i8(val), |
341 | 0 | Marker::U8 => T::from_u8(rd.read_data_u8()?), |
342 | 0 | Marker::U16 => T::from_u16(rd.read_data_u16()?), |
343 | 0 | Marker::U32 => T::from_u32(rd.read_data_u32()?), |
344 | 0 | Marker::U64 => T::from_u64(rd.read_data_u64()?), |
345 | 0 | Marker::I8 => T::from_i8(rd.read_data_i8()?), |
346 | 0 | Marker::I16 => T::from_i16(rd.read_data_i16()?), |
347 | 0 | Marker::I32 => T::from_i32(rd.read_data_i32()?), |
348 | 0 | Marker::I64 => T::from_i64(rd.read_data_i64()?), |
349 | 0 | marker => return Err(NumValueReadError::TypeMismatch(marker)), |
350 | | }; |
351 | | |
352 | 0 | val.ok_or(NumValueReadError::OutOfRange) |
353 | 0 | } |
354 | | |
355 | | /// Attempts to read up to 5 bytes from the given reader and to decode them as a big-endian u32 |
356 | | /// array size. |
357 | | /// |
358 | | /// Array format family stores a sequence of elements in 1, 3, or 5 bytes of extra bytes in addition |
359 | | /// to the elements. |
360 | | /// |
361 | | /// # Note |
362 | | /// |
363 | | /// This function will silently retry on every EINTR received from the underlying `Read` until |
364 | | /// successful read. |
365 | | // TODO: Docs. |
366 | | // NOTE: EINTR is managed internally. |
367 | 0 | pub fn read_array_len<R>(rd: &mut R) -> Result<u32, ValueReadError<R::Error>> |
368 | 0 | where |
369 | 0 | R: RmpRead, |
370 | | { |
371 | 0 | match read_marker(rd)? { |
372 | 0 | Marker::FixArray(size) => Ok(u32::from(size)), |
373 | 0 | Marker::Array16 => Ok(u32::from(rd.read_data_u16()?)), |
374 | 0 | Marker::Array32 => Ok(rd.read_data_u32()?), |
375 | 0 | marker => Err(ValueReadError::TypeMismatch(marker)), |
376 | | } |
377 | 0 | } |
378 | | |
379 | | /// Attempts to read up to 5 bytes from the given reader and to decode them as a big-endian u32 |
380 | | /// map size. |
381 | | /// |
382 | | /// Map format family stores a sequence of elements in 1, 3, or 5 bytes of extra bytes in addition |
383 | | /// to the elements. |
384 | | /// |
385 | | /// # Note |
386 | | /// |
387 | | /// This function will silently retry on every EINTR received from the underlying `Read` until |
388 | | /// successful read. |
389 | | // TODO: Docs. |
390 | 0 | pub fn read_map_len<R: RmpRead>(rd: &mut R) -> Result<u32, ValueReadError<R::Error>> { |
391 | 0 | let marker = read_marker(rd)?; |
392 | 0 | marker_to_len(rd, marker) |
393 | 0 | } |
394 | | |
395 | 0 | pub fn marker_to_len<R: RmpRead>(rd: &mut R, marker: Marker) -> Result<u32, ValueReadError<R::Error>> { |
396 | 0 | match marker { |
397 | 0 | Marker::FixMap(size) => Ok(u32::from(size)), |
398 | 0 | Marker::Map16 => Ok(u32::from(rd.read_data_u16()?)), |
399 | 0 | Marker::Map32 => Ok(rd.read_data_u32()?), |
400 | 0 | marker => Err(ValueReadError::TypeMismatch(marker)), |
401 | | } |
402 | 0 | } |
403 | | |
404 | | /// Attempts to read up to 5 bytes from the given reader and to decode them as Binary array length. |
405 | | /// |
406 | | /// # Note |
407 | | /// |
408 | | /// This function will silently retry on every EINTR received from the underlying `Read` until |
409 | | /// successful read. |
410 | | // TODO: Docs. |
411 | 0 | pub fn read_bin_len<R: RmpRead>(rd: &mut R) -> Result<u32, ValueReadError<R::Error>> { |
412 | 0 | match read_marker(rd)? { |
413 | 0 | Marker::Bin8 => Ok(u32::from(rd.read_data_u8()?)), |
414 | 0 | Marker::Bin16 => Ok(u32::from(rd.read_data_u16()?)), |
415 | 0 | Marker::Bin32 => Ok(rd.read_data_u32()?), |
416 | 0 | marker => Err(ValueReadError::TypeMismatch(marker)), |
417 | | } |
418 | 0 | } |