|
1 | 1 | use crate::config::ParseOptions;
|
2 |
| -use crate::ebml::element_reader::ElementReader; |
3 |
| -use crate::ebml::EbmlTag; |
| 2 | +use crate::ebml::element_reader::{ElementIdent, ElementReader, ElementReaderYield}; |
| 3 | +use crate::ebml::{AttachedFile, EbmlTag}; |
4 | 4 | use crate::error::Result;
|
| 5 | +use crate::macros::decode_err; |
| 6 | +use crate::picture::MimeType; |
5 | 7 |
|
6 | 8 | use std::io::{Read, Seek};
|
7 | 9 |
|
8 | 10 | pub(super) fn read_from<R>(
|
9 |
| - _element_reader: &mut ElementReader<R>, |
| 11 | + element_reader: &mut ElementReader<R>, |
10 | 12 | _parse_options: ParseOptions,
|
11 |
| - _tag: &mut EbmlTag, |
| 13 | + tag: &mut EbmlTag, |
12 | 14 | ) -> Result<()>
|
13 | 15 | where
|
14 | 16 | R: Read + Seek,
|
15 | 17 | {
|
16 |
| - unimplemented!("\\Ebml\\Segment\\Attachments") |
| 18 | + let mut children_reader = element_reader.children(); |
| 19 | + |
| 20 | + while let Some(child) = children_reader.next()? { |
| 21 | + match child { |
| 22 | + ElementReaderYield::Master((ElementIdent::AttachedFile, size)) => { |
| 23 | + let attached_file = read_attachment(&mut children_reader)?; |
| 24 | + tag.attached_files.push(attached_file); |
| 25 | + }, |
| 26 | + ElementReaderYield::Eof => break, |
| 27 | + _ => unreachable!("Unhandled child element in \\Ebml\\Segment\\Attachments: {child:?}"), |
| 28 | + } |
| 29 | + } |
| 30 | + |
| 31 | + Ok(()) |
| 32 | +} |
| 33 | + |
| 34 | +fn read_attachment<R>(element_reader: &mut ElementReader<R>) -> Result<AttachedFile> |
| 35 | +where |
| 36 | + R: Read + Seek, |
| 37 | +{ |
| 38 | + let mut description = None; |
| 39 | + let mut file_name = None; |
| 40 | + let mut mime_type = None; |
| 41 | + let mut file_data = None; |
| 42 | + let mut uid = None; |
| 43 | + let mut referral = None; |
| 44 | + let mut used_start_time = None; |
| 45 | + let mut used_end_time = None; |
| 46 | + |
| 47 | + let mut children_reader = element_reader.children(); |
| 48 | + while let Some(child) = children_reader.next()? { |
| 49 | + let ElementReaderYield::Child((child, size)) = child else { |
| 50 | + match child { |
| 51 | + ElementReaderYield::Eof => break, |
| 52 | + _ => unreachable!( |
| 53 | + "Unhandled child element in \\Ebml\\Segment\\Attachments\\AttachedFile: \ |
| 54 | + {child:?}" |
| 55 | + ), |
| 56 | + } |
| 57 | + }; |
| 58 | + |
| 59 | + let size = size.value(); |
| 60 | + match child.ident { |
| 61 | + ElementIdent::FileDescription => { |
| 62 | + description = Some(children_reader.read_string(size)?); |
| 63 | + }, |
| 64 | + ElementIdent::FileName => { |
| 65 | + file_name = Some(children_reader.read_string(size)?); |
| 66 | + }, |
| 67 | + ElementIdent::FileMimeType => { |
| 68 | + let mime_str = children_reader.read_string(size)?; |
| 69 | + mime_type = Some(MimeType::from_str(&mime_str)); |
| 70 | + }, |
| 71 | + ElementIdent::FileData => { |
| 72 | + file_data = Some(children_reader.read_binary(size)?); |
| 73 | + }, |
| 74 | + ElementIdent::FileUID => { |
| 75 | + uid = Some(children_reader.read_unsigned_int(size)?); |
| 76 | + }, |
| 77 | + ElementIdent::FileReferral => { |
| 78 | + referral = Some(children_reader.read_string(size)?); |
| 79 | + }, |
| 80 | + ElementIdent::FileUsedStartTime => { |
| 81 | + used_start_time = Some(children_reader.read_unsigned_int(size)?); |
| 82 | + }, |
| 83 | + ElementIdent::FileUsedEndTime => { |
| 84 | + used_end_time = Some(children_reader.read_unsigned_int(size)?); |
| 85 | + }, |
| 86 | + _ => unreachable!( |
| 87 | + "Unhandled child element in \\Ebml\\Segment\\Attachments\\AttachedFile: {child:?}" |
| 88 | + ), |
| 89 | + } |
| 90 | + } |
| 91 | + |
| 92 | + let Some(file_name) = file_name else { |
| 93 | + decode_err!(@BAIL Ebml, "File name is required for an attached file"); |
| 94 | + }; |
| 95 | + |
| 96 | + let Some(mime_type) = mime_type else { |
| 97 | + decode_err!(@BAIL Ebml, "MIME type is required for an attached file"); |
| 98 | + }; |
| 99 | + |
| 100 | + let Some(file_data) = file_data else { |
| 101 | + decode_err!(@BAIL Ebml, "File data is required for an attached file"); |
| 102 | + }; |
| 103 | + |
| 104 | + let Some(uid) = uid else { |
| 105 | + decode_err!(@BAIL Ebml, "UID is required for an attached file"); |
| 106 | + }; |
| 107 | + |
| 108 | + Ok(AttachedFile { |
| 109 | + description, |
| 110 | + file_name, |
| 111 | + mime_type, |
| 112 | + file_data, |
| 113 | + uid, |
| 114 | + referral, |
| 115 | + used_start_time, |
| 116 | + used_end_time, |
| 117 | + }) |
17 | 118 | }
|
0 commit comments