1use std::fmt;
28use std::fmt::Write as _;
29
30use crate::endian::Endian;
31use crate::error::Error;
32
33#[derive(Clone)]
35pub enum Value {
36 Byte(Vec<u8>),
38 Ascii(Vec<Vec<u8>>),
42 Short(Vec<u16>),
44 Long(Vec<u32>),
46 Rational(Vec<Rational>),
49 SByte(Vec<i8>),
51 Undefined(Vec<u8>, u32),
58 SShort(Vec<i16>),
60 SLong(Vec<i32>),
62 SRational(Vec<SRational>),
65 Float(Vec<f32>),
68 Double(Vec<f64>),
71 Unknown(u16, u32, u32),
75}
76
77impl Value {
78 #[inline]
94 pub fn display_as(&self, tag: crate::tag::Tag) -> Display {
95 crate::tag::display_value_as(self, tag)
96 }
97
98 #[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 #[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 #[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 #[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 #[inline]
154 pub fn as_uint(&self) -> Result<&UIntValue, Error> {
155 UIntValue::ref_from(self)
156 }
157
158 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 #[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
222pub 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#[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
316pub 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 ContextDependent,
326 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#[derive(Copy, Clone)]
350pub struct Rational { pub num: u32, pub denom: u32 }
351
352impl Rational {
353 #[inline]
355 pub fn to_f32(&self) -> f32 {
356 self.to_f64() as f32
357 }
358
359 #[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 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#[derive(Copy, Clone)]
388pub struct SRational { pub num: i32, pub denom: i32 }
389
390impl SRational {
391 #[inline]
393 pub fn to_f32(&self) -> f32 {
394 self.to_f64() as f32
395 }
396
397 #[inline]
399 pub fn to_f64(&self) -> f64 {
400 self.num as f64 / self.denom as f64
401 }
402}
403
404impl From<(i32, i32)> for SRational {
405 fn from(t: (i32, i32)) -> SRational {
406 SRational { num: t.0, denom: t.1 }
407 }
408}
409
410impl fmt::Debug for SRational {
411 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
412 write!(f, "SRational({}/{})", self.num, self.denom)
413 }
414}
415
416impl fmt::Display for SRational {
417 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
419 let buf = fmt_rational_sub(
420 f, self.num.wrapping_abs() as u32, self.denom);
421 f.pad_integral(self.num >= 0, "", &buf)
422 }
423}
424
425fn fmt_rational_sub<T>(f: &mut fmt::Formatter, num: u32, denom: T)
427 -> String where T: fmt::Display {
428 match (f.sign_plus(), f.precision(), f.sign_aware_zero_pad()) {
431 (true, Some(prec), true) =>
432 format!("{}/{:+0w$}", num, denom, w = prec),
433 (true, Some(prec), false) =>
434 format!("{}/{:+w$}", num, denom, w = prec),
435 (true, None, _) =>
436 format!("{}/{:+}", num, denom),
437 (false, Some(prec), true) =>
438 format!("{}/{:0w$}", num, denom, w = prec),
439 (false, Some(prec), false) =>
440 format!("{}/{:w$}", num, denom, w = prec),
441 (false, None, _) =>
442 format!("{}/{}", num, denom),
443 }
444}
445
446type Parser = fn(&[u8], usize, usize) -> Value;
447
448pub fn get_type_info<E>(typecode: u16) -> (usize, Parser) where E: Endian {
450 match typecode {
451 1 => (1, parse_byte),
452 2 => (1, parse_ascii),
453 3 => (2, parse_short::<E>),
454 4 => (4, parse_long::<E>),
455 5 => (8, parse_rational::<E>),
456 6 => (1, parse_sbyte),
457 7 => (1, parse_undefined),
458 8 => (2, parse_sshort::<E>),
459 9 => (4, parse_slong::<E>),
460 10 => (8, parse_srational::<E>),
461 11 => (4, parse_float::<E>),
462 12 => (8, parse_double::<E>),
463 _ => (0, parse_unknown),
464 }
465}
466
467fn parse_byte(data: &[u8], offset: usize, count: usize) -> Value {
468 Value::Byte(data[offset .. offset + count].to_vec())
469}
470
471fn parse_ascii(data: &[u8], offset: usize, count: usize) -> Value {
472 let iter = (&data[offset .. offset + count]).split(|&b| b == b'\0');
475 let mut v: Vec<Vec<u8>> = iter.map(|x| x.to_vec()).collect();
476 if v.last().map_or(false, |x| x.len() == 0) {
477 v.pop();
478 }
479 Value::Ascii(v)
480}
481
482fn parse_short<E>(data: &[u8], offset: usize, count: usize)
483 -> Value where E: Endian {
484 let mut val = Vec::with_capacity(count);
485 for i in 0..count {
486 val.push(E::loadu16(data, offset + i * 2));
487 }
488 Value::Short(val)
489}
490
491fn parse_long<E>(data: &[u8], offset: usize, count: usize)
492 -> Value where E: Endian {
493 let mut val = Vec::with_capacity(count);
494 for i in 0..count {
495 val.push(E::loadu32(data, offset + i * 4));
496 }
497 Value::Long(val)
498}
499
500fn parse_rational<E>(data: &[u8], offset: usize, count: usize)
501 -> Value where E: Endian {
502 let mut val = Vec::with_capacity(count);
503 for i in 0..count {
504 val.push(Rational {
505 num: E::loadu32(data, offset + i * 8),
506 denom: E::loadu32(data, offset + i * 8 + 4),
507 });
508 }
509 Value::Rational(val)
510}
511
512fn parse_sbyte(data: &[u8], offset: usize, count: usize) -> Value {
513 let bytes = data[offset .. offset + count].iter()
514 .map(|x| *x as i8).collect();
515 Value::SByte(bytes)
516}
517
518fn parse_undefined(data: &[u8], offset: usize, count: usize) -> Value {
519 Value::Undefined(data[offset .. offset + count].to_vec(), offset as u32)
520}
521
522fn parse_sshort<E>(data: &[u8], offset: usize, count: usize)
523 -> Value where E: Endian {
524 let mut val = Vec::with_capacity(count);
525 for i in 0..count {
526 val.push(E::loadu16(data, offset + i * 2) as i16);
527 }
528 Value::SShort(val)
529}
530
531fn parse_slong<E>(data: &[u8], offset: usize, count: usize)
532 -> Value where E: Endian {
533 let mut val = Vec::with_capacity(count);
534 for i in 0..count {
535 val.push(E::loadu32(data, offset + i * 4) as i32);
536 }
537 Value::SLong(val)
538}
539
540fn parse_srational<E>(data: &[u8], offset: usize, count: usize)
541 -> Value where E: Endian {
542 let mut val = Vec::with_capacity(count);
543 for i in 0..count {
544 val.push(SRational {
545 num: E::loadu32(data, offset + i * 8) as i32,
546 denom: E::loadu32(data, offset + i * 8 + 4) as i32,
547 });
548 }
549 Value::SRational(val)
550}
551
552fn parse_float<E>(data: &[u8], offset: usize, count: usize)
554 -> Value where E: Endian {
555 let mut val = Vec::with_capacity(count);
556 for i in 0..count {
557 val.push(f32::from_bits(E::loadu32(data, offset + i * 4)));
558 }
559 Value::Float(val)
560}
561
562fn parse_double<E>(data: &[u8], offset: usize, count: usize)
564 -> Value where E: Endian {
565 let mut val = Vec::with_capacity(count);
566 for i in 0..count {
567 val.push(f64::from_bits(E::loadu64(data, offset + i * 8)));
568 }
569 Value::Double(val)
570}
571
572#[allow(unused_variables)]
574fn parse_unknown(data: &[u8], offset: usize, count: usize) -> Value {
575 unreachable!()
576}
577
578#[cfg(test)]
579mod tests {
580 use crate::endian::BigEndian;
581 use super::*;
582
583 #[test]
584 fn byte() {
585 let sets: &[(&[u8], &[u8])] = &[
586 (b"x", b""),
587 (b"x\xbe\xad", b"\xbe\xad"),
588 ];
589 let (unitlen, parser) = get_type_info::<BigEndian>(1);
590 for &(data, ans) in sets {
591 assert!((data.len() - 1) % unitlen == 0);
592 match parser(data, 1, (data.len() - 1) / unitlen) {
593 Value::Byte(v) => assert_eq!(v, ans),
594 v => panic!("wrong variant {:?}", v),
595 }
596 }
597 }
598
599 #[test]
600 fn ascii() {
601 let sets: &[(&[u8], Vec<&[u8]>)] = &[
602 (b"x", vec![]), (b"x\0", vec![b""]),
604 (b"x\0\0", vec![b"", b""]),
605 (b"xA", vec![b"A"]), (b"xA\0", vec![b"A"]),
607 (b"xA\0B", vec![b"A", b"B"]), (b"xA\0B\0", vec![b"A", b"B"]),
609 (b"xA\0\xbe\0", vec![b"A", b"\xbe"]), ];
611 let (unitlen, parser) = get_type_info::<BigEndian>(2);
612 for &(data, ref ans) in sets {
613 match parser(data, 1, (data.len() - 1) / unitlen) {
614 Value::Ascii(v) => assert_eq!(v, *ans),
615 v => panic!("wrong variant {:?}", v),
616 }
617 }
618 }
619
620 #[test]
621 fn short() {
622 let sets: &[(&[u8], Vec<u16>)] = &[
623 (b"x", vec![]),
624 (b"x\x01\x02\x03\x04", vec![0x0102, 0x0304]),
625 ];
626 let (unitlen, parser) = get_type_info::<BigEndian>(3);
627 for &(data, ref ans) in sets {
628 assert!((data.len() - 1) % unitlen == 0);
629 match parser(data, 1, (data.len() - 1) / unitlen) {
630 Value::Short(v) => assert_eq!(v, *ans),
631 v => panic!("wrong variant {:?}", v),
632 }
633 }
634 }
635
636 #[test]
637 fn long() {
638 let sets: &[(&[u8], Vec<u32>)] = &[
639 (b"x", vec![]),
640 (b"x\x01\x02\x03\x04\x05\x06\x07\x08",
641 vec![0x01020304, 0x05060708]),
642 ];
643 let (unitlen, parser) = get_type_info::<BigEndian>(4);
644 for &(data, ref ans) in sets {
645 assert!((data.len() - 1) % unitlen == 0);
646 match parser(data, 1, (data.len() - 1) / unitlen) {
647 Value::Long(v) => assert_eq!(v, *ans),
648 v => panic!("wrong variant {:?}", v),
649 }
650 }
651 }
652
653 #[test]
654 fn rational() {
655 let sets: &[(&[u8], Vec<Rational>)] = &[
656 (b"x", vec![]),
657 (b"x\xa1\x02\x03\x04\x05\x06\x07\x08\
658 \x09\x0a\x0b\x0c\xbd\x0e\x0f\x10",
659 vec![(0xa1020304, 0x05060708).into(),
660 (0x090a0b0c, 0xbd0e0f10).into()]),
661 ];
662 let (unitlen, parser) = get_type_info::<BigEndian>(5);
663 for &(data, ref ans) in sets {
664 assert!((data.len() - 1) % unitlen == 0);
665 match parser(data, 1, (data.len() - 1) / unitlen) {
666 Value::Rational(v) => {
667 assert_eq!(v.len(), ans.len());
668 for (x, y) in v.iter().zip(ans.iter()) {
669 assert!(x.num == y.num && x.denom == y.denom);
670 }
671 },
672 v => panic!("wrong variant {:?}", v),
673 }
674 }
675 }
676
677 #[test]
678 fn sbyte() {
679 let sets: &[(&[u8], &[i8])] = &[
680 (b"x", &[]),
681 (b"x\xbe\x7d", &[-0x42, 0x7d]),
682 ];
683 let (unitlen, parser) = get_type_info::<BigEndian>(6);
684 for &(data, ans) in sets {
685 assert!((data.len() - 1) % unitlen == 0);
686 match parser(data, 1, (data.len() - 1) / unitlen) {
687 Value::SByte(v) => assert_eq!(v, ans),
688 v => panic!("wrong variant {:?}", v),
689 }
690 }
691 }
692
693 #[test]
694 fn undefined() {
695 let sets: &[(&[u8], &[u8])] = &[
696 (b"x", b""),
697 (b"x\xbe\xad", b"\xbe\xad"),
698 ];
699 let (unitlen, parser) = get_type_info::<BigEndian>(7);
700 for &(data, ans) in sets {
701 assert!((data.len() - 1) % unitlen == 0);
702 match parser(data, 1, (data.len() - 1) / unitlen) {
703 Value::Undefined(v, o) => {
704 assert_eq!(v, ans);
705 assert_eq!(o, 1);
706 },
707 v => panic!("wrong variant {:?}", v),
708 }
709 }
710 }
711
712 #[test]
713 fn sshort() {
714 let sets: &[(&[u8], Vec<i16>)] = &[
715 (b"x", vec![]),
716 (b"x\x01\x02\xf3\x04", vec![0x0102, -0x0cfc]),
717 ];
718 let (unitlen, parser) = get_type_info::<BigEndian>(8);
719 for &(data, ref ans) in sets {
720 assert!((data.len() - 1) % unitlen == 0);
721 match parser(data, 1, (data.len() - 1) / unitlen) {
722 Value::SShort(v) => assert_eq!(v, *ans),
723 v => panic!("wrong variant {:?}", v),
724 }
725 }
726 }
727
728 #[test]
729 fn slong() {
730 let sets: &[(&[u8], Vec<i32>)] = &[
731 (b"x", vec![]),
732 (b"x\x01\x02\x03\x04\x85\x06\x07\x08",
733 vec![0x01020304, -0x7af9f8f8]),
734 ];
735 let (unitlen, parser) = get_type_info::<BigEndian>(9);
736 for &(data, ref ans) in sets {
737 assert!((data.len() - 1) % unitlen == 0);
738 match parser(data, 1, (data.len() - 1) / unitlen) {
739 Value::SLong(v) => assert_eq!(v, *ans),
740 v => panic!("wrong variant {:?}", v),
741 }
742 }
743 }
744
745 #[test]
746 fn srational() {
747 let sets: &[(&[u8], Vec<SRational>)] = &[
748 (b"x", vec![]),
749 (b"x\xa1\x02\x03\x04\x05\x06\x07\x08\
750 \x09\x0a\x0b\x0c\xbd\x0e\x0f\x10",
751 vec![(-0x5efdfcfc, 0x05060708).into(),
752 (0x090a0b0c, -0x42f1f0f0).into()]),
753 ];
754 let (unitlen, parser) = get_type_info::<BigEndian>(10);
755 for &(data, ref ans) in sets {
756 assert!((data.len() - 1) % unitlen == 0);
757 match parser(data, 1, (data.len() - 1) / unitlen) {
758 Value::SRational(v) => {
759 assert_eq!(v.len(), ans.len());
760 for (x, y) in v.iter().zip(ans.iter()) {
761 assert!(x.num == y.num && x.denom == y.denom);
762 }
763 },
764 v => panic!("wrong variant {:?}", v),
765 }
766 }
767 }
768
769 #[test]
770 fn float() {
771 let sets: &[(&[u8], Vec<f32>)] = &[
772 (b"x", vec![]),
773 (b"x\x7f\x7f\xff\xff\x80\x80\x00\x00\x40\x00\x00\x00",
774 vec![std::f32::MAX, -std::f32::MIN_POSITIVE, 2.0]),
775 ];
776 let (unitlen, parser) = get_type_info::<BigEndian>(11);
777 for &(data, ref ans) in sets {
778 assert!((data.len() - 1) % unitlen == 0);
779 match parser(data, 1, (data.len() - 1) / unitlen) {
780 Value::Float(v) => assert_eq!(v, *ans),
781 v => panic!("wrong variant {:?}", v),
782 }
783 }
784 }
785
786 #[test]
787 fn double() {
788 let sets: &[(&[u8], Vec<f64>)] = &[
789 (b"x", vec![]),
790 (b"x\x7f\xef\xff\xff\xff\xff\xff\xff\
791 \x80\x10\x00\x00\x00\x00\x00\x00\
792 \x40\x00\x00\x00\x00\x00\x00\x00",
793 vec![std::f64::MAX, -std::f64::MIN_POSITIVE, 2.0]),
794 ];
795 let (unitlen, parser) = get_type_info::<BigEndian>(12);
796 for &(data, ref ans) in sets {
797 assert!((data.len() - 1) % unitlen == 0);
798 match parser(data, 1, (data.len() - 1) / unitlen) {
799 Value::Double(v) => assert_eq!(v, *ans),
800 v => panic!("wrong variant {:?}", v),
801 }
802 }
803 }
804
805 #[test]
808 #[should_panic(expected = "index 5 out of range for slice of length 4")]
809 fn short_oor() {
810 parse_short::<BigEndian>(b"\x01\x02\x03\x04", 1, 2);
811 }
812
813 #[test]
814 fn unknown() {
815 let (unitlen, _parser) = get_type_info::<BigEndian>(0xffff);
816 assert_eq!(unitlen, 0);
817 }
818
819 #[test]
820 fn as_uint() {
821 let v = Value::Byte(vec![1, 2]);
822 assert_eq!(v.as_uint().unwrap().get(0), Some(1));
823 assert_eq!(v.as_uint().unwrap().get(1), Some(2));
824 assert_eq!(v.as_uint().unwrap().get(2), None);
825 let v = Value::Short(vec![1, 2]);
826 assert_eq!(v.as_uint().unwrap().get(0), Some(1));
827 assert_eq!(v.as_uint().unwrap().get(1), Some(2));
828 assert_eq!(v.as_uint().unwrap().get(2), None);
829 let v = Value::Long(vec![1, 2]);
830 assert_eq!(v.as_uint().unwrap().get(0), Some(1));
831 assert_eq!(v.as_uint().unwrap().get(1), Some(2));
832 assert_eq!(v.as_uint().unwrap().get(2), None);
833 let v = Value::SLong(vec![1, 2]);
834 assert_err_pat!(v.as_uint(), Error::UnexpectedValue(_));
835 }
836
837 #[test]
838 fn get_uint() {
839 let v = Value::Byte(vec![1, 2]);
840 assert_eq!(v.get_uint(0), Some(1));
841 assert_eq!(v.get_uint(1), Some(2));
842 assert_eq!(v.get_uint(2), None);
843 let v = Value::Short(vec![1, 2]);
844 assert_eq!(v.get_uint(0), Some(1));
845 assert_eq!(v.get_uint(1), Some(2));
846 assert_eq!(v.get_uint(2), None);
847 let v = Value::Long(vec![1, 2]);
848 assert_eq!(v.get_uint(0), Some(1));
849 assert_eq!(v.get_uint(1), Some(2));
850 assert_eq!(v.get_uint(2), None);
851 let v = Value::SLong(vec![1, 2]);
852 assert_eq!(v.get_uint(0), None);
853 assert_eq!(v.get_uint(1), None);
854 assert_eq!(v.get_uint(2), None);
855 }
856
857 #[test]
858 fn iter_uint() {
859 let vlist = &[
860 Value::Byte(vec![1, 2]),
861 Value::Short(vec![1, 2]),
862 Value::Long(vec![1, 2]),
863 ];
864 for v in vlist {
865 let mut it = v.iter_uint().unwrap();
866 assert_eq!(it.next(), Some(1));
867 assert_eq!(it.next(), Some(2));
868 assert_eq!(it.next(), None);
869 }
870
871 let v = Value::SLong(vec![1, 2]);
872 assert!(v.iter_uint().is_none());
873 }
874
875 #[test]
876 fn iter_uint_is_exact_size_iter() {
877 let v = Value::Byte(vec![1, 2, 3]);
878 let mut it = v.iter_uint().unwrap();
879 assert_eq!(it.len(), 3);
880 assert_eq!(it.next(), Some(1));
881 assert_eq!(it.len(), 2);
882 }
883
884 #[test]
885 fn value_fmt_debug() {
886 let v = Value::Byte(b"b\0y".to_vec());
887 assert_eq!(format!("{:?}", v), "Byte([98, 0, 121])");
888 let v = Value::Ascii(vec![]);
889 assert_eq!(format!("{:?}", v), "Ascii([])");
890 let v = Value::Ascii(vec![b"abc\"\\\n\x7f".to_vec(), b"".to_vec()]);
891 assert_eq!(format!("{:?}", v), r#"Ascii(["abc\"\\\x0a\x7f", ""])"#);
892 let v = Value::Short(vec![]);
893 assert_eq!(format!("{:?}", v), "Short([])");
894 let v = Value::Long(vec![1, 2]);
895 assert_eq!(format!("{:?}", v), "Long([1, 2])");
896 let v = Value::Rational(vec![(0, 0).into()]);
897 assert_eq!(format!("{:?}", v), "Rational([Rational(0/0)])");
898 let v = Value::SByte(vec![-3, 4, 5]);
899 assert_eq!(format!("{:?}", v), "SByte([-3, 4, 5])");
900 let v = Value::Undefined(vec![0, 0xff], 0);
901 assert_eq!(format!("{:?}", v), "Undefined(0x00ff, ofs=0x0)");
902 let v = Value::SShort(vec![6, -7]);
903 assert_eq!(format!("{:?}", v), "SShort([6, -7])");
904 let v = Value::SLong(vec![-9]);
905 assert_eq!(format!("{:?}", v), "SLong([-9])");
906 let v = Value::SRational(vec![(-2, -1).into()]);
907 assert_eq!(format!("{:?}", v), "SRational([SRational(-2/-1)])");
908 let v = Value::Float(vec![1.5, 0.0]);
909 assert_eq!(format!("{:?}", v), "Float([1.5, 0.0])");
910 let v = Value::Double(vec![-0.5, 1.0]);
911 assert_eq!(format!("{:?}", v), "Double([-0.5, 1.0])");
912 let v = Value::Unknown(1, 2, 10);
913 assert_eq!(format!("{:?}", v), "Unknown(typ=1, cnt=2, ofs=0xa)");
914 }
915
916 #[test]
917 fn rational_fmt_display() {
918 let r = Rational::from((u32::max_value(), u32::max_value()));
919 assert_eq!(format!("{}", r), "4294967295/4294967295");
920
921 let r = Rational::from((10, 20));
922 assert_eq!(format!("{}", r), "10/20");
923 assert_eq!(format!("{:11}", r), " 10/20");
924 assert_eq!(format!("{:3}", r), "10/20");
925 }
926
927 #[test]
928 fn srational_fmt_display() {
929 let r = SRational::from((i32::min_value(), i32::min_value()));
930 assert_eq!(format!("{}", r), "-2147483648/-2147483648");
931 let r = SRational::from((i32::max_value(), i32::max_value()));
932 assert_eq!(format!("{}", r), "2147483647/2147483647");
933
934 let r = SRational::from((-10, 20));
935 assert_eq!(format!("{}", r), "-10/20");
936 assert_eq!(format!("{:11}", r), " -10/20");
937 assert_eq!(format!("{:3}", r), "-10/20");
938
939 let r = SRational::from((10, -20));
940 assert_eq!(format!("{}", r), "10/-20");
941 assert_eq!(format!("{:11}", r), " 10/-20");
942 assert_eq!(format!("{:3}", r), "10/-20");
943
944 let r = SRational::from((-10, -20));
945 assert_eq!(format!("{}", r), "-10/-20");
946 assert_eq!(format!("{:11}", r), " -10/-20");
947 assert_eq!(format!("{:3}", r), "-10/-20");
948 }
949
950 #[test]
951 fn ratioanl_f64() {
952 use std::{f64, u32};
953 assert_eq!(Rational::from((1, 2)).to_f64(), 0.5);
954 assert_eq!(Rational::from((1, u32::MAX)).to_f64(),
955 2.3283064370807974e-10);
956 assert_eq!(Rational::from((u32::MAX, 1)).to_f64(),
957 u32::MAX as f64);
958 assert_eq!(Rational::from((u32::MAX - 1, u32::MAX)).to_f64(),
959 0.9999999997671694);
960 assert_eq!(Rational::from((u32::MAX, u32::MAX - 1)).to_f64(),
961 1.0000000002328306);
962 assert_eq!(Rational::from((1, 0)).to_f64(), f64::INFINITY);
963 assert!(Rational::from((0, 0)).to_f64().is_nan());
964
965 assert_eq!(SRational::from((1, 2)).to_f64(), 0.5);
966 assert_eq!(SRational::from((-1, 2)).to_f64(), -0.5);
967 assert_eq!(SRational::from((1, -2)).to_f64(), -0.5);
968 assert_eq!(SRational::from((-1, -2)).to_f64(), 0.5);
969 assert_eq!(SRational::from((1, 0)).to_f64(), f64::INFINITY);
970 assert_eq!(SRational::from((-1, 0)).to_f64(), f64::NEG_INFINITY);
971 }
972
973 #[test]
974 fn rational_f32() {
975 assert_eq!(Rational::from((1, 16777217)).to_f32(), 5.960464e-8);
978 }
979}