1use std::collections::HashMap;
2use std::io::Read;
3
4use bytes::Bytes;
5
6use crate::error::{AsyncTiffError, AsyncTiffResult, TiffError, TiffFormatError};
7use crate::metadata::fetch::MetadataCursor;
8use crate::metadata::MetadataFetch;
9use crate::reader::Endianness;
10use crate::tag_value::TagValue;
11use crate::tags::{Tag, Type};
12use crate::{ImageFileDirectory, TIFF};
13
14pub struct TiffMetadataReader {
24 endianness: Endianness,
25 bigtiff: bool,
26 next_ifd_offset: Option<u64>,
27}
28
29impl TiffMetadataReader {
30 pub async fn try_open<F: MetadataFetch>(fetch: &F) -> AsyncTiffResult<Self> {
35 let magic_bytes = fetch.fetch(0..2).await?;
36
37 let endianness = if magic_bytes == Bytes::from_static(b"II") {
39 Endianness::LittleEndian
40 } else if magic_bytes == Bytes::from_static(b"MM") {
41 Endianness::BigEndian
42 } else {
43 return Err(AsyncTiffError::General(format!(
44 "unexpected magic bytes {magic_bytes:?}"
45 )));
46 };
47
48 let mut cursor = MetadataCursor::new(fetch, endianness).with_offset(2);
50
51 let version = cursor.read_u16().await?;
52 let bigtiff = match version {
53 42 => false,
54 43 => {
55 if cursor.read_u16().await? != 8 {
57 return Err(
58 TiffError::FormatError(TiffFormatError::TiffSignatureNotFound).into(),
59 );
60 }
61 if cursor.read_u16().await? != 0 {
63 return Err(
64 TiffError::FormatError(TiffFormatError::TiffSignatureNotFound).into(),
65 );
66 }
67 true
68 }
69 _ => return Err(TiffError::FormatError(TiffFormatError::TiffSignatureInvalid).into()),
70 };
71
72 let first_ifd_location = if bigtiff {
73 cursor.read_u64().await?
74 } else {
75 cursor.read_u32().await?.into()
76 };
77
78 Ok(Self {
79 endianness,
80 bigtiff,
81 next_ifd_offset: Some(first_ifd_location),
82 })
83 }
84
85 pub fn endianness(&self) -> Endianness {
87 self.endianness
88 }
89
90 pub fn bigtiff(&self) -> bool {
92 self.bigtiff
93 }
94
95 pub fn has_next_ifd(&self) -> bool {
97 self.next_ifd_offset.is_some()
98 }
99
100 pub fn next_ifd_offset(&self) -> Option<u64> {
104 self.next_ifd_offset
105 }
106
107 pub async fn read_next_ifd<F: MetadataFetch>(
111 &mut self,
112 fetch: &F,
113 ) -> AsyncTiffResult<Option<ImageFileDirectory>> {
114 if let Some(ifd_start) = self.next_ifd_offset {
115 let ifd_reader =
116 ImageFileDirectoryReader::open(fetch, ifd_start, self.bigtiff, self.endianness)
117 .await?;
118 let ifd = ifd_reader.read(fetch).await?;
119 let next_ifd_offset = ifd_reader.finish(fetch).await?;
120 self.next_ifd_offset = next_ifd_offset;
121 Ok(Some(ifd))
122 } else {
123 Ok(None)
124 }
125 }
126
127 pub async fn read_all_ifds<F: MetadataFetch>(
129 &mut self,
130 fetch: &F,
131 ) -> AsyncTiffResult<Vec<ImageFileDirectory>> {
132 let mut ifds = vec![];
133 while let Some(ifd) = self.read_next_ifd(fetch).await? {
134 ifds.push(ifd);
135 }
136 Ok(ifds)
137 }
138
139 pub async fn read<F: MetadataFetch>(&mut self, fetch: &F) -> AsyncTiffResult<TIFF> {
141 let ifds = self.read_all_ifds(fetch).await?;
142 Ok(TIFF::new(ifds, self.endianness))
143 }
144}
145
146pub struct ImageFileDirectoryReader {
155 endianness: Endianness,
156 bigtiff: bool,
157 ifd_start_offset: u64,
159 tag_count: u64,
161 ifd_entry_byte_size: u64,
164 tag_count_byte_size: u64,
166}
167
168impl ImageFileDirectoryReader {
169 pub async fn open<F: MetadataFetch>(
171 fetch: &F,
172 ifd_start_offset: u64,
173 bigtiff: bool,
174 endianness: Endianness,
175 ) -> AsyncTiffResult<Self> {
176 let mut cursor = MetadataCursor::new_with_offset(fetch, endianness, ifd_start_offset);
177
178 let ifd_entry_byte_size = if bigtiff { 20 } else { 12 };
187 let tag_count_byte_size = if bigtiff { 8 } else { 2 };
189
190 let tag_count = if bigtiff {
191 cursor.read_u64().await?
192 } else {
193 cursor.read_u16().await?.into()
194 };
195
196 Ok(Self {
197 endianness,
198 bigtiff,
199 ifd_entry_byte_size,
200 tag_count,
201 tag_count_byte_size,
202 ifd_start_offset,
203 })
204 }
205
206 pub async fn read_tag<F: MetadataFetch>(
213 &self,
214 fetch: &F,
215 tag_idx: u64,
216 ) -> AsyncTiffResult<(Tag, TagValue)> {
217 assert!(tag_idx < self.tag_count);
218 let tag_offset =
219 self.ifd_start_offset + self.tag_count_byte_size + (self.ifd_entry_byte_size * tag_idx);
220 let (tag_name, tag_value) =
221 read_tag(fetch, tag_offset, self.endianness, self.bigtiff).await?;
222 Ok((tag_name, tag_value))
223 }
224
225 pub async fn read<F: MetadataFetch>(&self, fetch: &F) -> AsyncTiffResult<ImageFileDirectory> {
230 let mut tags = HashMap::with_capacity(self.tag_count as usize);
231 for tag_idx in 0..self.tag_count {
232 let (tag, value) = self.read_tag(fetch, tag_idx).await?;
233 tags.insert(tag, value);
234 }
235 ImageFileDirectory::from_tags(tags, self.endianness)
236 }
237
238 pub async fn finish<F: MetadataFetch>(self, fetch: &F) -> AsyncTiffResult<Option<u64>> {
240 let next_ifd_byte_offset = self.ifd_start_offset
242 + self.tag_count_byte_size
243 + (self.ifd_entry_byte_size * self.tag_count);
244 let mut cursor =
245 MetadataCursor::new_with_offset(fetch, self.endianness, next_ifd_byte_offset);
246
247 let next_ifd_offset = if self.bigtiff {
248 cursor.read_u64().await?
249 } else {
250 cursor.read_u32().await?.into()
251 };
252
253 if next_ifd_offset == 0 {
255 Ok(None)
256 } else {
257 Ok(Some(next_ifd_offset))
258 }
259 }
260}
261
262async fn read_tag<F: MetadataFetch>(
264 fetch: &F,
265 tag_offset: u64,
266 endianness: Endianness,
267 bigtiff: bool,
268) -> AsyncTiffResult<(Tag, TagValue)> {
269 let mut cursor = MetadataCursor::new_with_offset(fetch, endianness, tag_offset);
270
271 let tag_name = Tag::from_u16_exhaustive(cursor.read_u16().await?);
272
273 let tag_type_code = cursor.read_u16().await?;
274 let tag_type = Type::from_u16(tag_type_code).expect(
275 "Unknown tag type {tag_type_code}. TODO: we should skip entries with unknown tag types.",
276 );
277 let count = if bigtiff {
278 cursor.read_u64().await?
279 } else {
280 cursor.read_u32().await?.into()
281 };
282
283 let tag_value = read_tag_value(&mut cursor, tag_type, count, bigtiff).await?;
284
285 Ok((tag_name, tag_value))
286}
287
288async fn read_tag_value<F: MetadataFetch>(
294 cursor: &mut MetadataCursor<'_, F>,
295 tag_type: Type,
296 count: u64,
297 bigtiff: bool,
298) -> AsyncTiffResult<TagValue> {
299 if count == 0 {
301 return Ok(TagValue::List(vec![]));
302 }
303
304 let tag_size = match tag_type {
305 Type::BYTE | Type::SBYTE | Type::ASCII | Type::UNDEFINED => 1,
306 Type::SHORT | Type::SSHORT => 2,
307 Type::LONG | Type::SLONG | Type::FLOAT | Type::IFD => 4,
308 Type::LONG8
309 | Type::SLONG8
310 | Type::DOUBLE
311 | Type::RATIONAL
312 | Type::SRATIONAL
313 | Type::IFD8 => 8,
314 };
315
316 let value_byte_length = count.checked_mul(tag_size).unwrap();
317
318 if count == 1 {
320 if bigtiff && value_byte_length > 4 && value_byte_length <= 8 {
322 let mut data = cursor.read(value_byte_length).await?;
323
324 return Ok(match tag_type {
325 Type::LONG8 => TagValue::UnsignedBig(data.read_u64()?),
326 Type::SLONG8 => TagValue::SignedBig(data.read_i64()?),
327 Type::DOUBLE => TagValue::Double(data.read_f64()?),
328 Type::RATIONAL => TagValue::Rational(data.read_u32()?, data.read_u32()?),
329 Type::SRATIONAL => TagValue::SRational(data.read_i32()?, data.read_i32()?),
330 Type::IFD8 => TagValue::IfdBig(data.read_u64()?),
331 Type::BYTE
332 | Type::SBYTE
333 | Type::ASCII
334 | Type::UNDEFINED
335 | Type::SHORT
336 | Type::SSHORT
337 | Type::LONG
338 | Type::SLONG
339 | Type::FLOAT
340 | Type::IFD => unreachable!(),
341 });
342 }
343
344 let mut data = cursor.read(value_byte_length).await?;
348
349 return Ok(match tag_type {
351 Type::BYTE | Type::UNDEFINED => TagValue::Byte(data.read_u8()?),
352 Type::SBYTE => TagValue::SignedByte(data.read_i8()?),
353 Type::SHORT => TagValue::Short(data.read_u16()?),
354 Type::SSHORT => TagValue::SignedShort(data.read_i16()?),
355 Type::LONG => TagValue::Unsigned(data.read_u32()?),
356 Type::SLONG => TagValue::Signed(data.read_i32()?),
357 Type::FLOAT => TagValue::Float(data.read_f32()?),
358 Type::ASCII => {
359 if data.as_ref()[0] == 0 {
360 TagValue::Ascii("".to_string())
361 } else {
362 panic!("Invalid tag");
363 }
365 }
366 Type::LONG8 => {
367 let offset = data.read_u32()?;
368 cursor.seek(offset as _);
369 TagValue::UnsignedBig(cursor.read_u64().await?)
370 }
371 Type::SLONG8 => {
372 let offset = data.read_u32()?;
373 cursor.seek(offset as _);
374 TagValue::SignedBig(cursor.read_i64().await?)
375 }
376 Type::DOUBLE => {
377 let offset = data.read_u32()?;
378 cursor.seek(offset as _);
379 TagValue::Double(cursor.read_f64().await?)
380 }
381 Type::RATIONAL => {
382 let offset = data.read_u32()?;
383 cursor.seek(offset as _);
384 let numerator = cursor.read_u32().await?;
385 let denominator = cursor.read_u32().await?;
386 TagValue::Rational(numerator, denominator)
387 }
388 Type::SRATIONAL => {
389 let offset = data.read_u32()?;
390 cursor.seek(offset as _);
391 let numerator = cursor.read_i32().await?;
392 let denominator = cursor.read_i32().await?;
393 TagValue::SRational(numerator, denominator)
394 }
395 Type::IFD => TagValue::Ifd(data.read_u32()?),
396 Type::IFD8 => {
397 let offset = data.read_u32()?;
398 cursor.seek(offset as _);
399 TagValue::IfdBig(cursor.read_u64().await?)
400 }
401 });
402 }
403
404 if value_byte_length <= 4 || bigtiff && value_byte_length <= 8 {
406 let mut data = cursor.read(value_byte_length).await?;
407 if bigtiff {
408 cursor.advance(8 - value_byte_length);
409 } else {
410 cursor.advance(4 - value_byte_length);
411 }
412
413 match tag_type {
414 Type::BYTE | Type::UNDEFINED => {
415 return {
416 Ok(TagValue::List(
417 (0..count)
418 .map(|_| TagValue::Byte(data.read_u8().unwrap()))
419 .collect(),
420 ))
421 };
422 }
423 Type::SBYTE => {
424 return {
425 Ok(TagValue::List(
426 (0..count)
427 .map(|_| TagValue::SignedByte(data.read_i8().unwrap()))
428 .collect(),
429 ))
430 }
431 }
432 Type::ASCII => {
433 let mut buf = vec![0; count as usize];
434 data.read_exact(&mut buf)?;
435 if buf.is_ascii() && buf.ends_with(&[0]) {
436 let v = std::str::from_utf8(&buf)
437 .map_err(|err| AsyncTiffError::General(err.to_string()))?;
438 let v = v.trim_matches(char::from(0));
439 return Ok(TagValue::Ascii(v.into()));
440 } else {
441 panic!("Invalid tag");
442 }
444 }
445 Type::SHORT => {
446 let mut v = Vec::new();
447 for _ in 0..count {
448 v.push(TagValue::Short(data.read_u16()?));
449 }
450 return Ok(TagValue::List(v));
451 }
452 Type::SSHORT => {
453 let mut v = Vec::new();
454 for _ in 0..count {
455 v.push(TagValue::SignedShort(data.read_i16()?));
456 }
457 return Ok(TagValue::List(v));
458 }
459 Type::LONG => {
460 let mut v = Vec::new();
461 for _ in 0..count {
462 v.push(TagValue::Unsigned(data.read_u32()?));
463 }
464 return Ok(TagValue::List(v));
465 }
466 Type::SLONG => {
467 let mut v = Vec::new();
468 for _ in 0..count {
469 v.push(TagValue::Signed(data.read_i32()?));
470 }
471 return Ok(TagValue::List(v));
472 }
473 Type::FLOAT => {
474 let mut v = Vec::new();
475 for _ in 0..count {
476 v.push(TagValue::Float(data.read_f32()?));
477 }
478 return Ok(TagValue::List(v));
479 }
480 Type::IFD => {
481 let mut v = Vec::new();
482 for _ in 0..count {
483 v.push(TagValue::Ifd(data.read_u32()?));
484 }
485 return Ok(TagValue::List(v));
486 }
487 Type::LONG8
488 | Type::SLONG8
489 | Type::RATIONAL
490 | Type::SRATIONAL
491 | Type::DOUBLE
492 | Type::IFD8 => {
493 unreachable!()
494 }
495 }
496 }
497
498 let offset = if bigtiff {
500 cursor.read_u64().await?
501 } else {
502 cursor.read_u32().await?.into()
503 };
504 cursor.seek(offset);
505
506 match tag_type {
508 Type::BYTE | Type::UNDEFINED => {
511 let mut v = Vec::with_capacity(count as _);
512 for _ in 0..count {
513 v.push(TagValue::Byte(cursor.read_u8().await?))
514 }
515 Ok(TagValue::List(v))
516 }
517 Type::SBYTE => {
518 let mut v = Vec::with_capacity(count as _);
519 for _ in 0..count {
520 v.push(TagValue::SignedByte(cursor.read_i8().await?))
521 }
522 Ok(TagValue::List(v))
523 }
524 Type::SHORT => {
525 let mut v = Vec::with_capacity(count as _);
526 for _ in 0..count {
527 v.push(TagValue::Short(cursor.read_u16().await?))
528 }
529 Ok(TagValue::List(v))
530 }
531 Type::SSHORT => {
532 let mut v = Vec::with_capacity(count as _);
533 for _ in 0..count {
534 v.push(TagValue::SignedShort(cursor.read_i16().await?))
535 }
536 Ok(TagValue::List(v))
537 }
538 Type::LONG => {
539 let mut v = Vec::with_capacity(count as _);
540 for _ in 0..count {
541 v.push(TagValue::Unsigned(cursor.read_u32().await?))
542 }
543 Ok(TagValue::List(v))
544 }
545 Type::SLONG => {
546 let mut v = Vec::with_capacity(count as _);
547 for _ in 0..count {
548 v.push(TagValue::Signed(cursor.read_i32().await?))
549 }
550 Ok(TagValue::List(v))
551 }
552 Type::FLOAT => {
553 let mut v = Vec::with_capacity(count as _);
554 for _ in 0..count {
555 v.push(TagValue::Float(cursor.read_f32().await?))
556 }
557 Ok(TagValue::List(v))
558 }
559 Type::DOUBLE => {
560 let mut v = Vec::with_capacity(count as _);
561 for _ in 0..count {
562 v.push(TagValue::Double(cursor.read_f64().await?))
563 }
564 Ok(TagValue::List(v))
565 }
566 Type::RATIONAL => {
567 let mut v = Vec::with_capacity(count as _);
568 for _ in 0..count {
569 v.push(TagValue::Rational(
570 cursor.read_u32().await?,
571 cursor.read_u32().await?,
572 ))
573 }
574 Ok(TagValue::List(v))
575 }
576 Type::SRATIONAL => {
577 let mut v = Vec::with_capacity(count as _);
578 for _ in 0..count {
579 v.push(TagValue::SRational(
580 cursor.read_i32().await?,
581 cursor.read_i32().await?,
582 ))
583 }
584 Ok(TagValue::List(v))
585 }
586 Type::LONG8 => {
587 let mut v = Vec::with_capacity(count as _);
588 for _ in 0..count {
589 v.push(TagValue::UnsignedBig(cursor.read_u64().await?))
590 }
591 Ok(TagValue::List(v))
592 }
593 Type::SLONG8 => {
594 let mut v = Vec::with_capacity(count as _);
595 for _ in 0..count {
596 v.push(TagValue::SignedBig(cursor.read_i64().await?))
597 }
598 Ok(TagValue::List(v))
599 }
600 Type::IFD => {
601 let mut v = Vec::with_capacity(count as _);
602 for _ in 0..count {
603 v.push(TagValue::Ifd(cursor.read_u32().await?))
604 }
605 Ok(TagValue::List(v))
606 }
607 Type::IFD8 => {
608 let mut v = Vec::with_capacity(count as _);
609 for _ in 0..count {
610 v.push(TagValue::IfdBig(cursor.read_u64().await?))
611 }
612 Ok(TagValue::List(v))
613 }
614 Type::ASCII => {
615 let mut out = vec![0; count as _];
616 let mut buf = cursor.read(count).await?;
617 buf.read_exact(&mut out)?;
618
619 if let Some(first) = out.iter().position(|&b| b == 0) {
621 out.truncate(first);
622 }
623 Ok(TagValue::Ascii(String::from_utf8_lossy(&out).into_owned()))
624 }
625 }
626}
627
628#[cfg(test)]
629mod test {
630 use async_trait::async_trait;
631
632 use super::*;
633
634 #[async_trait]
635 impl MetadataFetch for Bytes {
636 async fn fetch(&self, range: std::ops::Range<u64>) -> crate::error::AsyncTiffResult<Bytes> {
637 let usize_range = range.start as usize..range.end as usize;
638 Ok(self.slice(usize_range))
639 }
640 }
641
642 #[tokio::test]
643 #[rustfmt::skip]
644 async fn test_single_fits_notbig() {
645 assert_eq!(u16::from_le_bytes([42,0]),42);
647 assert_eq!(u16::from_be_bytes([0,42]),42);
648 assert_eq!(f32::from_le_bytes([0x42,0,0,0]),f32::from_bits(0x00_00_00_42));
649 assert_eq!(f32::from_be_bytes([0,0,0,0x42]),f32::from_bits(0x00_00_00_42));
650 let cases= [
651 ([1,1, 1, 0, 1,0,0,0, 42, 0, 0, 0], Endianness::LittleEndian, TagValue::Byte (42 )),
654 ([1,1, 0, 1, 0,0,0,1, 42, 0, 0, 0], Endianness::BigEndian, TagValue::Byte (42 )),
655 ([1,1, 6, 0, 1,0,0,0, 42, 0, 0, 0], Endianness::LittleEndian, TagValue::SignedByte(42 )),
656 ([1,1, 0, 6, 0,0,0,1, 42, 0, 0, 0], Endianness::BigEndian, TagValue::SignedByte(42 )),
657 ([1,1, 7, 0, 1,0,0,0, 42, 0, 0, 0], Endianness::LittleEndian, TagValue::Byte (42 )), ([1,1, 0, 7, 0,0,0,1, 42, 0, 0, 0], Endianness::BigEndian, TagValue::Byte (42 )), ([1,1, 2, 0, 1,0,0,0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::Ascii ("".into() )),
660 ([1,1, 0, 2, 0,0,0,1, 0, 0, 0, 0], Endianness::BigEndian, TagValue::Ascii ("".into() )),
661 ([1,1, 3, 0, 1,0,0,0, 42, 0, 0, 0], Endianness::LittleEndian, TagValue::Short (42 )),
662 ([1,1, 0, 3, 0,0,0,1, 0,42, 0, 0], Endianness::BigEndian, TagValue::Short (42 )),
663 ([1,1, 8, 0, 1,0,0,0, 42, 0, 0, 0], Endianness::LittleEndian, TagValue::SignedShort (42 )),
664 ([1,1, 0, 8, 0,0,0,1, 0,42, 0, 0], Endianness::BigEndian, TagValue::SignedShort (42 )),
665 ([1,1, 4, 0, 1,0,0,0, 42, 0, 0, 0], Endianness::LittleEndian, TagValue::Unsigned (42 )),
666 ([1,1, 0, 4, 0,0,0,1, 0, 0, 0,42], Endianness::BigEndian, TagValue::Unsigned (42 )),
667 ([1,1, 9, 0, 1,0,0,0, 42, 0, 0, 0], Endianness::LittleEndian, TagValue::Signed (42 )),
668 ([1,1, 0, 9, 0,0,0,1, 0, 0, 0,42], Endianness::BigEndian, TagValue::Signed (42 )),
669 ([1,1,13, 0, 1,0,0,0, 42, 0, 0, 0], Endianness::LittleEndian, TagValue::Ifd (42 )),
670 ([1,1, 0,13, 0,0,0,1, 0, 0, 0,42], Endianness::BigEndian, TagValue::Ifd (42 )),
671 ([1,1,11, 0, 1,0,0,0, 42, 0, 0, 0], Endianness::LittleEndian, TagValue::Float (f32::from_bits(42))),
672 ([1,1, 0,11, 0,0,0,1, 0, 0, 0,42], Endianness::BigEndian, TagValue::Float (f32::from_bits(42))),
673 ];
675 for (buf, byte_order, res) in cases {
676 let fetch = Bytes::copy_from_slice(&buf);
677 assert_eq!(
678 read_tag(&fetch, 0, byte_order, false).await.unwrap(),
679 (Tag::from_u16_exhaustive(0x01_01),res)
680 );
681 }
682 }
683
684 #[tokio::test]
685 #[rustfmt::skip]
686 async fn test_single_fits_big() {
687 assert_eq!(u16::from_le_bytes([42,0]),42);
689 assert_eq!(u16::from_be_bytes([0,42]),42);
690
691 assert_eq!(f32::from_le_bytes([0x42,0,0,0]),f32::from_bits(0x00_00_00_42));
692 assert_eq!(f32::from_be_bytes([0,0,0,0x42]),f32::from_bits(0x00_00_00_42));
693 let cases = [
694 ([1,1, 1, 0, 1,0,0,0,0,0,0,0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::Byte (42) ),
697 ([1,1, 0, 1, 0,0,0,0,0,0,0,1, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::BigEndian, TagValue::Byte (42) ),
698 ([1,1, 6, 0, 1,0,0,0,0,0,0,0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::SignedByte (42) ),
699 ([1,1, 0, 6, 0,0,0,0,0,0,0,1, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::BigEndian, TagValue::SignedByte (42) ),
700 ([1,1, 7, 0, 1,0,0,0,0,0,0,0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::Byte (42) ), ([1,1, 0, 7, 0,0,0,0,0,0,0,1, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::BigEndian, TagValue::Byte (42) ), ([1,1, 2, 0, 1,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::Ascii ("".into()) ),
703 ([1,1, 0, 2, 0,0,0,0,0,0,0,1, 0, 0, 0, 0, 0, 0, 0, 0], Endianness::BigEndian, TagValue::Ascii ("".into()) ),
704 ([1,1, 3, 0, 1,0,0,0,0,0,0,0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::Short (42) ),
705 ([1,1, 0, 3, 0,0,0,0,0,0,0,1, 0,42, 0, 0, 0, 0, 0, 0], Endianness::BigEndian, TagValue::Short (42) ),
706 ([1,1, 8, 0, 1,0,0,0,0,0,0,0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::SignedShort(42) ),
707 ([1,1, 0, 8, 0,0,0,0,0,0,0,1, 0,42, 0, 0, 0, 0, 0, 0], Endianness::BigEndian, TagValue::SignedShort(42) ),
708 ([1,1, 4, 0, 1,0,0,0,0,0,0,0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::Unsigned (42) ),
709 ([1,1, 0, 4, 0,0,0,0,0,0,0,1, 0, 0, 0,42, 0, 0, 0, 0], Endianness::BigEndian, TagValue::Unsigned (42) ),
710 ([1,1, 9, 0, 1,0,0,0,0,0,0,0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::Signed (42) ),
711 ([1,1, 0, 9, 0,0,0,0,0,0,0,1, 0, 0, 0,42, 0, 0, 0, 0], Endianness::BigEndian, TagValue::Signed (42) ),
712 ([1,1, 13, 0, 1,0,0,0,0,0,0,0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::Ifd (42) ),
713 ([1,1, 0,13, 0,0,0,0,0,0,0,1, 0, 0, 0,42, 0, 0, 0, 0], Endianness::BigEndian, TagValue::Ifd (42) ),
714 ([1,1, 16, 0, 1,0,0,0,0,0,0,0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::UnsignedBig(42) ),
715 ([1,1, 0,16, 0,0,0,0,0,0,0,1, 0, 0, 0, 0, 0, 0, 0,42], Endianness::BigEndian, TagValue::UnsignedBig(42) ),
716 ([1,1, 17, 0, 1,0,0,0,0,0,0,0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::SignedBig (42) ),
717 ([1,1, 0,17, 0,0,0,0,0,0,0,1, 0, 0, 0, 0, 0, 0, 0,42], Endianness::BigEndian, TagValue::SignedBig (42) ),
718 ([1,1, 18, 0, 1,0,0,0,0,0,0,0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::IfdBig (42) ),
719 ([1,1, 0,18, 0,0,0,0,0,0,0,1, 0, 0, 0, 0, 0, 0, 0,42], Endianness::BigEndian, TagValue::IfdBig (42) ),
720 ([1,1, 11, 0, 1,0,0,0,0,0,0,0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::Float (f32::from_bits(42))),
721 ([1,1, 0,11, 0,0,0,0,0,0,0,1, 0, 0, 0,42, 0, 0, 0, 0], Endianness::BigEndian, TagValue::Float (f32::from_bits(42))),
722 ([1,1, 12, 0, 1,0,0,0,0,0,0,0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::Double (f64::from_bits(42))),
723 ([1,1, 0,12, 0,0,0,0,0,0,0,1, 0, 0, 0, 0, 0, 0, 0,42], Endianness::BigEndian, TagValue::Double (f64::from_bits(42))),
724 ([1,1, 5, 0, 1,0,0,0,0,0,0,0, 42,0, 0, 0,43, 0, 0, 0], Endianness::LittleEndian, TagValue::Rational (42, 43) ),
725 ([1,1, 0, 5, 0,0,0,0,0,0,0,1, 0, 0, 0,42, 0, 0, 0,43], Endianness::BigEndian, TagValue::Rational (42, 43) ),
726 ([1,1, 10,0, 1,0,0,0,0,0,0,0, 42, 0, 0, 0,43, 0, 0, 0], Endianness::LittleEndian, TagValue::SRational (42, 43) ),
727 ([1,1, 0,10, 0,0,0,0,0,0,0,1, 0, 0, 0,42, 0, 0, 0,43], Endianness::BigEndian, TagValue::SRational (42, 43) ),
728 ];
730 for (buf, byte_order, res) in cases {
731 let fetch = Bytes::copy_from_slice(&buf);
732 assert_eq!(
733 read_tag(&fetch, 0, byte_order, true).await.unwrap(),
734 (Tag::from_u16_exhaustive(0x0101), res)
735 )
736 }
737 }
738
739 #[tokio::test]
740 #[rustfmt::skip]
741 async fn test_fits_multi_notbig() {
742 assert_eq!(u16::from_le_bytes([42,0]),42);
744 assert_eq!(u16::from_be_bytes([0,42]),42);
745
746 assert_eq!(f32::from_le_bytes([0x42,0,0,0]),f32::from_bits(0x00_00_00_42));
747 assert_eq!(f32::from_be_bytes([0,0,0,0x42]),f32::from_bits(0x00_00_00_42));
748 let cases = [
749 ([1,1, 1, 0, 4,0,0,0, 42,42,42,42], Endianness::LittleEndian, TagValue::List(vec![TagValue::Byte (42); 4]) ),
752 ([1,1, 0, 1, 0,0,0,4, 42,42,42,42], Endianness::BigEndian, TagValue::List(vec![TagValue::Byte (42); 4]) ),
753 ([1,1, 6, 0, 4,0,0,0, 42,42,42,42], Endianness::LittleEndian, TagValue::List(vec![TagValue::SignedByte (42); 4]) ),
754 ([1,1, 0, 6, 0,0,0,4, 42,42,42,42], Endianness::BigEndian, TagValue::List(vec![TagValue::SignedByte (42); 4]) ),
755 ([1,1, 7, 0, 4,0,0,0, 42,42,42,42], Endianness::LittleEndian, TagValue::List(vec![TagValue::Byte (42); 4]) ), ([1,1, 0, 7, 0,0,0,4, 42,42,42,42], Endianness::BigEndian, TagValue::List(vec![TagValue::Byte (42); 4]) ), ([1,1, 2, 0, 4,0,0,0, 42,42,42, 0], Endianness::LittleEndian, TagValue::Ascii("***".into())),
758 ([1,1, 0, 2, 0,0,0,4, 42,42,42, 0], Endianness::BigEndian, TagValue::Ascii("***".into())),
759 ([1,1, 3, 0, 2,0,0,0, 42, 0,42, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Short (42); 2]) ),
760 ([1,1, 0, 3, 0,0,0,2, 0,42, 0,42], Endianness::BigEndian, TagValue::List(vec![TagValue::Short (42); 2]) ),
761 ([1,1, 8, 0, 2,0,0,0, 42, 0,42, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::SignedShort (42); 2]) ),
762 ([1,1, 0, 8, 0,0,0,2, 0,42, 0,42], Endianness::BigEndian, TagValue::List(vec![TagValue::SignedShort (42); 2]) ),
763 ([1,1, 0, 2, 0,0,0,4, b'A',b'B',b'C',0], Endianness::BigEndian, TagValue::Ascii("ABC".into())),
764 ];
766 for (buf, byte_order, res) in cases {
767 println!("testing {buf:?} to be {res:?}");
768 let fetch = Bytes::copy_from_slice(&buf);
769 assert_eq!(
770 read_tag(&fetch, 0, byte_order, false).await.unwrap(),
771 (Tag::from_u16_exhaustive(0x0101), res)
772 )
773 }
774 }
775
776 #[tokio::test]
777 #[rustfmt::skip]
778 async fn test_fits_multi_big() {
779 assert_eq!(u16::from_le_bytes([42,0]),42);
781 assert_eq!(u16::from_be_bytes([0,42]),42);
782
783 assert_eq!(f32::from_le_bytes([0x42,0,0,0]),f32::from_bits(0x00_00_00_42));
784 assert_eq!(f32::from_be_bytes([0,0,0,0x42]),f32::from_bits(0x00_00_00_42));
785 let cases = [
786 ([1,1, 1, 0, 8,0,0,0,0,0,0,0, 42,42,42,42,42,42,42,42], Endianness::LittleEndian, TagValue::List(vec![TagValue::Byte (42) ; 8])),
789 ([1,1, 0, 1, 0,0,0,0,0,0,0,8, 42,42,42,42,42,42,42,42], Endianness::BigEndian, TagValue::List(vec![TagValue::Byte (42) ; 8])),
790 ([1,1, 6, 0, 8,0,0,0,0,0,0,0, 42,42,42,42,42,42,42,42], Endianness::LittleEndian, TagValue::List(vec![TagValue::SignedByte(42) ; 8])),
791 ([1,1, 0, 6, 0,0,0,0,0,0,0,8, 42,42,42,42,42,42,42,42], Endianness::BigEndian, TagValue::List(vec![TagValue::SignedByte(42) ; 8])),
792 ([1,1, 7, 0, 8,0,0,0,0,0,0,0, 42,42,42,42,42,42,42,42], Endianness::LittleEndian, TagValue::List(vec![TagValue::Byte (42) ; 8])), ([1,1, 0, 7, 0,0,0,0,0,0,0,8, 42,42,42,42,42,42,42,42], Endianness::BigEndian, TagValue::List(vec![TagValue::Byte (42) ; 8])), ([1,1, 2, 0, 8,0,0,0,0,0,0,0, 42,42,42,42,42,42,42, 0], Endianness::LittleEndian, TagValue::Ascii ("*******".into() )),
795 ([1,1, 0, 2, 0,0,0,0,0,0,0,8, 42,42,42,42,42,42,42, 0], Endianness::BigEndian, TagValue::Ascii ("*******".into() )),
796 ([1,1, 3, 0, 4,0,0,0,0,0,0,0, 42, 0,42, 0,42, 0,42, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Short (42) ; 4])),
797 ([1,1, 0, 3, 0,0,0,0,0,0,0,4, 0,42, 0,42, 0,42, 0,42], Endianness::BigEndian, TagValue::List(vec![TagValue::Short (42) ; 4])),
798 ([1,1, 8, 0, 4,0,0,0,0,0,0,0, 42, 0,42, 0,42, 0,42, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::SignedShort (42) ; 4])),
799 ([1,1, 0, 8, 0,0,0,0,0,0,0,4, 0,42, 0,42, 0,42, 0,42], Endianness::BigEndian, TagValue::List(vec![TagValue::SignedShort (42) ; 4])),
800 ([1,1, 4, 0, 2,0,0,0,0,0,0,0, 42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Unsigned (42) ; 2])),
801 ([1,1, 0, 4, 0,0,0,0,0,0,0,2, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian, TagValue::List(vec![TagValue::Unsigned (42) ; 2])),
802 ([1,1, 9, 0, 2,0,0,0,0,0,0,0, 42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Signed (42) ; 2])),
803 ([1,1, 0, 9, 0,0,0,0,0,0,0,2, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian, TagValue::List(vec![TagValue::Signed (42) ; 2])),
804 ([1,1,13, 0, 2,0,0,0,0,0,0,0, 42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Ifd (42) ; 2])),
805 ([1,1, 0,13, 0,0,0,0,0,0,0,2, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian, TagValue::List(vec![TagValue::Ifd (42) ; 2])),
806 ([1,1,11, 0, 2,0,0,0,0,0,0,0, 42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Float (f32::from_bits(42)); 2])),
807 ([1,1, 0,11, 0,0,0,0,0,0,0,2, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian, TagValue::List(vec![TagValue::Float (f32::from_bits(42)); 2])),
808 ];
810 for (buf, byte_order, res) in cases {
811 let fetch = Bytes::copy_from_slice(&buf);
812 assert_eq!(
813 read_tag(&fetch, 0, byte_order, true).await.unwrap(),
814 (Tag::from_u16_exhaustive(0x0101), res)
815 )
816 }
817 }
818
819 #[tokio::test]
820 #[rustfmt::skip]
821 async fn test_notfits_notbig() {
822 assert_eq!(u16::from_le_bytes([42,0]),42);
824 assert_eq!(u16::from_be_bytes([0,42]),42);
825
826 assert_eq!(f32::from_le_bytes([0x42,0,0,0]),f32::from_bits(0x00_00_00_42));
827 assert_eq!(f32::from_be_bytes([0,0,0,0x42]),f32::from_bits(0x00_00_00_42));
828 let cases = [
829 (vec![1,1, 1, 0, 5,0,0,0, 12, 0, 0, 0, 42,42,42,42,42], Endianness::LittleEndian, TagValue::List(vec![TagValue::Byte (42 );5])),
832 (vec![1,1, 0, 1, 0,0,0,5, 0, 0, 0,12, 42,42,42,42,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Byte (42 );5])),
833 (vec![1,1, 6, 0, 5,0,0,0, 12, 0, 0, 0, 42,42,42,42,42], Endianness::LittleEndian, TagValue::List(vec![TagValue::SignedByte (42 );5])),
834 (vec![1,1, 0, 6, 0,0,0,5, 0, 0, 0,12, 42,42,42,42,42], Endianness::BigEndian , TagValue::List(vec![TagValue::SignedByte (42 );5])),
835 (vec![1,1, 7, 0, 5,0,0,0, 12, 0, 0, 0, 42,42,42,42,42], Endianness::LittleEndian, TagValue::List(vec![TagValue::Byte (42 );5])), (vec![1,1, 0, 7, 0,0,0,5, 0, 0, 0,12, 42,42,42,42,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Byte (42 );5])), (vec![1,1, 2, 0, 5,0,0,0, 12, 0, 0, 0, 42,42,42,42, 0], Endianness::LittleEndian, TagValue::Ascii ("****".into() ) ),
838 (vec![1,1, 0, 2, 0,0,0,5, 0, 0, 0,12, 42,42,42,42, 0], Endianness::BigEndian , TagValue::Ascii ("****".into() ) ),
839 (vec![1,1, 3, 0, 3,0,0,0, 12, 0, 0, 0, 42, 0,42, 0,42, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Short (42 );3])),
840 (vec![1,1, 0, 3, 0,0,0,3, 0, 0, 0,12, 0,42, 0,42, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Short (42 );3])),
841 (vec![1,1, 8, 0, 3,0,0,0, 12, 0, 0, 0, 42, 0,42, 0,42, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::SignedShort(42 );3])),
842 (vec![1,1, 0, 8, 0,0,0,3, 0, 0, 0,12, 0,42, 0,42, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::SignedShort(42 );3])),
843 (vec![1,1, 4, 0, 2,0,0,0, 12, 0, 0, 0, 42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Unsigned (42 );2])),
844 (vec![1,1, 0, 4, 0,0,0,2, 0, 0, 0,12, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Unsigned (42 );2])),
845 (vec![1,1, 9, 0, 2,0,0,0, 12, 0, 0, 0, 42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Signed (42 );2])),
846 (vec![1,1, 0, 9, 0,0,0,2, 0, 0, 0,12, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Signed (42 );2])),
847 (vec![1,1,13, 0, 2,0,0,0, 12, 0, 0, 0, 42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Ifd (42 );2])),
848 (vec![1,1, 0,13, 0,0,0,2, 0, 0, 0,12, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Ifd (42 );2])),
849 (vec![1,1, 16,0, 1,0,0,0, 12, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::UnsignedBig(42 ) ),
850 (vec![1,1, 0,16, 0,0,0,1, 0, 0, 0,12, 0, 0, 0, 0, 0, 0, 0,42], Endianness::BigEndian , TagValue::UnsignedBig(42 ) ),
851 (vec![1,1, 17,0, 1,0,0,0, 12, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::SignedBig (42 ) ),
852 (vec![1,1, 0,17, 0,0,0,1, 0, 0, 0,12, 0, 0, 0, 0, 0, 0, 0,42], Endianness::BigEndian , TagValue::SignedBig (42 ) ),
853 (vec![1,1, 18,0, 1,0,0,0, 12, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::IfdBig (42 ) ),
854 (vec![1,1, 0,18, 0,0,0,1, 0, 0, 0,12, 0, 0, 0, 0, 0, 0, 0,42], Endianness::BigEndian , TagValue::IfdBig (42 ) ),
855 (vec![1,1, 11,0, 2,0,0,0, 12, 0, 0, 0, 42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Float (f32::from_bits(42) );2])),
856 (vec![1,1, 0,11, 0,0,0,2, 0, 0, 0,12, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Float (f32::from_bits(42) );2])),
857 (vec![1,1, 12,0, 1,0,0,0, 12, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::Double (f64::from_bits(42)) ),
858 (vec![1,1, 0,12, 0,0,0,1, 0, 0, 0,12, 0, 0, 0, 0, 0, 0, 0,42], Endianness::BigEndian , TagValue::Double (f64::from_bits(42)) ),
859 (vec![1,1, 5, 0, 1,0,0,0, 12, 0, 0, 0, 42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::Rational (42, 42 ) ),
860 (vec![1,1, 0, 5, 0,0,0,1, 0, 0, 0,12, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian , TagValue::Rational (42, 42 ) ),
861 (vec![1,1, 10,0, 1,0,0,0, 12, 0, 0, 0, 42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::SRational (42, 42 ) ),
862 (vec![1,1, 0,10, 0,0,0,1, 0, 0, 0,12, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian , TagValue::SRational (42, 42 ) ),
863 ];
864 for (buf, byte_order, res) in cases {
865 println!("reading {buf:?} to be {res:?}");
866 let fetch = Bytes::from_owner(buf);
867 assert_eq!(
868 read_tag(&fetch, 0, byte_order, false).await.unwrap(),
869 (Tag::from_u16_exhaustive(0x0101), res)
870 )
871 }
872 }
873
874 #[tokio::test]
875 #[rustfmt::skip]
876 async fn test_notfits_big() {
877 assert_eq!(u16::from_le_bytes([42,0]),42);
879 assert_eq!(u16::from_be_bytes([0,42]),42);
880 assert_eq!(f32::from_le_bytes([0x42,0,0,0]),f32::from_bits(0x00_00_00_42));
881 assert_eq!(f32::from_be_bytes([0,0,0,0x42]),f32::from_bits(0x00_00_00_42));
882 let cases = [
883 (vec![1,1, 1, 0, 9,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42,42,42,42,42,42,42,42,42], Endianness::LittleEndian, TagValue::List(vec![TagValue::Byte (42 );9])),
886 (vec![1,1, 0, 1, 0,0,0,0,0,0,0,9, 0, 0, 0, 0, 0, 0, 0,20, 42,42,42,42,42,42,42,42,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Byte (42 );9])),
887 (vec![1,1, 6, 0, 9,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42,42,42,42,42,42,42,42,42], Endianness::LittleEndian, TagValue::List(vec![TagValue::SignedByte (42 );9])),
888 (vec![1,1, 0, 6, 0,0,0,0,0,0,0,9, 0, 0, 0, 0, 0, 0, 0,20, 42,42,42,42,42,42,42,42,42], Endianness::BigEndian , TagValue::List(vec![TagValue::SignedByte (42 );9])),
889 (vec![1,1, 7, 0, 9,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42,42,42,42,42,42,42,42,42], Endianness::LittleEndian, TagValue::List(vec![TagValue::Byte (42 );9])), (vec![1,1, 0, 7, 0,0,0,0,0,0,0,9, 0, 0, 0, 0, 0, 0, 0,20, 42,42,42,42,42,42,42,42,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Byte (42 );9])), (vec![1,1, 2, 0, 9,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42,42,42,42,42,42,42,42, 0], Endianness::LittleEndian, TagValue::Ascii ("********".into() ) ),
892 (vec![1,1, 0, 2, 0,0,0,0,0,0,0,9, 0, 0, 0, 0, 0, 0, 0,20, 42,42,42,42,42,42,42,42, 0], Endianness::BigEndian , TagValue::Ascii ("********".into() ) ),
893 (vec![1,1, 3, 0, 5,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42, 0,42, 0,42, 0,42, 0,42, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Short (42 );5])),
894 (vec![1,1, 0, 3, 0,0,0,0,0,0,0,5, 0, 0, 0, 0, 0, 0, 0,20, 0,42, 0,42, 0,42, 0,42, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Short (42 );5])),
895 (vec![1,1, 8, 0, 5,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42, 0,42, 0,42, 0,42, 0,42, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::SignedShort(42 );5])),
896 (vec![1,1, 0, 8, 0,0,0,0,0,0,0,5, 0, 0, 0, 0, 0, 0, 0,20, 0,42, 0,42, 0,42, 0,42, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::SignedShort(42 );5])),
897 (vec![1,1, 4, 0, 3,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Unsigned (42 );3])),
898 (vec![1,1, 0, 4, 0,0,0,0,0,0,0,3, 0, 0, 0, 0, 0, 0, 0,20, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Unsigned (42 );3])),
899 (vec![1,1, 9, 0, 3,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Signed (42 );3])),
900 (vec![1,1, 0, 9, 0,0,0,0,0,0,0,3, 0, 0, 0, 0, 0, 0, 0,20, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Signed (42 );3])),
901 (vec![1,1, 13, 0, 3,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Ifd (42 );3])),
902 (vec![1,1, 0,13, 0,0,0,0,0,0,0,3, 0, 0, 0, 0, 0, 0, 0,20, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Ifd (42 );3])),
903 (vec![1,1, 16, 0, 2,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0,42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::UnsignedBig(42 );2])),
904 (vec![1,1, 0,16, 0,0,0,0,0,0,0,2, 0, 0, 0, 0, 0, 0, 0,20, 0, 0, 0, 0, 0, 0, 0,42, 0, 0, 0, 0, 0, 0, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::UnsignedBig(42 );2])),
905 (vec![1,1, 17, 0, 2,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0,42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::SignedBig (42 );2])),
906 (vec![1,1, 0,17, 0,0,0,0,0,0,0,2, 0, 0, 0, 0, 0, 0, 0,20, 0, 0, 0, 0, 0, 0, 0,42, 0, 0, 0, 0, 0, 0, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::SignedBig (42 );2])),
907 (vec![1,1, 18, 0, 2,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0,42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::IfdBig (42 );2])),
908 (vec![1,1, 0,18, 0,0,0,0,0,0,0,2, 0, 0, 0, 0, 0, 0, 0,20, 0, 0, 0, 0, 0, 0, 0,42, 0, 0, 0, 0, 0, 0, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::IfdBig (42 );2])),
909 (vec![1,1, 11, 0, 3,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0,], Endianness::LittleEndian, TagValue::List(vec![TagValue::Float (f32::from_bits(42));3])),
910 (vec![1,1, 0,11, 0,0,0,0,0,0,0,3, 0, 0, 0, 0, 0, 0, 0,20, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0,42,], Endianness::BigEndian , TagValue::List(vec![TagValue::Float (f32::from_bits(42));3])),
911 (vec![1,1, 12, 0, 2,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0,42, 0, 0, 0, 0, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Double (f64::from_bits(42));2])),
912 (vec![1,1, 0,12, 0,0,0,0,0,0,0,2, 0, 0, 0, 0, 0, 0, 0,20, 0, 0, 0, 0, 0, 0, 0,42, 0, 0, 0, 0, 0, 0, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Double (f64::from_bits(42));2])),
913 (vec![1,1, 5, 0, 2,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::Rational (42, 42 );2])),
914 (vec![1,1, 0, 5, 0,0,0,0,0,0,0,2, 0, 0, 0, 0, 0, 0, 0,20, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::Rational (42, 42 );2])),
915 (vec![1,1, 10, 0, 2,0,0,0,0,0,0,0, 20, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0], Endianness::LittleEndian, TagValue::List(vec![TagValue::SRational (42, 42 );2])),
916 (vec![1,1, 0,10, 0,0,0,0,0,0,0,2, 0, 0, 0, 0, 0, 0, 0,20, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0,42, 0, 0, 0,42], Endianness::BigEndian , TagValue::List(vec![TagValue::SRational (42, 42 );2])),
917 ];
918 for (buf, byte_order, res) in cases {
919 println!("reading {buf:?} to be {res:?}");
920 let fetch = Bytes::from_owner(buf);
921 assert_eq!(read_tag(&fetch, 0, byte_order, true).await.unwrap(), (Tag::from_u16_exhaustive(0x0101), res))
922 }
923 }
924}