1 //
2 // Copyright (c) 2016 KAMADA Ken'ichi.
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions
7 // are met:
8 // 1. Redistributions of source code must retain the above copyright
9 //    notice, this list of conditions and the following disclaimer.
10 // 2. Redistributions in binary form must reproduce the above copyright
11 //    notice, this list of conditions and the following disclaimer in the
12 //    documentation and/or other materials provided with the distribution.
13 //
14 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 // ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 // SUCH DAMAGE.
25 //
26 
27 use std::fmt;
28 use std::fmt::Write as _;
29 
30 use crate::endian::Endian;
31 
32 /// A type and values of a TIFF/Exif field.
33 #[derive(Clone)]
34 pub enum Value {
35     /// Vector of 8-bit unsigned integers.
36     Byte(Vec<u8>),
37     /// Vector of slices of 8-bit bytes containing 7-bit ASCII characters.
38     /// The trailing null characters are not included.  Note that
39     /// the 8th bits may present if a non-conforming data is given.
40     Ascii(Vec<Vec<u8>>),
41     /// Vector of 16-bit unsigned integers.
42     Short(Vec<u16>),
43     /// Vector of 32-bit unsigned integers.
44     Long(Vec<u32>),
45     /// Vector of unsigned rationals.
46     /// An unsigned rational number is a pair of 32-bit unsigned integers.
47     Rational(Vec<Rational>),
48     /// Vector of 8-bit signed integers.  Unused in the Exif specification.
49     SByte(Vec<i8>),
50     /// Slice of 8-bit bytes.
51     ///
52     /// The second member keeps the offset of the value in the Exif data.
53     /// The interpretation of the value does not generally depend on
54     /// the location, but if it does, the offset information helps.
55     /// When encoding Exif, it is ignored.
56     Undefined(Vec<u8>, u32),
57     /// Vector of 16-bit signed integers.  Unused in the Exif specification.
58     SShort(Vec<i16>),
59     /// Vector of 32-bit signed integers.
60     SLong(Vec<i32>),
61     /// Vector of signed rationals.
62     /// A signed rational number is a pair of 32-bit signed integers.
63     SRational(Vec<SRational>),
64     /// Vector of 32-bit (single precision) floating-point numbers.
65     /// Unused in the Exif specification.
66     Float(Vec<f32>),
67     /// Vector of 64-bit (double precision) floating-point numbers.
68     /// Unused in the Exif specification.
69     Double(Vec<f64>),
70     /// The type is unknown to this implementation.
71     /// The associated values are the type, the count, and the
72     /// offset of the "Value Offset" element.
73     Unknown(u16, u32, u32),
74 }
75 
76 impl Value {
77     /// Returns an object that implements `std::fmt::Display` for
78     /// printing a value in a tag-specific format.
79     /// The tag of the value is specified as the argument.
80     ///
81     /// If you want to display with the unit, use `Field::display_value`.
82     ///
83     /// # Examples
84     ///
85     /// ```
86     /// use exif::{Value, Tag};
87     /// let val = Value::Undefined(b"0231".to_vec(), 0);
88     /// assert_eq!(val.display_as(Tag::ExifVersion).to_string(), "2.31");
89     /// let val = Value::Short(vec![2]);
90     /// assert_eq!(val.display_as(Tag::ResolutionUnit).to_string(), "inch");
91     /// ```
92     #[inline]
93     pub fn display_as(&self, tag: crate::tag::Tag) -> Display {
94         crate::tag::display_value_as(self, tag)
95     }
96 
97     /// Returns the value as a slice if the type is BYTE.
98     #[inline]
99     pub(crate) fn byte(&self) -> Option<&[u8]> {
100         match *self {
101             Value::Byte(ref v) => Some(v),
102             _ => None,
103         }
104     }
105 
106     /// Returns the value as `AsciiValues` if the type is ASCII.
107     #[inline]
108     pub(crate) fn ascii(&self) -> Option<AsciiValues> {
109         match *self {
110             Value::Ascii(ref v) => Some(AsciiValues(v)),
111             _ => None,
112         }
113     }
114 
115     /// Returns the value as a slice if the type is RATIONAL.
116     #[inline]
117     pub(crate) fn rational(&self) -> Option<&[Rational]> {
118         match *self {
119             Value::Rational(ref v) => Some(v),
120             _ => None,
121         }
122     }
123 
124     /// Returns the value as a slice if the type is UNDEFINED.
125     #[inline]
126     pub(crate) fn undefined(&self) -> Option<&[u8]> {
127         match *self {
128             Value::Undefined(ref v, _) => Some(v),
129             _ => None,
130         }
131     }
132 
133     /// Returns the unsigned integer at the given position.
134     /// None is returned if the value type is not unsigned integer
135     /// (BYTE, SHORT, or LONG) or the position is out of bounds.
136     pub fn get_uint(&self, index: usize) -> Option<u32> {
137         match *self {
138             Value::Byte(ref v) if v.len() > index => Some(v[index] as u32),
139             Value::Short(ref v) if v.len() > index => Some(v[index] as u32),
140             Value::Long(ref v) if v.len() > index => Some(v[index]),
141             _ => None,
142         }
143     }
144 
145     /// Returns an iterator over the unsigned integers (BYTE, SHORT, or LONG).
146     /// The iterator yields `u32` regardless of the underlying integer size.
147     /// The returned iterator implements `Iterator` and `ExactSizeIterator`
148     /// traits.
149     /// `None` is returned if the value is not an unsigned integer type.
150     #[inline]
151     pub fn iter_uint(&self) -> Option<UIntIter> {
152         match *self {
153             Value::Byte(ref v) =>
154                 Some(UIntIter { iter: Box::new(v.iter().map(|&x| x as u32)) }),
155             Value::Short(ref v) =>
156                 Some(UIntIter { iter: Box::new(v.iter().map(|&x| x as u32)) }),
157             Value::Long(ref v) =>
158                 Some(UIntIter { iter: Box::new(v.iter().map(|&x| x)) }),
159             _ => None,
160         }
161     }
162 }
163 
164 pub struct AsciiValues<'a>(&'a [Vec<u8>]);
165 
166 impl<'a> AsciiValues<'a> {
167     pub fn first(&self) -> Option<&'a [u8]> {
168         self.0.first().map(|x| &x[..])
169     }
170 }
171 
172 // A struct that wraps std::slice::Iter<'a, u8/u16/u32>.
173 pub struct UIntIter<'a> {
174     iter: Box<dyn ExactSizeIterator<Item=u32> + 'a>
175 }
176 
177 impl<'a> Iterator for UIntIter<'a> {
178     type Item = u32;
179 
180     #[inline]
181     fn next(&mut self) -> Option<u32> {
182         self.iter.next()
183     }
184 
185     #[inline]
186     fn size_hint(&self) -> (usize, Option<usize>) {
187         self.iter.size_hint()
188     }
189 }
190 
191 impl<'a> ExactSizeIterator for UIntIter<'a> {}
192 
193 /// Helper struct for printing a value in a tag-specific format.
194 #[derive(Copy, Clone)]
195 pub struct Display<'a> {
196     pub fmt: fn(&mut dyn fmt::Write, &Value) -> fmt::Result,
197     pub value: &'a Value,
198 }
199 
200 impl<'a> fmt::Display for Display<'a> {
201     #[inline]
202     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
203         (self.fmt)(f, self.value)
204     }
205 }
206 
207 impl fmt::Debug for Value {
208     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
209         match self {
210             Self::Byte(v) => f.debug_tuple("Byte").field(v).finish(),
211             Self::Ascii(v) => f.debug_tuple("Ascii")
212                 .field(&IterDebugAdapter(
213                     || v.iter().map(|x| AsciiDebugAdapter(x)))).finish(),
214             Self::Short(v) => f.debug_tuple("Short").field(v).finish(),
215             Self::Long(v) => f.debug_tuple("Long").field(v).finish(),
216             Self::Rational(v) => f.debug_tuple("Rational").field(v).finish(),
217             Self::SByte(v) => f.debug_tuple("SByte").field(v).finish(),
218             Self::Undefined(v, o) => f.debug_tuple("Undefined")
219                 .field(&HexDebugAdapter(v))
220                 .field(&format_args!("ofs={:#x}", o)).finish(),
221             Self::SShort(v) => f.debug_tuple("SShort").field(v).finish(),
222             Self::SLong(v) => f.debug_tuple("SLong").field(v).finish(),
223             Self::SRational(v) => f.debug_tuple("SRational").field(v).finish(),
224             Self::Float(v) => f.debug_tuple("Float").field(v).finish(),
225             Self::Double(v) => f.debug_tuple("Double").field(v).finish(),
226             Self::Unknown(t, c, oo) => f.debug_tuple("Unknown")
227                 .field(&format_args!("typ={}", t))
228                 .field(&format_args!("cnt={}", c))
229                 .field(&format_args!("ofs={:#x}", oo)).finish(),
230         }
231     }
232 }
233 
234 struct IterDebugAdapter<F>(F);
235 
236 impl<F, T, I> fmt::Debug for IterDebugAdapter<F>
237 where F: Fn() -> T, T: Iterator<Item = I>, I: fmt::Debug {
238     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
239         f.debug_list().entries(self.0()).finish()
240     }
241 }
242 
243 struct AsciiDebugAdapter<'a>(&'a [u8]);
244 
245 impl<'a> fmt::Debug for AsciiDebugAdapter<'a> {
246     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
247         f.write_char('"')?;
248         self.0.iter().try_for_each(|&c| match c {
249             b'\\' | b'"' => write!(f, "\\{}", c as char),
250             0x20..=0x7e => f.write_char(c as char),
251             _ => write!(f, "\\x{:02x}", c),
252         })?;
253         f.write_char('"')
254     }
255 }
256 
257 struct HexDebugAdapter<'a>(&'a [u8]);
258 
259 impl<'a> fmt::Debug for HexDebugAdapter<'a> {
260     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
261         f.write_str("0x")?;
262         self.0.iter().try_for_each(|x| write!(f, "{:02x}", x))
263     }
264 }
265 
266 // Static default values.
267 pub enum DefaultValue {
268     None,
269     Byte(&'static [u8]),
270     Ascii(&'static [&'static [u8]]),
271     Short(&'static [u16]),
272     Rational(&'static [(u32, u32)]),
273     Undefined(&'static [u8]),
274     // Depends on other tags, JPEG markers, etc.
275     ContextDependent,
276     // Unspecified in the Exif standard.
277     Unspecified,
278 }
279 
280 impl From<&DefaultValue> for Option<Value> {
281     fn from(defval: &DefaultValue) -> Option<Value> {
282         match *defval {
283             DefaultValue::None => None,
284             DefaultValue::Byte(s) => Some(Value::Byte(s.to_vec())),
285             DefaultValue::Ascii(s) => Some(Value::Ascii(
286                 s.iter().map(|&x| x.to_vec()).collect())),
287             DefaultValue::Short(s) => Some(Value::Short(s.to_vec())),
288             DefaultValue::Rational(s) => Some(Value::Rational(
289                 s.iter().map(|&x| x.into()).collect())),
290             DefaultValue::Undefined(s) => Some(Value::Undefined(
291                 s.to_vec(), 0)),
292             DefaultValue::ContextDependent => None,
293             DefaultValue::Unspecified => None,
294         }
295     }
296 }
297 
298 /// An unsigned rational number, which is a pair of 32-bit unsigned integers.
299 #[derive(Copy, Clone)]
300 pub struct Rational { pub num: u32, pub denom: u32 }
301 
302 impl Rational {
303     /// Converts the value to an f64.
304     #[inline]
305     pub fn to_f64(&self) -> f64 {
306         self.num as f64 / self.denom as f64
307     }
308 }
309 
310 impl From<(u32, u32)> for Rational {
311     fn from(t: (u32, u32)) -> Rational {
312         Rational { num: t.0, denom: t.1 }
313     }
314 }
315 
316 impl fmt::Debug for Rational {
317     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
318         write!(f, "Rational({}/{})", self.num, self.denom)
319     }
320 }
321 
322 impl fmt::Display for Rational {
323     /// Formatting parameters other than width are not supported.
324     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
325         let buf = fmt_rational_sub(f, self.num, self.denom);
326         f.pad_integral(true, "", &buf)
327     }
328 }
329 
330 impl From<Rational> for f64 {
331     #[inline]
332     fn from(r: Rational) -> f64 { r.to_f64() }
333 }
334 
335 impl From<Rational> for f32 {
336     #[inline]
337     fn from(r: Rational) -> f32 { r.to_f64() as f32 }
338 }
339 
340 /// A signed rational number, which is a pair of 32-bit signed integers.
341 #[derive(Copy, Clone)]
342 pub struct SRational { pub num: i32, pub denom: i32 }
343 
344 impl SRational {
345     /// Converts the value to an f64.
346     #[inline]
347     pub fn to_f64(&self) -> f64 {
348         self.num as f64 / self.denom as f64
349     }
350 }
351 
352 impl From<(i32, i32)> for SRational {
353     fn from(t: (i32, i32)) -> SRational {
354         SRational { num: t.0, denom: t.1 }
355     }
356 }
357 
358 impl fmt::Debug for SRational {
359     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
360         write!(f, "SRational({}/{})", self.num, self.denom)
361     }
362 }
363 
364 impl fmt::Display for SRational {
365     /// Formatting parameters other than width are not supported.
366     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
367         let buf = fmt_rational_sub(
368             f, self.num.wrapping_abs() as u32, self.denom);
369         f.pad_integral(self.num >= 0, "", &buf)
370     }
371 }
372 
373 impl From<SRational> for f64 {
374     #[inline]
375     fn from(r: SRational) -> f64 { r.to_f64() }
376 }
377 
378 impl From<SRational> for f32 {
379     #[inline]
380     fn from(r: SRational) -> f32 { r.to_f64() as f32 }
381 }
382 
383 // Only u32 or i32 are expected for T.
384 fn fmt_rational_sub<T>(f: &mut fmt::Formatter, num: u32, denom: T)
385                        -> String where T: fmt::Display {
386     // The API to get the alignment is not yet stable as of Rust 1.16,
387     // so it is not fully supported.
388     match (f.sign_plus(), f.precision(), f.sign_aware_zero_pad()) {
389         (true, Some(prec), true) =>
390             format!("{}/{:+0w$}", num, denom, w = prec),
391         (true, Some(prec), false) =>
392             format!("{}/{:+w$}", num, denom, w = prec),
393         (true, None, _) =>
394             format!("{}/{:+}", num, denom),
395         (false, Some(prec), true) =>
396             format!("{}/{:0w$}", num, denom, w = prec),
397         (false, Some(prec), false) =>
398             format!("{}/{:w$}", num, denom, w = prec),
399         (false, None, _) =>
400             format!("{}/{}", num, denom),
401     }
402 }
403 
404 type Parser = fn(&[u8], usize, usize) -> Value;
405 
406 // Return the length of a single value and the parser of the type.
407 pub fn get_type_info<E>(typecode: u16) -> (usize, Parser) where E: Endian {
408     match typecode {
409         1 => (1, parse_byte),
410         2 => (1, parse_ascii),
411         3 => (2, parse_short::<E>),
412         4 => (4, parse_long::<E>),
413         5 => (8, parse_rational::<E>),
414         6 => (1, parse_sbyte),
415         7 => (1, parse_undefined),
416         8 => (2, parse_sshort::<E>),
417         9 => (4, parse_slong::<E>),
418         10 => (8, parse_srational::<E>),
419         11 => (4, parse_float::<E>),
420         12 => (8, parse_double::<E>),
421         _ => (0, parse_unknown),
422     }
423 }
424 
425 fn parse_byte(data: &[u8], offset: usize, count: usize) -> Value {
426     Value::Byte(data[offset .. offset + count].to_vec())
427 }
428 
429 fn parse_ascii(data: &[u8], offset: usize, count: usize) -> Value {
430     // Any ASCII field can contain multiple strings [TIFF6 Image File
431     // Directory].
432     let iter = (&data[offset .. offset + count]).split(|&b| b == b'\0');
433     let mut v: Vec<Vec<u8>> = iter.map(|x| x.to_vec()).collect();
434     if v.last().map_or(false, |x| x.len() == 0) {
435         v.pop();
436     }
437     Value::Ascii(v)
438 }
439 
440 fn parse_short<E>(data: &[u8], offset: usize, count: usize)
441                   -> Value where E: Endian {
442     let mut val = Vec::with_capacity(count);
443     for i in 0..count {
444         val.push(E::loadu16(data, offset + i * 2));
445     }
446     Value::Short(val)
447 }
448 
449 fn parse_long<E>(data: &[u8], offset: usize, count: usize)
450                  -> Value where E: Endian {
451     let mut val = Vec::with_capacity(count);
452     for i in 0..count {
453         val.push(E::loadu32(data, offset + i * 4));
454     }
455     Value::Long(val)
456 }
457 
458 fn parse_rational<E>(data: &[u8], offset: usize, count: usize)
459                      -> Value where E: Endian {
460     let mut val = Vec::with_capacity(count);
461     for i in 0..count {
462         val.push(Rational {
463             num: E::loadu32(data, offset + i * 8),
464             denom: E::loadu32(data, offset + i * 8 + 4),
465         });
466     }
467     Value::Rational(val)
468 }
469 
470 fn parse_sbyte(data: &[u8], offset: usize, count: usize) -> Value {
471     let bytes = data[offset .. offset + count].iter()
472         .map(|x| *x as i8).collect();
473     Value::SByte(bytes)
474 }
475 
476 fn parse_undefined(data: &[u8], offset: usize, count: usize) -> Value {
477     Value::Undefined(data[offset .. offset + count].to_vec(), offset as u32)
478 }
479 
480 fn parse_sshort<E>(data: &[u8], offset: usize, count: usize)
481                    -> Value where E: Endian {
482     let mut val = Vec::with_capacity(count);
483     for i in 0..count {
484         val.push(E::loadu16(data, offset + i * 2) as i16);
485     }
486     Value::SShort(val)
487 }
488 
489 fn parse_slong<E>(data: &[u8], offset: usize, count: usize)
490                   -> Value where E: Endian {
491     let mut val = Vec::with_capacity(count);
492     for i in 0..count {
493         val.push(E::loadu32(data, offset + i * 4) as i32);
494     }
495     Value::SLong(val)
496 }
497 
498 fn parse_srational<E>(data: &[u8], offset: usize, count: usize)
499                       -> Value where E: Endian {
500     let mut val = Vec::with_capacity(count);
501     for i in 0..count {
502         val.push(SRational {
503             num: E::loadu32(data, offset + i * 8) as i32,
504             denom: E::loadu32(data, offset + i * 8 + 4) as i32,
505         });
506     }
507     Value::SRational(val)
508 }
509 
510 // TIFF and Rust use IEEE 754 format, so no conversion is required.
511 fn parse_float<E>(data: &[u8], offset: usize, count: usize)
512                   -> Value where E: Endian {
513     let mut val = Vec::with_capacity(count);
514     for i in 0..count {
515         val.push(f32::from_bits(E::loadu32(data, offset + i * 4)));
516     }
517     Value::Float(val)
518 }
519 
520 // TIFF and Rust use IEEE 754 format, so no conversion is required.
521 fn parse_double<E>(data: &[u8], offset: usize, count: usize)
522                    -> Value where E: Endian {
523     let mut val = Vec::with_capacity(count);
524     for i in 0..count {
525         val.push(f64::from_bits(E::loadu64(data, offset + i * 8)));
526     }
527     Value::Double(val)
528 }
529 
530 // This is a dummy function and will never be called.
531 #[allow(unused_variables)]
532 fn parse_unknown(data: &[u8], offset: usize, count: usize) -> Value {
533     unreachable!()
534 }
535 
536 #[cfg(test)]
537 mod tests {
538     use crate::endian::BigEndian;
539     use super::*;
540 
541     #[test]
542     fn byte() {
543         let sets: &[(&[u8], &[u8])] = &[
544             (b"x", b""),
545             (b"x\xbe\xad", b"\xbe\xad"),
546         ];
547         let (unitlen, parser) = get_type_info::<BigEndian>(1);
548         for &(data, ans) in sets {
549             assert!((data.len() - 1) % unitlen == 0);
550             match parser(data, 1, (data.len() - 1) / unitlen) {
551                 Value::Byte(v) => assert_eq!(v, ans),
552                 v => panic!("wrong variant {:?}", v),
553             }
554         }
555     }
556 
557     #[test]
558     fn ascii() {
559         let sets: &[(&[u8], Vec<&[u8]>)] = &[
560             (b"x", vec![]),				// malformed
561             (b"x\0", vec![b""]),
562             (b"x\0\0", vec![b"", b""]),
563             (b"xA", vec![b"A"]),			// malformed
564             (b"xA\0", vec![b"A"]),
565             (b"xA\0B", vec![b"A", b"B"]),		// malformed
566             (b"xA\0B\0", vec![b"A", b"B"]),
567             (b"xA\0\xbe\0", vec![b"A", b"\xbe"]),	// not ASCII
568         ];
569         let (unitlen, parser) = get_type_info::<BigEndian>(2);
570         for &(data, ref ans) in sets {
571             match parser(data, 1, (data.len() - 1) / unitlen) {
572                 Value::Ascii(v) => assert_eq!(v, *ans),
573                 v => panic!("wrong variant {:?}", v),
574             }
575         }
576     }
577 
578     #[test]
579     fn short() {
580         let sets: &[(&[u8], Vec<u16>)] = &[
581             (b"x", vec![]),
582             (b"x\x01\x02\x03\x04", vec![0x0102, 0x0304]),
583         ];
584         let (unitlen, parser) = get_type_info::<BigEndian>(3);
585         for &(data, ref ans) in sets {
586             assert!((data.len() - 1) % unitlen == 0);
587             match parser(data, 1, (data.len() - 1) / unitlen) {
588                 Value::Short(v) => assert_eq!(v, *ans),
589                 v => panic!("wrong variant {:?}", v),
590             }
591         }
592     }
593 
594     #[test]
595     fn long() {
596         let sets: &[(&[u8], Vec<u32>)] = &[
597             (b"x", vec![]),
598             (b"x\x01\x02\x03\x04\x05\x06\x07\x08",
599              vec![0x01020304, 0x05060708]),
600         ];
601         let (unitlen, parser) = get_type_info::<BigEndian>(4);
602         for &(data, ref ans) in sets {
603             assert!((data.len() - 1) % unitlen == 0);
604             match parser(data, 1, (data.len() - 1) / unitlen) {
605                 Value::Long(v) => assert_eq!(v, *ans),
606                 v => panic!("wrong variant {:?}", v),
607             }
608         }
609     }
610 
611     #[test]
612     fn rational() {
613         let sets: &[(&[u8], Vec<Rational>)] = &[
614             (b"x", vec![]),
615             (b"x\xa1\x02\x03\x04\x05\x06\x07\x08\
616                \x09\x0a\x0b\x0c\xbd\x0e\x0f\x10",
617              vec![(0xa1020304, 0x05060708).into(),
618                   (0x090a0b0c, 0xbd0e0f10).into()]),
619         ];
620         let (unitlen, parser) = get_type_info::<BigEndian>(5);
621         for &(data, ref ans) in sets {
622             assert!((data.len() - 1) % unitlen == 0);
623             match parser(data, 1, (data.len() - 1) / unitlen) {
624                 Value::Rational(v) => {
625                     assert_eq!(v.len(), ans.len());
626                     for (x, y) in v.iter().zip(ans.iter()) {
627                         assert!(x.num == y.num && x.denom == y.denom);
628                     }
629                 },
630                 v => panic!("wrong variant {:?}", v),
631             }
632         }
633     }
634 
635     #[test]
636     fn sbyte() {
637         let sets: &[(&[u8], &[i8])] = &[
638             (b"x", &[]),
639             (b"x\xbe\x7d", &[-0x42, 0x7d]),
640         ];
641         let (unitlen, parser) = get_type_info::<BigEndian>(6);
642         for &(data, ans) in sets {
643             assert!((data.len() - 1) % unitlen == 0);
644             match parser(data, 1, (data.len() - 1) / unitlen) {
645                 Value::SByte(v) => assert_eq!(v, ans),
646                 v => panic!("wrong variant {:?}", v),
647             }
648         }
649     }
650 
651     #[test]
652     fn undefined() {
653         let sets: &[(&[u8], &[u8])] = &[
654             (b"x", b""),
655             (b"x\xbe\xad", b"\xbe\xad"),
656         ];
657         let (unitlen, parser) = get_type_info::<BigEndian>(7);
658         for &(data, ans) in sets {
659             assert!((data.len() - 1) % unitlen == 0);
660             match parser(data, 1, (data.len() - 1) / unitlen) {
661                 Value::Undefined(v, o) => {
662                     assert_eq!(v, ans);
663                     assert_eq!(o, 1);
664                 },
665                 v => panic!("wrong variant {:?}", v),
666             }
667         }
668     }
669 
670     #[test]
671     fn sshort() {
672         let sets: &[(&[u8], Vec<i16>)] = &[
673             (b"x", vec![]),
674             (b"x\x01\x02\xf3\x04", vec![0x0102, -0x0cfc]),
675         ];
676         let (unitlen, parser) = get_type_info::<BigEndian>(8);
677         for &(data, ref ans) in sets {
678             assert!((data.len() - 1) % unitlen == 0);
679             match parser(data, 1, (data.len() - 1) / unitlen) {
680                 Value::SShort(v) => assert_eq!(v, *ans),
681                 v => panic!("wrong variant {:?}", v),
682             }
683         }
684     }
685 
686     #[test]
687     fn slong() {
688         let sets: &[(&[u8], Vec<i32>)] = &[
689             (b"x", vec![]),
690             (b"x\x01\x02\x03\x04\x85\x06\x07\x08",
691              vec![0x01020304, -0x7af9f8f8]),
692         ];
693         let (unitlen, parser) = get_type_info::<BigEndian>(9);
694         for &(data, ref ans) in sets {
695             assert!((data.len() - 1) % unitlen == 0);
696             match parser(data, 1, (data.len() - 1) / unitlen) {
697                 Value::SLong(v) => assert_eq!(v, *ans),
698                 v => panic!("wrong variant {:?}", v),
699             }
700         }
701     }
702 
703     #[test]
704     fn srational() {
705         let sets: &[(&[u8], Vec<SRational>)] = &[
706             (b"x", vec![]),
707             (b"x\xa1\x02\x03\x04\x05\x06\x07\x08\
708                \x09\x0a\x0b\x0c\xbd\x0e\x0f\x10",
709              vec![(-0x5efdfcfc, 0x05060708).into(),
710                   (0x090a0b0c, -0x42f1f0f0).into()]),
711         ];
712         let (unitlen, parser) = get_type_info::<BigEndian>(10);
713         for &(data, ref ans) in sets {
714             assert!((data.len() - 1) % unitlen == 0);
715             match parser(data, 1, (data.len() - 1) / unitlen) {
716                 Value::SRational(v) => {
717                     assert_eq!(v.len(), ans.len());
718                     for (x, y) in v.iter().zip(ans.iter()) {
719                         assert!(x.num == y.num && x.denom == y.denom);
720                     }
721                 },
722                 v => panic!("wrong variant {:?}", v),
723             }
724         }
725     }
726 
727     #[test]
728     fn float() {
729         let sets: &[(&[u8], Vec<f32>)] = &[
730             (b"x", vec![]),
731             (b"x\x7f\x7f\xff\xff\x80\x80\x00\x00\x40\x00\x00\x00",
732              vec![std::f32::MAX, -std::f32::MIN_POSITIVE, 2.0]),
733         ];
734         let (unitlen, parser) = get_type_info::<BigEndian>(11);
735         for &(data, ref ans) in sets {
736             assert!((data.len() - 1) % unitlen == 0);
737             match parser(data, 1, (data.len() - 1) / unitlen) {
738                 Value::Float(v) => assert_eq!(v, *ans),
739                 v => panic!("wrong variant {:?}", v),
740             }
741         }
742     }
743 
744     #[test]
745     fn double() {
746         let sets: &[(&[u8], Vec<f64>)] = &[
747             (b"x", vec![]),
748             (b"x\x7f\xef\xff\xff\xff\xff\xff\xff\
749                \x80\x10\x00\x00\x00\x00\x00\x00\
750                \x40\x00\x00\x00\x00\x00\x00\x00",
751              vec![std::f64::MAX, -std::f64::MIN_POSITIVE, 2.0]),
752         ];
753         let (unitlen, parser) = get_type_info::<BigEndian>(12);
754         for &(data, ref ans) in sets {
755             assert!((data.len() - 1) % unitlen == 0);
756             match parser(data, 1, (data.len() - 1) / unitlen) {
757                 Value::Double(v) => assert_eq!(v, *ans),
758                 v => panic!("wrong variant {:?}", v),
759             }
760         }
761     }
762 
763     // These functions are never called in a way that an out-of-range access
764     // could happen, so this test is hypothetical but just for safety.
765     #[test]
766     #[should_panic(expected = "index 5 out of range for slice of length 4")]
767     fn short_oor() {
768         parse_short::<BigEndian>(b"\x01\x02\x03\x04", 1, 2);
769     }
770 
771     #[test]
772     fn unknown() {
773         let (unitlen, _parser) = get_type_info::<BigEndian>(0xffff);
774         assert_eq!(unitlen, 0);
775     }
776 
777     #[test]
778     fn get_uint() {
779         let v = Value::Byte(vec![1, 2]);
780         assert_eq!(v.get_uint(0), Some(1));
781         assert_eq!(v.get_uint(1), Some(2));
782         assert_eq!(v.get_uint(2), None);
783         let v = Value::Short(vec![1, 2]);
784         assert_eq!(v.get_uint(0), Some(1));
785         assert_eq!(v.get_uint(1), Some(2));
786         assert_eq!(v.get_uint(2), None);
787         let v = Value::Long(vec![1, 2]);
788         assert_eq!(v.get_uint(0), Some(1));
789         assert_eq!(v.get_uint(1), Some(2));
790         assert_eq!(v.get_uint(2), None);
791         let v = Value::SLong(vec![1, 2]);
792         assert_eq!(v.get_uint(0), None);
793         assert_eq!(v.get_uint(1), None);
794         assert_eq!(v.get_uint(2), None);
795     }
796 
797     #[test]
798     fn iter_uint() {
799         let vlist = &[
800             Value::Byte(vec![1, 2]),
801             Value::Short(vec![1, 2]),
802             Value::Long(vec![1, 2]),
803         ];
804         for v in vlist {
805             let mut it = v.iter_uint().unwrap();
806             assert_eq!(it.next(), Some(1));
807             assert_eq!(it.next(), Some(2));
808             assert_eq!(it.next(), None);
809         }
810 
811         let v = Value::SLong(vec![1, 2]);
812         assert!(v.iter_uint().is_none());
813     }
814 
815     #[test]
816     fn iter_uint_is_exact_size_iter() {
817         let v = Value::Byte(vec![1, 2, 3]);
818         let mut it = v.iter_uint().unwrap();
819         assert_eq!(it.len(), 3);
820         assert_eq!(it.next(), Some(1));
821         assert_eq!(it.len(), 2);
822     }
823 
824     #[test]
825     fn value_fmt_debug() {
826         let v = Value::Byte(b"b\0y".to_vec());
827         assert_eq!(format!("{:?}", v), "Byte([98, 0, 121])");
828         let v = Value::Ascii(vec![]);
829         assert_eq!(format!("{:?}", v), "Ascii([])");
830         let v = Value::Ascii(vec![b"abc\"\\\n\x7f".to_vec(), b"".to_vec()]);
831         assert_eq!(format!("{:?}", v), r#"Ascii(["abc\"\\\x0a\x7f", ""])"#);
832         let v = Value::Short(vec![]);
833         assert_eq!(format!("{:?}", v), "Short([])");
834         let v = Value::Long(vec![1, 2]);
835         assert_eq!(format!("{:?}", v), "Long([1, 2])");
836         let v = Value::Rational(vec![(0, 0).into()]);
837         assert_eq!(format!("{:?}", v), "Rational([Rational(0/0)])");
838         let v = Value::SByte(vec![-3, 4, 5]);
839         assert_eq!(format!("{:?}", v), "SByte([-3, 4, 5])");
840         let v = Value::Undefined(vec![0, 0xff], 0);
841         assert_eq!(format!("{:?}", v), "Undefined(0x00ff, ofs=0x0)");
842         let v = Value::SShort(vec![6, -7]);
843         assert_eq!(format!("{:?}", v), "SShort([6, -7])");
844         let v = Value::SLong(vec![-9]);
845         assert_eq!(format!("{:?}", v), "SLong([-9])");
846         let v = Value::SRational(vec![(-2, -1).into()]);
847         assert_eq!(format!("{:?}", v), "SRational([SRational(-2/-1)])");
848         let v = Value::Float(vec![1.5, 0.0]);
849         assert_eq!(format!("{:?}", v), "Float([1.5, 0.0])");
850         let v = Value::Double(vec![-0.5, 1.0]);
851         assert_eq!(format!("{:?}", v), "Double([-0.5, 1.0])");
852         let v = Value::Unknown(1, 2, 10);
853         assert_eq!(format!("{:?}", v), "Unknown(typ=1, cnt=2, ofs=0xa)");
854     }
855 
856     #[test]
857     fn rational_fmt_display() {
858         let r = Rational::from((u32::max_value(), u32::max_value()));
859         assert_eq!(format!("{}", r), "4294967295/4294967295");
860 
861         let r = Rational::from((10, 20));
862         assert_eq!(format!("{}", r),         "10/20");
863         assert_eq!(format!("{:11}", r),      "      10/20");
864         assert_eq!(format!("{:3}", r),       "10/20");
865     }
866 
867     #[test]
868     fn srational_fmt_display() {
869         let r = SRational::from((i32::min_value(), i32::min_value()));
870         assert_eq!(format!("{}", r), "-2147483648/-2147483648");
871         let r = SRational::from((i32::max_value(), i32::max_value()));
872         assert_eq!(format!("{}", r), "2147483647/2147483647");
873 
874         let r = SRational::from((-10, 20));
875         assert_eq!(format!("{}", r),         "-10/20");
876         assert_eq!(format!("{:11}", r),      "     -10/20");
877         assert_eq!(format!("{:3}", r),       "-10/20");
878 
879         let r = SRational::from((10, -20));
880         assert_eq!(format!("{}", r),         "10/-20");
881         assert_eq!(format!("{:11}", r),      "     10/-20");
882         assert_eq!(format!("{:3}", r),       "10/-20");
883 
884         let r = SRational::from((-10, -20));
885         assert_eq!(format!("{}", r),         "-10/-20");
886         assert_eq!(format!("{:11}", r),      "    -10/-20");
887         assert_eq!(format!("{:3}", r),       "-10/-20");
888     }
889 
890     #[test]
891     fn ratioanl_f64() {
892         use std::{f64, u32};
893         assert_eq!(f64::from(Rational::from((1, 2))), 0.5);
894         assert_eq!(f64::from(Rational::from((1, u32::MAX))),
895                    2.3283064370807974e-10);
896         assert_eq!(f64::from(Rational::from((u32::MAX, 1))),
897                    u32::MAX as f64);
898         assert_eq!(f64::from(Rational::from((u32::MAX - 1, u32::MAX))),
899                    0.9999999997671694);
900         assert_eq!(f64::from(Rational::from((u32::MAX, u32::MAX - 1))),
901                    1.0000000002328306);
902         assert_eq!(f64::from(Rational::from((1, 0))), f64::INFINITY);
903         assert!(f64::from(Rational::from((0, 0))).is_nan());
904 
905         assert_eq!(f64::from(SRational::from((1, 2))), 0.5);
906         assert_eq!(f64::from(SRational::from((-1, 2))), -0.5);
907         assert_eq!(f64::from(SRational::from((1, -2))), -0.5);
908         assert_eq!(f64::from(SRational::from((-1, -2))), 0.5);
909         assert_eq!(f64::from(SRational::from((1, 0))), f64::INFINITY);
910         assert_eq!(f64::from(SRational::from((-1, 0))), f64::NEG_INFINITY);
911     }
912 
913     #[test]
914     fn rational_f32() {
915         // If num and demon are converted to f32 before the division,
916         // the precision is lost in this example.
917         assert_eq!(f32::from(Rational::from((1, 16777217))), 5.960464e-8);
918     }
919 }
920