1use std;
2use std::io::{self, Cursor, ErrorKind, Read};
3use std::str;
4
5use rmp::Marker;
6use rmp::decode::{read_marker, read_data_u8, read_data_u16, read_data_u32, read_data_u64,
7 read_data_i8, read_data_i16, read_data_i32, read_data_i64, read_data_f32,
8 read_data_f64};
9
10use crate::{Utf8StringRef, ValueRef};
11use super::Error;
12
13fn read_str_data<'a, R>(rd: &mut R, len: usize) -> Result<Utf8StringRef<'a>, Error>
14 where R: BorrowRead<'a>
15{
16 let buf = read_bin_data(rd, len)?;
17 match str::from_utf8(buf) {
18 Ok(s) => Ok(Utf8StringRef::from(s)),
19 Err(err) => {
20 let s = Utf8StringRef {
21 s: Err((buf, err)),
22 };
23 Ok(s)
24 }
25 }
26}
27
28fn read_bin_data<'a, R>(rd: &mut R, len: usize) -> Result<&'a [u8], Error>
29 where R: BorrowRead<'a>
30{
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 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) -> Result<(i8, &'a [u8]), Error>
45 where R: BorrowRead<'a>
46{
47 let ty = read_data_i8(rd)?;
48 let buf = read_bin_data(rd, len)?;
49
50 Ok((ty, buf))
51}
52
53fn read_array_data<'a, R>(rd: &mut R, mut len: usize) -> Result<Vec<ValueRef<'a>>, Error>
54 where R: BorrowRead<'a>
55{
56 let mut vec = Vec::new();
59
60 while len > 0 {
61 vec.push(read_value_ref(rd)?);
62 len -= 1;
63 }
64
65 Ok(vec)
66}
67
68fn read_map_data<'a, R>(rd: &mut R, mut len: usize) -> Result<Vec<(ValueRef<'a>, ValueRef<'a>)>, Error>
69 where R: BorrowRead<'a>
70{
71 let mut vec = Vec::new();
74
75 while len > 0 {
76 vec.push((read_value_ref(rd)?, read_value_ref(rd)?));
77 len -= 1;
78 }
79
80 Ok(vec)
81}
82
83pub trait BorrowRead<'a>: Read {
88 fn fill_buf(&self) -> &'a [u8];
98
99 fn consume(&mut self, len: usize);
102}
103
104impl<'a> BorrowRead<'a> for &'a [u8] {
105 fn fill_buf(&self) -> &'a [u8] {
106 self
107 }
108
109 fn consume(&mut self, len: usize) {
110 *self = &(*self)[len..];
111 }
112}
113
114impl<'a> BorrowRead<'a> for Cursor<&'a [u8]> {
116 fn fill_buf(&self) -> &'a [u8] {
117 let len = std::cmp::min(self.position(), self.get_ref().len() as u64);
118 &self.get_ref()[len as usize..]
119 }
120
121 fn consume(&mut self, len: usize) {
122 let pos = self.position();
123 self.set_position(pos + len as u64);
124 }
125}
126
127pub fn read_value_ref<'a, R>(rd: &mut R) -> Result<ValueRef<'a>, Error>
158 where R: BorrowRead<'a>
159{
160
161 let val = match read_marker(rd)? {
164 Marker::Null => ValueRef::Nil,
165 Marker::True => ValueRef::Boolean(true),
166 Marker::False => ValueRef::Boolean(false),
167 Marker::FixPos(val) => ValueRef::from(val),
168 Marker::FixNeg(val) => ValueRef::from(val),
169 Marker::U8 => ValueRef::from(read_data_u8(rd)?),
170 Marker::U16 => ValueRef::from(read_data_u16(rd)?),
171 Marker::U32 => ValueRef::from(read_data_u32(rd)?),
172 Marker::U64 => ValueRef::from(read_data_u64(rd)?),
173 Marker::I8 => ValueRef::from(read_data_i8(rd)?),
174 Marker::I16 => ValueRef::from(read_data_i16(rd)?),
175 Marker::I32 => ValueRef::from(read_data_i32(rd)?),
176 Marker::I64 => ValueRef::from(read_data_i64(rd)?),
177 Marker::F32 => ValueRef::F32(read_data_f32(rd)?),
178 Marker::F64 => ValueRef::F64(read_data_f64(rd)?),
179 Marker::FixStr(len) => {
180 let res = read_str_data(rd, len as usize)?;
181 ValueRef::String(res)
182 }
183 Marker::Str8 => {
184 let len = read_data_u8(rd)?;
185 let res = read_str_data(rd, len as usize)?;
186 ValueRef::String(res)
187 }
188 Marker::Str16 => {
189 let len = read_data_u16(rd)?;
190 let res = read_str_data(rd, len as usize)?;
191 ValueRef::String(res)
192 }
193 Marker::Str32 => {
194 let len = read_data_u32(rd)?;
195 let res = read_str_data(rd, len as usize)?;
196 ValueRef::String(res)
197 }
198 Marker::Bin8 => {
199 let len = read_data_u8(rd)?;
200 let res = read_bin_data(rd, len as usize)?;
201 ValueRef::Binary(res)
202 }
203 Marker::Bin16 => {
204 let len = read_data_u16(rd)?;
205 let res = read_bin_data(rd, len as usize)?;
206 ValueRef::Binary(res)
207 }
208 Marker::Bin32 => {
209 let len = read_data_u32(rd)?;
210 let res = read_bin_data(rd, len as usize)?;
211 ValueRef::Binary(res)
212 }
213 Marker::FixArray(len) => {
214 let vec = read_array_data(rd, len as usize)?;
215 ValueRef::Array(vec)
216 }
217 Marker::Array16 => {
218 let len = read_data_u16(rd)?;
219 let vec = read_array_data(rd, len as usize)?;
220 ValueRef::Array(vec)
221 }
222 Marker::Array32 => {
223 let len = read_data_u32(rd)?;
224 let vec = read_array_data(rd, len as usize)?;
225 ValueRef::Array(vec)
226 }
227 Marker::FixMap(len) => {
228 let map = read_map_data(rd, len as usize)?;
229 ValueRef::Map(map)
230 }
231 Marker::Map16 => {
232 let len = read_data_u16(rd)?;
233 let map = read_map_data(rd, len as usize)?;
234 ValueRef::Map(map)
235 }
236 Marker::Map32 => {
237 let len = read_data_u32(rd)?;
238 let map = read_map_data(rd, len as usize)?;
239 ValueRef::Map(map)
240 }
241 Marker::FixExt1 => {
242 let len = 1;
243 let (ty, vec) = read_ext_body(rd, len as usize)?;
244 ValueRef::Ext(ty, vec)
245 }
246 Marker::FixExt2 => {
247 let len = 2;
248 let (ty, vec) = read_ext_body(rd, len as usize)?;
249 ValueRef::Ext(ty, vec)
250 }
251 Marker::FixExt4 => {
252 let len = 4;
253 let (ty, vec) = read_ext_body(rd, len as usize)?;
254 ValueRef::Ext(ty, vec)
255 }
256 Marker::FixExt8 => {
257 let len = 8;
258 let (ty, vec) = read_ext_body(rd, len as usize)?;
259 ValueRef::Ext(ty, vec)
260 }
261 Marker::FixExt16 => {
262 let len = 16;
263 let (ty, vec) = read_ext_body(rd, len as usize)?;
264 ValueRef::Ext(ty, vec)
265 }
266 Marker::Ext8 => {
267 let len = read_data_u8(rd)?;
268 let (ty, vec) = read_ext_body(rd, len as usize)?;
269 ValueRef::Ext(ty, vec)
270 }
271 Marker::Ext16 => {
272 let len = read_data_u16(rd)?;
273 let (ty, vec) = read_ext_body(rd, len as usize)?;
274 ValueRef::Ext(ty, vec)
275 }
276 Marker::Ext32 => {
277 let len = read_data_u32(rd)?;
278 let (ty, vec) = read_ext_body(rd, len as usize)?;
279 ValueRef::Ext(ty, vec)
280 }
281 Marker::Reserved => ValueRef::Nil,
282 };
283
284 Ok(val)
285}