Skip to main content

v_common_onto/
msgpack2individual.rs

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    // read individual URI
26    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                //cur.set_position(m_pos);
243                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}