array_object/pack/
unpack.rs

1use crate::bitfield::*;
2use crate::error::ArrayObjectError;
3use crate::misc::Product;
4use crate::pack::unpack_float::*;
5use crate::pack::unpack_integer::*;
6use crate::pack::unpack_string::*;
7use crate::pack::varint::*;
8use crate::storage::*;
9
10/// Restore from binary.
11pub trait Unpack {
12    /// Restore ArrayObject from a binary data.
13    fn unpack(data: Vec<u8>) -> Result<Self, ArrayObjectError>
14    where
15        Self: Sized;
16}
17
18impl Unpack for ArrayObject {
19    fn unpack(mut data: Vec<u8>) -> Result<Self, ArrayObjectError> {
20        let (datatype, format, shape, shortdata) = read_footer(&mut data);
21        match datatype & TYPE_MASK {
22            SHORT_UNSIGNED_INTEGER => {
23                if !data.is_empty() {
24                    return Err(ArrayObjectError::UnableToDecode);
25                }
26                Ok(Self {
27                    data: shortdata.unwrap(),
28                    shape: vec![],
29                    datatype: DataType::UnsignedInteger,
30                })
31            }
32            SHORT_SIGNED_INTEGER => {
33                if !data.is_empty() {
34                    return Err(ArrayObjectError::UnableToDecode);
35                }
36                Ok(Self {
37                    data: shortdata.unwrap(),
38                    shape: vec![],
39                    datatype: DataType::SignedInteger,
40                })
41            }
42            UNSIGNED_INTEGER => {
43                let shape = shape.unwrap();
44                if format == VARIABLE_LENGTH {
45                    data = from_variable_integer(data);
46                } else {
47                    let total_len = shape.product();
48                    while (data.len() == 0 && total_len > 0)
49                        || (total_len == 1 && 2usize.pow(data.len().ilog2()) != data.len())
50                    {
51                        data.push(0);
52                    }
53                }
54                Ok(Self {
55                    data,
56                    shape,
57                    datatype: DataType::UnsignedInteger,
58                })
59            }
60            SIGNED_INTEGER => {
61                let shape = shape.unwrap();
62                if format == VARIABLE_LENGTH {
63                    data = from_variable_integer(data);
64                } else {
65                    let total_len = shape.product();
66                    while (data.len() == 0 && total_len > 0)
67                        || (total_len == 1 && 2usize.pow(data.len().ilog2()) != data.len())
68                    {
69                        data.push(0);
70                    }
71                }
72                Ok(Self {
73                    data,
74                    shape,
75                    datatype: DataType::SignedInteger,
76                })
77            }
78            REAL => {
79                if format == VARIABLE_LENGTH {
80                    data = from_variable_float(data);
81                }
82                Ok(Self {
83                    data,
84                    shape: shape.unwrap(),
85                    datatype: DataType::Real,
86                })
87            }
88            COMPLEX => {
89                if format == VARIABLE_LENGTH {
90                    data = from_variable_float(data);
91                }
92                Ok(Self {
93                    data,
94                    shape: shape.unwrap(),
95                    datatype: DataType::Complex,
96                })
97            }
98            STRING => {
99                if format == DICTIONARY {
100                    data = from_dictionary(data);
101                }
102                Ok(Self {
103                    data,
104                    shape: shape.unwrap(),
105                    datatype: DataType::String,
106                })
107            }
108            _ => {
109                return Err(ArrayObjectError::UnableToDecode);
110            }
111        }
112    }
113}
114
115fn read_footer(bytes: &mut Vec<u8>) -> (u8, u8, Option<Vec<u64>>, Option<Vec<u8>>) {
116    let last = bytes.pop().unwrap();
117    let ty = last & TYPE_MASK;
118    let format = last & FORMAT_MASK;
119    if ty == SHORT_UNSIGNED_INTEGER || ty == SHORT_SIGNED_INTEGER {
120        let data = last & SHORTDATA_MASK;
121        (ty, format, None, Some(vec![data]))
122    } else {
123        let dim = (last & DIMENSION_MASK) as usize;
124        let iter = bytes.iter().rev();
125        let (shape, len) = varint_decode(iter, dim);
126        bytes.truncate(bytes.len() - len);
127        (ty, format, Some(shape), None)
128    }
129}