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