1use crate::primitive::*;
2use crate::value;
3use crate::{code, unpack, value::RefValue, BufferedRead, UnpackError};
4
5use std::io::{self, ErrorKind};
6
7pub fn unpack_ary_data<'a, R>(reader: &mut R, len: usize) -> Result<Vec<RefValue<'a>>, UnpackError>
8where
9 R: BufferedRead<'a>,
10{
11 let mut vec = Vec::with_capacity(len);
12 for _ in 0..len {
13 vec.push(unpack_value_ref(reader)?);
14 }
15
16 Ok(vec)
17}
18
19pub fn unpack_ary<'a, R>(reader: &mut R) -> Result<Vec<RefValue<'a>>, UnpackError>
20where
21 R: BufferedRead<'a>,
22{
23 let len = unpack::unpack_ary_header(reader)?;
24 unpack_ary_data(reader, len)
25}
26
27pub fn unpack_map_data<'a, R>(
28 reader: &mut R,
29 len: usize,
30) -> Result<Vec<(RefValue<'a>, RefValue<'a>)>, UnpackError>
31where
32 R: BufferedRead<'a>,
33{
34 let mut vec = Vec::with_capacity(len);
35 for _ in 0..len {
36 vec.push((unpack_value_ref(reader)?, unpack_value_ref(reader)?));
37 }
38
39 Ok(vec)
40}
41
42pub fn unpack_map<'a, R>(reader: &mut R) -> Result<Vec<(RefValue<'a>, RefValue<'a>)>, UnpackError>
43where
44 R: BufferedRead<'a>,
45{
46 let len = unpack::unpack_map_header(reader)?;
47 unpack_map_data(reader, len)
48}
49
50fn unpack_str_data<'a, R>(
51 reader: &mut R,
52 len: usize,
53) -> Result<value::Utf8StringRef<'a>, UnpackError>
54where
55 R: BufferedRead<'a>,
56{
57 let buf = unpack_bin_data(reader, len)?;
58 Ok(value::Utf8StringRef::from(buf))
59}
60
61pub fn unpack_str<'a, R>(reader: &mut R) -> Result<value::Utf8StringRef<'a>, UnpackError>
62where
63 R: BufferedRead<'a>,
64{
65 let len = unpack::unpack_str_header(reader)?;
66 unpack_str_data(reader, len)
67}
68
69#[test]
70fn test_unpack_str() {
71 let v = vec![0xa5, 0x68, 0x65, 0x6c, 0x6c, 0x6f];
72 let mut cur = io::Cursor::new(v.as_ref());
73 let ret = unpack_str(&mut cur).unwrap();
74 assert_eq!(*ret, Ok("hello"));
75}
76
77fn unpack_bin_data<'a, R>(reader: &mut R, len: usize) -> Result<&'a [u8], UnpackError>
78where
79 R: BufferedRead<'a>,
80{
81 let buf = reader.fill_buf().map_err(|e| UnpackError::InvalidData(e))?;
82 if len > buf.len() {
83 return Err(UnpackError::InvalidData(io::Error::new(
84 ErrorKind::UnexpectedEof,
85 "Unexpected EOF",
86 )));
87 }
88
89 let buf = &buf[..len];
90 reader.consume(len);
91 Ok(buf)
92}
93
94pub fn unpack_bin<'a, R>(reader: &mut R) -> Result<&'a [u8], UnpackError>
95where
96 R: BufferedRead<'a>,
97{
98 let len = unpack::unpack_bin_header(reader)?;
99 unpack_bin_data(reader, len)
100}
101
102#[test]
103fn test_unpack_bin() {
104 let v = vec![0xc4, 0x03, 0x61, 0x61, 0x61];
105 let mut cur = io::Cursor::new(v.as_ref());
106 let ret = unpack_bin(&mut cur).unwrap();
107 assert_eq!(ret, &[0x61, 0x61, 0x61]);
108}
109
110fn unpack_ext_type_data<'a, R>(reader: &mut R, len: usize) -> Result<(i8, &'a [u8]), UnpackError>
111where
112 R: BufferedRead<'a>,
113{
114 let ty = read_data_i8(reader)?;
115 let bin = unpack_bin_data(reader, len)?;
116 Ok((ty, bin))
117}
118
119const TIMESTAMP64_SEC_MASK: u64 = (1 << 35) - 1;
120const TIMESTAMP64_NSEC_MASK: u32 = (1 << 31) - 1;
121
122pub fn unpack_value_ref<'a, R>(reader: &mut R) -> Result<RefValue<'a>, UnpackError>
123where
124 R: BufferedRead<'a>,
125{
126 use code::Code;
127
128 let val = match read_code(reader)? {
129 Code::Nil => RefValue::Nil,
130 Code::True => RefValue::from(true),
131 Code::False => RefValue::from(false),
132 Code::PosInt(v) => RefValue::from(v),
133 Code::Uint8 => RefValue::from(read_data_u8(reader)?),
134 Code::Uint16 => RefValue::from(read_data_u16(reader)?),
135 Code::Uint32 => RefValue::from(read_data_u32(reader)?),
136 Code::Uint64 => RefValue::from(read_data_u64(reader)?),
137 Code::NegInt(v) => RefValue::from(v),
138 Code::Int8 => RefValue::from(read_data_i8(reader)?),
139 Code::Int16 => RefValue::from(read_data_i16(reader)?),
140 Code::Int32 => RefValue::from(read_data_i32(reader)?),
141 Code::Int64 => RefValue::from(read_data_i64(reader)?),
142 Code::Float32 => RefValue::from(read_data_f32(reader)?),
143 Code::Float64 => RefValue::from(read_data_f64(reader)?),
144 Code::FixStr(len) => RefValue::String(unpack_str_data(reader, usize::from(len))?),
145 Code::Str8 => {
146 let len = usize::from(read_data_u8(reader)?);
147 RefValue::String(unpack_str_data(reader, len)?)
148 }
149 Code::Str16 => {
150 let len = usize::from(read_data_u16(reader)?);
151 RefValue::String(unpack_str_data(reader, len)?)
152 }
153 Code::Str32 => {
154 let len = read_data_u32(reader)? as usize;
155 RefValue::String(unpack_str_data(reader, len)?)
156 }
157 Code::Bin8 => {
158 let len = usize::from(read_data_u8(reader)?);
159 RefValue::Binary(unpack_bin_data(reader, len)?)
160 }
161 Code::Bin16 => {
162 let len = usize::from(read_data_u16(reader)?);
163 RefValue::Binary(unpack_bin_data(reader, len)?)
164 }
165 Code::Bin32 => {
166 let len = read_data_u32(reader)? as usize;
167 RefValue::Binary(unpack_bin_data(reader, len)?)
168 }
169 Code::FixArray(len) => RefValue::Array(unpack_ary_data(reader, len as usize)?),
170 Code::Array16 => {
171 let len = usize::from(read_data_u16(reader)?);
172 RefValue::Array(unpack_ary_data(reader, len)?)
173 }
174 Code::Array32 => {
175 let len = read_data_u32(reader)? as usize;
176 RefValue::Array(unpack_ary_data(reader, len)?)
177 }
178 Code::FixMap(len) => RefValue::Map(unpack_map_data(reader, len as usize)?),
179 Code::Map16 => {
180 let len = read_data_u16(reader)? as usize;
181 RefValue::Map(unpack_map_data(reader, len)?)
182 }
183 Code::Map32 => {
184 let len = read_data_u16(reader)? as usize;
185 RefValue::Map(unpack_map_data(reader, len)?)
186 }
187 Code::FixExt1 => {
188 let (ty, vec) = unpack_ext_type_data(reader, 1)?;
189 RefValue::Extension(ty, vec)
190 }
191 Code::FixExt2 => {
192 let (ty, vec) = unpack_ext_type_data(reader, 2)?;
193 RefValue::Extension(ty, vec)
194 }
195 Code::FixExt4 => {
196 let ty = read_data_i8(reader)?;
197
198 if ty == -1 {
200 let v: u32 = read_data_u32(reader)?;
201 RefValue::Timestamp(v as i64, 0)
202 } else {
203 let buf = unpack_bin_data(reader, 4)?;
204 RefValue::Extension(ty, buf)
205 }
206 }
207 Code::FixExt8 => {
208 let ty = read_data_i8(reader)?;
209
210 if ty == -1 {
212 let v = read_data_u64(reader)?;
213 let sec = v | TIMESTAMP64_SEC_MASK;
214 let nsec = (v >> 34) as u32 | TIMESTAMP64_NSEC_MASK;
215 RefValue::Timestamp(sec as i64, nsec)
216 } else {
217 let buf = unpack_bin_data(reader, 8)?;
218 RefValue::Extension(ty, buf)
219 }
220 }
221 Code::FixExt16 => {
222 let (ty, vec) = unpack_ext_type_data(reader, 16)?;
223 RefValue::Extension(ty, vec)
224 }
225 Code::Ext8 => {
226 let len = usize::from(read_data_u8(reader)?);
228 let ty = read_data_i8(reader)?;
229 if len == 12 && ty == -1 {
230 let nsec = read_data_u32(reader)?;
231 let sec = read_data_i64(reader)?;
232 RefValue::Timestamp(sec as i64, nsec)
233 } else {
234 let buf = unpack_bin_data(reader, 4)?;
235 RefValue::Extension(ty, buf)
236 }
237 }
238 Code::Ext16 => {
239 let len = usize::from(read_data_u16(reader)?);
240 let (ty, vec) = unpack_ext_type_data(reader, len)?;
241 RefValue::Extension(ty, vec)
242 }
243 Code::Ext32 => {
244 let len = read_data_u32(reader)? as usize;
245 let (ty, vec) = unpack_ext_type_data(reader, len)?;
246 RefValue::Extension(ty, vec)
247 }
248 _ => unreachable!(),
250 };
251
252 Ok(val)
253}