exif/
value.rs

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