1extern crate rmp as msgpack;
2use crate::datatype::*;
3use crate::individual::*;
4use crate::parser::*;
5use crate::resource::*;
6use msgpack::decode::*;
7use msgpack::Marker;
8use std::io::Cursor;
9
10pub fn parse_msgpack(raw: &mut RawObj) -> Result<String, i8> {
11 if raw.data.is_empty() || raw.raw_type != RawType::Msgpack {
12 return Err(-1);
13 }
14
15 let mut cur = Cursor::new(raw.data.as_slice());
16
17 if let Ok(Marker::FixArray(size)) = read_marker(&mut cur) {
18 if size != 2 {
19 return Err(-1);
20 }
21 } else {
22 return Err(-1);
23 }
24
25 let uri = match read_string_from_msgpack(&mut cur) {
27 Ok(p) => p,
28 Err(_) => return Err(-1),
29 };
30
31 if let Ok(size) = read_map_len(&mut cur) {
32 raw.len_predicates = size as u32;
33 raw.cur = cur.position();
34 Ok(uri)
35 } else {
36 Err(-1)
37 }
38}
39
40pub fn parse_msgpack_to_predicate(expect_predicate: &str, iraw: &mut Individual) -> Result<(), String> {
41 if iraw.raw.cur >= iraw.raw.data.len() as u64 {
42 return Err("fail position of cursor".to_owned());
43 }
44
45 let mut is_found = false;
46 let mut cur = Cursor::new(iraw.raw.data.as_slice());
47 cur.set_position(iraw.raw.cur);
48
49 for i in iraw.raw.cur_predicates..iraw.raw.len_predicates {
50 let predicate = match read_string_from_msgpack(&mut cur) {
51 Ok(p) => p,
52 Err(e) => {
53 iraw.raw.cur = cur.position();
54 if e == -1 {
55 return Err("fail read_string_from_msgpack".to_owned());
56 } else {
57 return Err(String::default());
58 }
59 }
60 };
61
62 iraw.raw.cur_predicates = i;
63
64 if predicate == expect_predicate {
65 is_found = true;
66 }
67
68 match read_array_len(&mut cur) {
69 Ok(size) => {
70 for _i_values in 0..size {
71 match read_marker(&mut cur) {
72 Ok(v) => match v {
73 Marker::FixArray(size) => {
74 if size != 2 && size != 3 {
75 return Err(format!("parsing values, unexpected array size, len={:?}", size));
76 }
77
78 let v_type: u8;
79 if let Ok(t) = read_int(&mut cur) {
80 v_type = t;
81 } else {
82 return Err("parsing type".to_owned());
83 }
84
85 if size == 2 {
86 if v_type == DataType::Boolean as u8 {
87 match read_bool(&mut cur) {
88 Ok(res) => iraw.obj.add_bool(&predicate, res),
89 Err(e) => return Err(format!("value: expected {}, err={:?}", v_type, e)),
90 }
91 } else if v_type == DataType::Datetime as u8 {
92 match read_int(&mut cur) {
93 Ok(res) => iraw.obj.add_datetime(&predicate, res),
94 Err(e) => return Err(format!("value: expected {}, err={:?}", v_type, e)),
95 }
96 } else if v_type == DataType::Integer as u8 {
97 match read_int(&mut cur) {
98 Ok(res) => iraw.obj.add_integer(&predicate, res),
99 Err(e) => return Err(format!("value: expected {}, err={:?}", v_type, e)),
100 }
101 } else if v_type == DataType::Uri as u8 {
102 match read_string_from_msgpack(&mut cur) {
103 Ok(res) => iraw.obj.add_uri(&predicate, &res),
104 Err(e) => return Err(format!("value: expected {}, err={:?}", v_type, e)),
105 }
106 } else if v_type == DataType::Binary as u8 {
107 let values = iraw.obj.resources.entry(predicate.to_owned()).or_default();
108 if !read_raw_into_resources(&mut cur, values) {
109 return Err("value: fail read raw".to_owned());
110 }
111 } else if v_type == DataType::String as u8 {
112 match read_string_from_msgpack(&mut cur) {
113 Ok(res) => iraw.obj.add_string(&predicate, &res, Lang::NONE),
114 Err(e) => return Err(format!("value: expected {}, err={:?}", v_type, e)),
115 };
116 } else {
117 return Err(format!("msgpack:unknown type {}", v_type));
118 }
119 } else if size == 3 {
120 if v_type == DataType::Decimal as u8 {
121 match read_int(&mut cur) {
122 Ok(mantissa) => match read_int(&mut cur) {
123 Ok(exponent) => iraw.obj.add_decimal_d(&predicate, mantissa, exponent),
124 Err(e) => {
125 return Err(format!("value: fail read exponent, err={:?}", e));
126 }
127 },
128 Err(e) => return Err(format!("value: fail read mantissa, err={:?}", e)),
129 }
130 } else if v_type == DataType::String as u8 {
131 match read_string_from_msgpack(&mut cur) {
132 Ok(res) => {
133 let lang;
134 match read_int(&mut cur) {
135 Ok(res) => lang = Lang::new_from_i64(res),
136 Err(e) => {
137 return Err(format!("value: fail read lang, err={:?}", e));
138 }
139 }
140
141 iraw.obj.add_string(&predicate, &res, lang);
142 }
143 Err(e) => return Err(format!("value: expected {}, err={:?}", v_type, e)),
144 }
145 }
146 }
147 }
148 marker => return Err(format!("parsing values: unexpected marker={:?}", marker)),
149 },
150 Err(e) => return Err(format!("parsing values: err={:?}", e)),
151 }
152 }
153 }
154 Err(e) => return Err(format!("parsing {:?}", e)),
155 }
156
157 if is_found {
158 iraw.raw.cur = cur.position();
159 return Ok(());
160 }
161 }
162
163 iraw.raw.cur = cur.position();
164 Ok(())
165}
166
167fn read_raw_into_resources(cur: &mut Cursor<&[u8]>, values: &mut Vec<Resource>) -> bool {
168 let m_pos = cur.position();
169 let size: u32;
170
171 if let Ok(v) = read_marker(cur) {
172 match v {
173 Marker::FixStr(s) => {
174 size = u32::from(s);
175 cur.set_position(m_pos);
176 }
177 Marker::Str8 | Marker::Str16 | Marker::Str32 => {
178 cur.set_position(m_pos);
179
180 match read_str_len(cur) {
181 Ok(s) => size = s,
182 Err(e) => {
183 error!("fail read str len , err={:?}", e);
184 return false;
185 }
186 }
187 cur.set_position(m_pos);
188 }
189 _marker => return false,
190 }
191 } else {
192 return false;
193 }
194
195 let mut out = vec![0u8; size as usize];
196
197 match read_str(cur, &mut out) {
198 Ok(v) => {
199 values.push(Resource {
200 rtype: DataType::Binary,
201 order: 0,
202 value: Value::Binary(v.as_bytes().to_vec()),
203 });
204 true
205 }
206 Err(e) => {
207 if let DecodeStringError::InvalidUtf8(buf, _err) = e {
208 values.push(Resource {
209 rtype: DataType::Binary,
210 order: 0,
211 value: Value::Binary(buf.to_vec()),
212 });
213 return true;
214 }
215 false
216 }
217 }
218}
219
220fn read_string_from_msgpack(cur: &mut Cursor<&[u8]>) -> Result<String, i64> {
221 let m_pos = cur.position();
222 let size: u32;
223
224 if let Ok(v) = read_marker(cur) {
225 match v {
226 Marker::FixStr(s) => {
227 size = u32::from(s);
228 cur.set_position(m_pos);
229 }
230 Marker::Str8 | Marker::Str16 | Marker::Str32 => {
231 cur.set_position(m_pos);
232 match read_str_len(cur) {
233 Ok(s) => size = s,
234 Err(e) => {
235 error!("fail read str len , err={:?}", e);
236 return Err(-1);
237 }
238 }
239 cur.set_position(m_pos);
240 }
241 Marker::Null => {
242 return Ok("".to_string());
244 }
245 marker => {
246 error!("marker={:?}", marker);
247 return Err(-1);
248 }
249 }
250 } else {
251 return Err(-2);
252 }
253
254 let mut out = vec![0u8; size as usize];
255 match read_str(cur, &mut out) {
256 Ok(v) => Ok(v.to_string()),
257 Err(e) => {
258 if let DecodeStringError::InvalidUtf8(buf, _err) = e {
259 let res = String::from_utf8_lossy(buf);
260 return Ok(res.to_string());
261 }
262 error!("fail read str, err={:?}", e);
263 Err(-1)
264 }
265 }
266}