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
386impl From<Rational> for f64 {
388 #[inline]
389 fn from(r: Rational) -> f64 { r.to_f64() }
390}
391
392impl From<Rational> for f32 {
394 #[inline]
395 fn from(r: Rational) -> f32 { r.to_f32() }
396}
397
398#[derive(Copy, Clone)]
400pub struct SRational { pub num: i32, pub denom: i32 }
401
402impl SRational {
403 #[inline]
405 pub fn to_f32(&self) -> f32 {
406 self.to_f64() as f32
407 }
408
409 #[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 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
437impl From<SRational> for f64 {
439 #[inline]
440 fn from(r: SRational) -> f64 { r.to_f64() }
441}
442
443impl From<SRational> for f32 {
445 #[inline]
446 fn from(r: SRational) -> f32 { r.to_f32() }
447}
448
449fn fmt_rational_sub<T>(f: &mut fmt::Formatter, num: u32, denom: T)
451 -> String where T: fmt::Display {
452 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
472pub 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 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
576fn 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
586fn 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#[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![]), (b"x\0", vec![b""]),
628 (b"x\0\0", vec![b"", b""]),
629 (b"xA", vec![b"A"]), (b"xA\0", vec![b"A"]),
631 (b"xA\0B", vec![b"A", b"B"]), (b"xA\0B\0", vec![b"A", b"B"]),
633 (b"xA\0\xbe\0", vec![b"A", b"\xbe"]), ];
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 #[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 assert_eq!(f32::from(Rational::from((1, 16777217))), 5.960464e-8);
1002 }
1003}