1use std::cmp::min;
2use std::io::{self, Read};
3
4use rmp::Marker;
5use rmp::decode::{read_marker, read_data_u8, read_data_u16, read_data_u32, read_data_u64,
6 read_data_i8, read_data_i16, read_data_i32, read_data_i64, read_data_f32,
7 read_data_f64};
8
9use crate::{Utf8String, Value};
10use super::Error;
11
12
13const PREALLOC_MAX: usize = 64 * 1024; fn read_array_data<R: Read>(rd: &mut R, mut len: usize) -> Result<Vec<Value>, Error> {
18 let mut vec = Vec::new();
21
22 while len > 0 {
23 vec.push(read_value(rd)?);
24 len -= 1;
25 }
26
27 Ok(vec)
28}
29
30fn read_map_data<R: Read>(rd: &mut R, mut len: usize) -> Result<Vec<(Value, Value)>, Error> {
31 let mut vec = Vec::new();
34
35 while len > 0 {
36 vec.push((read_value(rd)?, read_value(rd)?));
37 len -= 1;
38 }
39
40 Ok(vec)
41}
42
43fn read_str_data<R: Read>(rd: &mut R, len: usize) -> Result<Utf8String, Error> {
44 match String::from_utf8(read_bin_data(rd, len)?) {
45 Ok(s) => Ok(Utf8String::from(s)),
46 Err(err) => {
47 let e = err.utf8_error();
48 let s = Utf8String {
49 s: Err((err.into_bytes(), e)),
50 };
51 Ok(s)
52 }
53 }
54}
55
56fn read_bin_data<R: Read>(rd: &mut R, len: usize) -> Result<Vec<u8>, Error> {
57 let mut buf = Vec::with_capacity(min(len, PREALLOC_MAX));
58 let bytes_read = rd.take(len as u64).read_to_end(&mut buf).map_err(Error::InvalidDataRead)?;
59 if bytes_read != len {
60 return Err(Error::InvalidDataRead(io::Error::new(
61 io::ErrorKind::UnexpectedEof,
62 format!("Expected {} bytes, read {} bytes", len, bytes_read),
63 )));
64 }
65
66 Ok(buf)
67}
68
69fn read_ext_body<R: Read>(rd: &mut R, len: usize) -> Result<(i8, Vec<u8>), Error> {
70 let ty = read_data_i8(rd)?;
71 let vec = read_bin_data(rd, len)?;
72
73 Ok((ty, vec))
74}
75
76pub fn read_value<R>(rd: &mut R) -> Result<Value, Error>
84 where R: Read
85{
86 let val = match read_marker(rd)? {
87 Marker::Null => Value::Nil,
88 Marker::True => Value::Boolean(true),
89 Marker::False => Value::Boolean(false),
90 Marker::FixPos(val) => Value::from(val),
91 Marker::FixNeg(val) => Value::from(val),
92 Marker::U8 => Value::from(read_data_u8(rd)?),
93 Marker::U16 => Value::from(read_data_u16(rd)?),
94 Marker::U32 => Value::from(read_data_u32(rd)?),
95 Marker::U64 => Value::from(read_data_u64(rd)?),
96 Marker::I8 => Value::from(read_data_i8(rd)?),
97 Marker::I16 => Value::from(read_data_i16(rd)?),
98 Marker::I32 => Value::from(read_data_i32(rd)?),
99 Marker::I64 => Value::from(read_data_i64(rd)?),
100 Marker::F32 => Value::F32(read_data_f32(rd)?),
101 Marker::F64 => Value::F64(read_data_f64(rd)?),
102 Marker::FixStr(len) => {
103 let res = read_str_data(rd, len as usize)?;
104 Value::String(res)
105 }
106 Marker::Str8 => {
107 let len = read_data_u8(rd)?;
108 let res = read_str_data(rd, len as usize)?;
109 Value::String(res)
110 }
111 Marker::Str16 => {
112 let len = read_data_u16(rd)?;
113 let res = read_str_data(rd, len as usize)?;
114 Value::String(res)
115 }
116 Marker::Str32 => {
117 let len = read_data_u32(rd)?;
118 let res = read_str_data(rd, len as usize)?;
119 Value::String(res)
120 }
121 Marker::FixArray(len) => {
122 let vec = read_array_data(rd, len as usize)?;
123 Value::Array(vec)
124 }
125 Marker::Array16 => {
126 let len = read_data_u16(rd)?;
127 let vec = read_array_data(rd, len as usize)?;
128 Value::Array(vec)
129 }
130 Marker::Array32 => {
131 let len = read_data_u32(rd)?;
132 let vec = read_array_data(rd, len as usize)?;
133 Value::Array(vec)
134 }
135 Marker::FixMap(len) => {
136 let map = read_map_data(rd, len as usize)?;
137 Value::Map(map)
138 }
139 Marker::Map16 => {
140 let len = read_data_u16(rd)?;
141 let map = read_map_data(rd, len as usize)?;
142 Value::Map(map)
143 }
144 Marker::Map32 => {
145 let len = read_data_u32(rd)?;
146 let map = read_map_data(rd, len as usize)?;
147 Value::Map(map)
148 }
149 Marker::Bin8 => {
150 let len = read_data_u8(rd)?;
151 let vec = read_bin_data(rd, len as usize)?;
152 Value::Binary(vec)
153 }
154 Marker::Bin16 => {
155 let len = read_data_u16(rd)?;
156 let vec = read_bin_data(rd, len as usize)?;
157 Value::Binary(vec)
158 }
159 Marker::Bin32 => {
160 let len = read_data_u32(rd)?;
161 let vec = read_bin_data(rd, len as usize)?;
162 Value::Binary(vec)
163 }
164 Marker::FixExt1 => {
165 let len = 1 as usize;
166 let (ty, vec) = read_ext_body(rd, len)?;
167 Value::Ext(ty, vec)
168 }
169 Marker::FixExt2 => {
170 let len = 2 as usize;
171 let (ty, vec) = read_ext_body(rd, len)?;
172 Value::Ext(ty, vec)
173 }
174 Marker::FixExt4 => {
175 let len = 4 as usize;
176 let (ty, vec) = read_ext_body(rd, len)?;
177 Value::Ext(ty, vec)
178 }
179 Marker::FixExt8 => {
180 let len = 8 as usize;
181 let (ty, vec) = read_ext_body(rd, len)?;
182 Value::Ext(ty, vec)
183 }
184 Marker::FixExt16 => {
185 let len = 16 as usize;
186 let (ty, vec) = read_ext_body(rd, len)?;
187 Value::Ext(ty, vec)
188 }
189 Marker::Ext8 => {
190 let len = read_data_u8(rd)? as usize;
191 let (ty, vec) = read_ext_body(rd, len)?;
192 Value::Ext(ty, vec)
193 }
194 Marker::Ext16 => {
195 let len = read_data_u16(rd)? as usize;
196 let (ty, vec) = read_ext_body(rd, len)?;
197 Value::Ext(ty, vec)
198 }
199 Marker::Ext32 => {
200 let len = read_data_u32(rd)? as usize;
201 let (ty, vec) = read_ext_body(rd, len)?;
202 Value::Ext(ty, vec)
203 }
204 Marker::Reserved => Value::Nil,
205 };
206
207 Ok(val)
208}