array_object/pack/
unpack.rs1use 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
10pub trait Unpack {
12 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}