1use crate::{Big, Endianness, General, Little, TdmsError, UnknownDataType};
2use std::io::{Read, Seek};
3
4#[derive(Debug, Copy, Clone, PartialEq)]
6pub enum TdmsDataType {
7 Void,
8 I8(usize),
9 I16(usize),
10 I32(usize),
11 I64(usize),
12 U8(usize),
13 U16(usize),
14 U32(usize),
15 U64(usize),
16 SingleFloat(usize),
17 DoubleFloat(usize),
18 ExtendedFloat(usize),
19 SingleFloatWithUnit(usize),
20 DoubleFloatWithUnit(usize),
21 ExtendedFloatWithUnit(usize),
22 String,
23 Boolean(usize),
24 TimeStamp(usize),
25 FixedPoint(usize),
26 ComplexSingleFloat(usize),
27 ComplexDoubleFloat(usize),
28 DAQmxRawData,
29}
30
31impl TryFrom<i32> for TdmsDataType {
32 type Error = TdmsError;
33
34 fn try_from(v: i32) -> Result<Self, TdmsError> {
35 match v {
36 x if x == 0 => Ok(TdmsDataType::Void),
37 x if x == 1 => Ok(TdmsDataType::I8(1)),
38 x if x == 2 => Ok(TdmsDataType::I16(2)),
39 x if x == 3 => Ok(TdmsDataType::I32(4)),
40 x if x == 4 => Ok(TdmsDataType::I64(8)),
41 x if x == 5 => Ok(TdmsDataType::U8(1)),
42 x if x == 6 => Ok(TdmsDataType::U16(2)),
43 x if x == 7 => Ok(TdmsDataType::U32(4)),
44 x if x == 8 => Ok(TdmsDataType::U64(8)),
45 x if x == 9 => Ok(TdmsDataType::SingleFloat(4)),
46 x if x == 10 => Ok(TdmsDataType::DoubleFloat(8)),
47 x if x == 11 => Ok(TdmsDataType::ExtendedFloat(10)),
48 x if x == 0x19 => Ok(TdmsDataType::SingleFloatWithUnit(4)),
49 x if x == 0x1a => Ok(TdmsDataType::DoubleFloatWithUnit(8)),
50 x if x == 0x1b => Ok(TdmsDataType::ExtendedFloatWithUnit(10)),
51 x if x == 0x20 => Ok(TdmsDataType::String),
52 x if x == 0x21 => Ok(TdmsDataType::Boolean(1)),
53 x if x == 0x44 => Ok(TdmsDataType::TimeStamp(16)),
54 x if x == 0x4f => Ok(TdmsDataType::FixedPoint(10)),
55 x if x == 0x08000c => Ok(TdmsDataType::ComplexSingleFloat(4)),
56 x if x == 0x10000d => Ok(TdmsDataType::ComplexDoubleFloat(8)),
57 x if x == -1 => Ok(TdmsDataType::DAQmxRawData), _ => Err(UnknownDataType()),
59 }
60 }
61}
62
63impl TdmsDataType {
64 pub fn get_size(data_type: TdmsDataType) -> usize {
65 return match data_type {
66 TdmsDataType::Void => 0,
67 TdmsDataType::I8(v) => v,
68 TdmsDataType::I16(v) => v,
69 TdmsDataType::I32(v) => v,
70 TdmsDataType::I64(v) => v,
71 TdmsDataType::U8(v) => v,
72 TdmsDataType::U16(v) => v,
73 TdmsDataType::U32(v) => v,
74 TdmsDataType::U64(v) => v,
75 TdmsDataType::SingleFloat(v) => v,
76 TdmsDataType::DoubleFloat(v) => v,
77 TdmsDataType::ExtendedFloat(v) => v,
78 TdmsDataType::SingleFloatWithUnit(v) => v,
79 TdmsDataType::DoubleFloatWithUnit(v) => v,
80 TdmsDataType::ExtendedFloatWithUnit(v) => v,
81 TdmsDataType::String => 0,
82 TdmsDataType::Boolean(v) => v,
83 TdmsDataType::TimeStamp(v) => v,
84 TdmsDataType::FixedPoint(v) => v,
85 TdmsDataType::ComplexSingleFloat(v) => v,
86 TdmsDataType::ComplexDoubleFloat(v) => v,
87 TdmsDataType::DAQmxRawData => 0,
88 };
89 }
90}
91
92#[derive(Debug, Clone)]
93pub struct TDMSValue {
97 pub data_type: TdmsDataType,
98 pub endianness: Endianness,
99 pub value: Option<Vec<u8>>,
100}
101
102impl TDMSValue {
103 pub fn from_reader<R: Read + Seek>(
106 endianness: Endianness,
107 data_type: TdmsDataType,
108 r: &mut R,
109 ) -> Result<Self, TdmsError> {
110 return match data_type {
111 TdmsDataType::Void => Ok(TDMSValue {
112 data_type,
113 endianness,
114 value: None,
115 }),
116 TdmsDataType::I8(_) => {
117 let mut buf: [u8; 1] = [0; 1];
118 r.read_exact(&mut buf)?;
119
120 Ok(TDMSValue {
121 data_type,
122 endianness,
123 value: Some(buf.to_vec()),
124 })
125 }
126 TdmsDataType::I16(_) => {
127 let mut buf: [u8; 2] = [0; 2];
128 r.read_exact(&mut buf)?;
129
130 Ok(TDMSValue {
131 data_type,
132 endianness,
133 value: Some(buf.to_vec()),
134 })
135 }
136 TdmsDataType::I32(_) => {
137 let mut buf: [u8; 4] = [0; 4];
138 r.read_exact(&mut buf)?;
139
140 Ok(TDMSValue {
141 data_type,
142 endianness,
143 value: Some(buf.to_vec()),
144 })
145 }
146 TdmsDataType::I64(_) => {
147 let mut buf: [u8; 8] = [0; 8];
148 r.read_exact(&mut buf)?;
149
150 Ok(TDMSValue {
151 data_type,
152 endianness,
153 value: Some(buf.to_vec()),
154 })
155 }
156 TdmsDataType::U8(_) => {
157 let mut buf: [u8; 1] = [0; 1];
158 r.read_exact(&mut buf)?;
159
160 Ok(TDMSValue {
161 data_type,
162 endianness,
163 value: Some(buf.to_vec()),
164 })
165 }
166 TdmsDataType::U16(_) => {
167 let mut buf: [u8; 2] = [0; 2];
168 r.read_exact(&mut buf)?;
169
170 Ok(TDMSValue {
171 data_type,
172 endianness,
173 value: Some(buf.to_vec()),
174 })
175 }
176 TdmsDataType::U32(_) => {
177 let mut buf: [u8; 4] = [0; 4];
178 r.read_exact(&mut buf)?;
179
180 Ok(TDMSValue {
181 data_type,
182 endianness,
183 value: Some(buf.to_vec()),
184 })
185 }
186 TdmsDataType::U64(_) => {
187 let mut buf: [u8; 8] = [0; 8];
188 r.read_exact(&mut buf)?;
189
190 Ok(TDMSValue {
191 data_type,
192 endianness,
193 value: Some(buf.to_vec()),
194 })
195 }
196 TdmsDataType::SingleFloat(_) => {
197 let mut buf: [u8; 4] = [0; 4];
198 r.read_exact(&mut buf)?;
199
200 Ok(TDMSValue {
201 data_type,
202 endianness,
203 value: Some(buf.to_vec()),
204 })
205 }
206 TdmsDataType::DoubleFloat(_) => {
207 let mut buf: [u8; 8] = [0; 8];
208 r.read_exact(&mut buf)?;
209
210 Ok(TDMSValue {
211 data_type,
212 endianness,
213 value: Some(buf.to_vec()),
214 })
215 }
216 TdmsDataType::ExtendedFloat(_) => {
217 let mut buf: [u8; 10] = [0; 10];
218 r.read_exact(&mut buf)?;
219
220 Ok(TDMSValue {
221 data_type,
222 endianness,
223 value: Some(buf.to_vec()),
224 })
225 }
226 TdmsDataType::SingleFloatWithUnit(_) => {
227 let mut buf: [u8; 4] = [0; 4];
228 r.read_exact(&mut buf)?;
229
230 Ok(TDMSValue {
231 data_type,
232 endianness,
233 value: Some(buf.to_vec()),
234 })
235 }
236 TdmsDataType::DoubleFloatWithUnit(_) => {
237 let mut buf: [u8; 8] = [0; 8];
238 r.read_exact(&mut buf)?;
239
240 Ok(TDMSValue {
241 data_type,
242 endianness,
243 value: Some(buf.to_vec()),
244 })
245 }
246 TdmsDataType::ExtendedFloatWithUnit(_) => {
247 let mut buf: [u8; 10] = [0; 10];
248 r.read_exact(&mut buf)?;
249
250 Ok(TDMSValue {
251 data_type,
252 endianness,
253 value: Some(buf.to_vec()),
254 })
255 }
256 TdmsDataType::String => {
257 let mut buf: [u8; 4] = [0; 4];
258 r.read_exact(&mut buf)?;
259
260 let length: u32 = match endianness {
261 Little => u32::from_le_bytes(buf),
262 Big => u32::from_be_bytes(buf),
263 };
264
265 let length = match usize::try_from(length) {
267 Ok(l) => l,
268 Err(_) => {
269 return Err(General(String::from(
270 "error converting strength length to system size",
271 )))
272 }
273 };
274
275 let mut value = vec![0; length];
276 r.read_exact(&mut value)?;
277
278 Ok(TDMSValue {
279 data_type,
280 endianness,
281 value: Some(value),
282 })
283 }
284 TdmsDataType::Boolean(_) => {
285 let mut buf: [u8; 1] = [0; 1];
286 r.read_exact(&mut buf)?;
287
288 Ok(TDMSValue {
289 data_type,
290 endianness,
291 value: Some(buf.to_vec()),
292 })
293 }
294 TdmsDataType::TimeStamp(_) => {
295 let mut buf: [u8; 16] = [0; 16];
296 r.read_exact(&mut buf)?;
297
298 Ok(TDMSValue {
299 data_type,
300 endianness,
301 value: Some(buf.to_vec()),
302 })
303 }
304 TdmsDataType::FixedPoint(_) => {
307 let mut buf: [u8; 10] = [0; 10];
308 r.read_exact(&mut buf)?;
309
310 Ok(TDMSValue {
311 data_type,
312 endianness,
313 value: Some(buf.to_vec()),
314 })
315 }
316 TdmsDataType::ComplexSingleFloat(_) => {
317 let mut buf: [u8; 8] = [0; 8];
318 r.read_exact(&mut buf)?;
319
320 Ok(TDMSValue {
321 data_type,
322 endianness,
323 value: Some(buf.to_vec()),
324 })
325 }
326 TdmsDataType::ComplexDoubleFloat(_) => {
327 let mut buf: [u8; 16] = [0; 16];
328 r.read_exact(&mut buf)?;
329
330 Ok(TDMSValue {
331 data_type,
332 endianness,
333 value: Some(buf.to_vec()),
334 })
335 }
336 TdmsDataType::DAQmxRawData => {
337 let mut buf: [u8; 8] = [0; 8];
338 r.read_exact(&mut buf)?;
339
340 Ok(TDMSValue {
341 data_type,
342 endianness,
343 value: Some(buf.to_vec()),
344 })
345 }
346 };
347 }
348}
349
350#[derive(Clone, Debug, Copy)]
351pub struct TdmsTimestamp(pub i64, pub u64);