/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rmp-0.8.15/src/decode/ext.rs
Line | Count | Source |
1 | | use super::{read_marker, RmpRead, ValueReadError}; |
2 | | use crate::Marker; |
3 | | |
4 | | /// Attempts to read exactly 3 bytes from the given reader and interpret them as a fixext1 type |
5 | | /// with data attached. |
6 | | /// |
7 | | /// According to the MessagePack specification, a fixext1 stores an integer and a byte array whose |
8 | | /// length is 1 byte. Its marker byte is `0xd4`. |
9 | | /// |
10 | | /// Note, that this function copies a byte array from the reader to the output `u8` variable. |
11 | | /// |
12 | | /// # Errors |
13 | | /// |
14 | | /// This function will return `ValueReadError` on any I/O error while reading either the marker or |
15 | | /// the data. |
16 | | /// |
17 | | /// # Note |
18 | | /// |
19 | | /// This function will silently retry on every EINTR received from the underlying `Read` until |
20 | | /// successful read. |
21 | 0 | pub fn read_fixext1<R: RmpRead>(rd: &mut R) -> Result<(i8, u8), ValueReadError<R::Error>> { |
22 | 0 | match read_marker(rd)? { |
23 | | Marker::FixExt1 => { |
24 | 0 | let ty = rd.read_data_i8()?; |
25 | 0 | let data = rd.read_data_u8()?; |
26 | 0 | Ok((ty, data)) |
27 | | }, |
28 | 0 | marker => Err(ValueReadError::TypeMismatch(marker)), |
29 | | } |
30 | 0 | } |
31 | | |
32 | | /// Attempts to read exactly 4 bytes from the given reader and interpret them as a fixext2 type |
33 | | /// with data attached. |
34 | | /// |
35 | | /// According to the MessagePack specification, a fixext2 stores an integer and a byte array whose |
36 | | /// length is 2 bytes. Its marker byte is `0xd5`. |
37 | | /// |
38 | | /// Note, that this function copies a byte array from the reader to the output buffer, which is |
39 | | /// unlikely if you want zero-copy functionality. |
40 | | /// |
41 | | /// # Errors |
42 | | /// |
43 | | /// This function will return `ValueReadError` on any I/O error while reading either the marker or |
44 | | /// the data. |
45 | 0 | pub fn read_fixext2<R: RmpRead>(rd: &mut R) -> Result<(i8, [u8; 2]), ValueReadError<R::Error>> { |
46 | 0 | match read_marker(rd)? { |
47 | | Marker::FixExt2 => { |
48 | 0 | let mut buf = [0; 2]; |
49 | 0 | read_fixext_data(rd, &mut buf).map(|ty| (ty, buf)) |
50 | | }, |
51 | 0 | marker => Err(ValueReadError::TypeMismatch(marker)), |
52 | | } |
53 | 0 | } |
54 | | |
55 | | /// Attempts to read exactly 6 bytes from the given reader and interpret them as a fixext4 type |
56 | | /// with data attached. |
57 | | /// |
58 | | /// According to the MessagePack specification, a fixext4 stores an integer and a byte array whose |
59 | | /// length is 4 bytes. Its marker byte is `0xd6`. |
60 | | /// |
61 | | /// Note, that this function copies a byte array from the reader to the output buffer, which is |
62 | | /// unlikely if you want zero-copy functionality. |
63 | | /// |
64 | | /// # Errors |
65 | | /// |
66 | | /// This function will return `ValueReadError` on any I/O error while reading either the marker or |
67 | | /// the data. |
68 | 0 | pub fn read_fixext4<R: RmpRead>(rd: &mut R) -> Result<(i8, [u8; 4]), ValueReadError<R::Error>> { |
69 | 0 | match read_marker(rd)? { |
70 | | Marker::FixExt4 => { |
71 | 0 | let mut buf = [0; 4]; |
72 | 0 | read_fixext_data(rd, &mut buf).map(|ty| (ty, buf)) |
73 | | }, |
74 | 0 | marker => Err(ValueReadError::TypeMismatch(marker)), |
75 | | } |
76 | 0 | } |
77 | | |
78 | | /// Attempts to read exactly 10 bytes from the given reader and interpret them as a fixext8 type |
79 | | /// with data attached. |
80 | | /// |
81 | | /// According to the MessagePack specification, a fixext8 stores an integer and a byte array whose |
82 | | /// length is 8 bytes. Its marker byte is `0xd7`. |
83 | | /// |
84 | | /// Note, that this function copies a byte array from the reader to the output buffer, which is |
85 | | /// unlikely if you want zero-copy functionality. |
86 | | /// |
87 | | /// # Errors |
88 | | /// |
89 | | /// This function will return `ValueReadError` on any I/O error while reading either the marker or |
90 | | /// the data. |
91 | 0 | pub fn read_fixext8<R: RmpRead>(rd: &mut R) -> Result<(i8, [u8; 8]), ValueReadError<R::Error>> { |
92 | 0 | match read_marker(rd)? { |
93 | | Marker::FixExt8 => { |
94 | 0 | let mut buf = [0; 8]; |
95 | 0 | read_fixext_data(rd, &mut buf).map(|ty| (ty, buf)) |
96 | | }, |
97 | 0 | marker => Err(ValueReadError::TypeMismatch(marker)), |
98 | | } |
99 | 0 | } |
100 | | |
101 | | /// Attempts to read exactly 18 bytes from the given reader and interpret them as a fixext16 type |
102 | | /// with data attached. |
103 | | /// |
104 | | /// According to the MessagePack specification, a fixext16 stores an integer and a byte array whose |
105 | | /// length is 16 bytes. Its marker byte is `0xd8`. |
106 | | /// |
107 | | /// Note, that this function copies a byte array from the reader to the output buffer, which is |
108 | | /// unlikely if you want zero-copy functionality. |
109 | | /// |
110 | | /// # Errors |
111 | | /// |
112 | | /// This function will return `ValueReadError` on any I/O error while reading either the marker or |
113 | | /// the data. |
114 | 0 | pub fn read_fixext16<R: RmpRead>(rd: &mut R) -> Result<(i8, [u8; 16]), ValueReadError<R::Error>> { |
115 | 0 | match read_marker(rd)? { |
116 | | Marker::FixExt16 => { |
117 | 0 | let mut buf = [0; 16]; |
118 | 0 | read_fixext_data(rd, &mut buf).map(|ty| (ty, buf)) |
119 | | }, |
120 | 0 | marker => Err(ValueReadError::TypeMismatch(marker)), |
121 | | } |
122 | 0 | } |
123 | | |
124 | 0 | fn read_fixext_data<R: RmpRead>(rd: &mut R, buf: &mut [u8]) -> Result<i8, ValueReadError<R::Error>> { |
125 | 0 | let id = rd.read_data_i8()?; |
126 | 0 | match rd.read_exact_buf(buf) { |
127 | 0 | Ok(()) => Ok(id), |
128 | 0 | Err(err) => Err(ValueReadError::InvalidDataRead(err)), |
129 | | } |
130 | 0 | } |
131 | | |
132 | | /// Extension type meta information. |
133 | | /// |
134 | | /// Extension represents a tuple of type information and a byte array where type information is an |
135 | | /// integer whose meaning is defined by applications. |
136 | | /// |
137 | | /// Applications can assign 0 to 127 to store application-specific type information. |
138 | | /// |
139 | | /// # Note |
140 | | /// |
141 | | /// MessagePack reserves -1 to -128 for future extension to add predefined types which will be |
142 | | /// described in separated documents. |
143 | | #[derive(Debug, PartialEq)] |
144 | | pub struct ExtMeta { |
145 | | /// Type information. |
146 | | pub typeid: i8, |
147 | | /// Byte array size. |
148 | | pub size: u32, |
149 | | } |
150 | | |
151 | 0 | pub fn read_ext_meta<R: RmpRead>(rd: &mut R) -> Result<ExtMeta, ValueReadError<R::Error>> { |
152 | 0 | let size = match read_marker(rd)? { |
153 | 0 | Marker::FixExt1 => 1, |
154 | 0 | Marker::FixExt2 => 2, |
155 | 0 | Marker::FixExt4 => 4, |
156 | 0 | Marker::FixExt8 => 8, |
157 | 0 | Marker::FixExt16 => 16, |
158 | 0 | Marker::Ext8 => u32::from(rd.read_data_u8()?), |
159 | 0 | Marker::Ext16 => u32::from(rd.read_data_u16()?), |
160 | 0 | Marker::Ext32 => rd.read_data_u32()?, |
161 | 0 | marker => return Err(ValueReadError::TypeMismatch(marker)), |
162 | | }; |
163 | | |
164 | 0 | let ty = rd.read_data_i8()?; |
165 | 0 | let meta = ExtMeta { typeid: ty, size }; |
166 | | |
167 | 0 | Ok(meta) |
168 | 0 | } |