array_object/pack/
pack.rs1use crate::bitfield::*;
2use crate::misc::Product;
3use crate::pack::pack_float::*;
4use crate::pack::pack_integer::*;
5use crate::pack::pack_string::*;
6use crate::pack::varint::*;
7use crate::storage::*;
8
9pub trait Pack {
11 fn pack(self) -> Vec<u8>;
13 fn pack_as_it_is(self) -> Vec<u8>;
15}
16
17impl Pack for ArrayObject {
18 fn pack(self) -> Vec<u8> {
19 match self.datatype {
20 DataType::UnsignedInteger => {
21 let len = self.shape.product();
22 if len == 0 {
23 let mut data = vec![];
24 let datatype = UNSIGNED_INTEGER | FIXED_LENGTH | self.shape.len() as u8;
25 write_footer(&mut data, datatype, self.shape);
26 return data;
27 }
28 let size_orig = self.data.len() / len as usize;
29 match inspect_integer(&self.data, size_orig, &self.shape) {
30 IntegerPackingOption::FixedLength(size_new) => {
31 let mut data = into_fixed_integer(self.data, size_orig, size_new);
32 let datatype = UNSIGNED_INTEGER | FIXED_LENGTH | self.shape.len() as u8;
33 write_footer(&mut data, datatype, self.shape);
34 data
35 }
36 IntegerPackingOption::VariableLength(total_len) => {
37 let mut data = into_variable_integer(self.data, size_orig, total_len);
38 let datatype = UNSIGNED_INTEGER | VARIABLE_LENGTH | self.shape.len() as u8;
39 write_footer(&mut data, datatype, self.shape);
40 data
41 }
42 IntegerPackingOption::Short => {
43 let mut data = vec![];
44 let datatype = SHORT_UNSIGNED_INTEGER | self.data[0];
45 write_footer(&mut data, datatype, self.shape);
46 data
47 }
48 IntegerPackingOption::ShortVariable => {
49 let mut data = into_short_variable_integer(self.data);
50 let datatype = UNSIGNED_INTEGER | FIXED_LENGTH | self.shape.len() as u8;
51 write_footer(&mut data, datatype, self.shape);
52 data
53 }
54 IntegerPackingOption::None => {
55 let mut data = self.data;
56 let datatype = UNSIGNED_INTEGER | FIXED_LENGTH | self.shape.len() as u8;
57 write_footer(&mut data, datatype, self.shape);
58 data
59 }
60 }
61 }
62 DataType::SignedInteger => {
63 let len = self.shape.product();
64 if len == 0 {
65 let mut data = vec![];
66 let datatype = SIGNED_INTEGER | FIXED_LENGTH | self.shape.len() as u8;
67 write_footer(&mut data, datatype, self.shape);
68 return data;
69 }
70 let size_orig = self.data.len() / len as usize;
71 match inspect_integer(&self.data, size_orig, &self.shape) {
72 IntegerPackingOption::FixedLength(size_new) => {
73 let mut data = into_fixed_integer(self.data, size_orig, size_new);
74 let datatype = SIGNED_INTEGER | FIXED_LENGTH | self.shape.len() as u8;
75 write_footer(&mut data, datatype, self.shape);
76 data
77 }
78 IntegerPackingOption::VariableLength(total_len) => {
79 let mut data = into_variable_integer(self.data, size_orig, total_len);
80 let datatype = SIGNED_INTEGER | VARIABLE_LENGTH | self.shape.len() as u8;
81 write_footer(&mut data, datatype, self.shape);
82 data
83 }
84 IntegerPackingOption::Short => {
85 let mut data = vec![];
86 let datatype = SHORT_SIGNED_INTEGER | self.data[0];
87 write_footer(&mut data, datatype, self.shape);
88 data
89 }
90 IntegerPackingOption::ShortVariable => {
91 let mut data = into_short_variable_integer(self.data);
92 let datatype = SIGNED_INTEGER | FIXED_LENGTH | self.shape.len() as u8;
93 write_footer(&mut data, datatype, self.shape);
94 data
95 }
96 IntegerPackingOption::None => {
97 let mut data = self.data;
98 let datatype = SIGNED_INTEGER | FIXED_LENGTH | self.shape.len() as u8;
99 write_footer(&mut data, datatype, self.shape);
100 data
101 }
102 }
103 }
104 DataType::Real => {
105 let len = self.shape.product();
106 if len == 0 {
107 let mut data = vec![];
108 let datatype = REAL | FIXED_LENGTH | self.shape.len() as u8;
109 write_footer(&mut data, datatype, self.shape);
110 return data;
111 }
112 let size_orig = self.data.len() / len as usize;
113 match inspect_float(&self.data, size_orig) {
114 FloatPackingOption::FixedLength(size_new) => {
115 let mut data = into_fixed_float(self.data, size_orig, size_new);
116 let datatype = REAL | FIXED_LENGTH | self.shape.len() as u8;
117 write_footer(&mut data, datatype, self.shape);
118 data
119 }
120 FloatPackingOption::VariableLength(total_len) => {
121 let mut data = into_variable_float(self.data, size_orig, total_len);
122 let datatype = REAL | VARIABLE_LENGTH | self.shape.len() as u8;
123 write_footer(&mut data, datatype, self.shape);
124 data
125 }
126 FloatPackingOption::None => {
127 let mut data = self.data;
128 let datatype = REAL | FIXED_LENGTH | self.shape.len() as u8;
129 write_footer(&mut data, datatype, self.shape);
130 data
131 }
132 }
133 }
134 DataType::Complex => {
135 let len = self.shape.product();
136 if len == 0 {
137 let mut data = vec![];
138 let datatype = COMPLEX | FIXED_LENGTH | self.shape.len() as u8;
139 write_footer(&mut data, datatype, self.shape);
140 return data;
141 }
142 let size_orig = self.data.len() / len as usize / 2;
143 match inspect_float(&self.data, size_orig) {
144 FloatPackingOption::FixedLength(size_new) => {
145 let mut data = into_fixed_float(self.data, size_orig, size_new);
146 let datatype = COMPLEX | FIXED_LENGTH | self.shape.len() as u8;
147 write_footer(&mut data, datatype, self.shape);
148 data
149 }
150 FloatPackingOption::VariableLength(total_len) => {
151 let mut data = into_variable_float(self.data, size_orig, total_len);
152 let datatype = COMPLEX | VARIABLE_LENGTH | self.shape.len() as u8;
153 write_footer(&mut data, datatype, self.shape);
154 data
155 }
156 FloatPackingOption::None => {
157 let mut data = self.data;
158 let datatype = COMPLEX | FIXED_LENGTH | self.shape.len() as u8;
159 write_footer(&mut data, datatype, self.shape);
160 data
161 }
162 }
163 }
164 DataType::String => match inspect_string(&self.data, &self.shape) {
165 StringPackingOption::Dictionary(dic) => {
166 let mut data = into_dictionary(self.data, dic);
167 let datatype = STRING | DICTIONARY | self.shape.len() as u8;
168 write_footer(&mut data, datatype, self.shape);
169 data
170 }
171 StringPackingOption::None => {
172 let mut data = self.data;
173 let datatype = STRING | JOINED | self.shape.len() as u8;
174 write_footer(&mut data, datatype, self.shape);
175 data
176 }
177 },
178 }
179 }
180 fn pack_as_it_is(self) -> Vec<u8> {
181 match self.datatype {
182 DataType::UnsignedInteger => {
183 let mut data = self.data;
184 let datatype = UNSIGNED_INTEGER | FIXED_LENGTH | self.shape.len() as u8;
185 write_footer(&mut data, datatype, self.shape);
186 data
187 }
188 DataType::SignedInteger => {
189 let mut data = self.data;
190 let datatype = SIGNED_INTEGER | FIXED_LENGTH | self.shape.len() as u8;
191 write_footer(&mut data, datatype, self.shape);
192 data
193 }
194 DataType::Real => {
195 let mut data = self.data;
196 let datatype = REAL | FIXED_LENGTH | self.shape.len() as u8;
197 write_footer(&mut data, datatype, self.shape);
198 data
199 }
200 DataType::Complex => {
201 let mut data = self.data;
202 let datatype = COMPLEX | FIXED_LENGTH | self.shape.len() as u8;
203 write_footer(&mut data, datatype, self.shape);
204 data
205 }
206 DataType::String => {
207 let mut data = self.data;
208 let datatype = STRING | JOINED | self.shape.len() as u8;
209 write_footer(&mut data, datatype, self.shape);
210 data
211 }
212 }
213 }
214}
215
216fn write_footer(data: &mut Vec<u8>, datatype: u8, shape: Vec<u64>) {
217 let mut footer = [vec![datatype], varint_encode(shape)].concat();
218 footer.reverse();
219 data.append(&mut footer);
220}