array_object/pack/
pack.rs

1use 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
9/// Convert into binary.
10pub trait Pack {
11    /// Compress the data and create a binary object.
12    fn pack(self) -> Vec<u8>;
13    /// Create a binary object without compression.
14    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}