Skip to content

Commit 782209c

Browse files
committed
aud_io: Move AtomInfo and AtomIdent from lofty
1 parent 2227b09 commit 782209c

File tree

14 files changed

+98
-74
lines changed

14 files changed

+98
-74
lines changed

aud_io/src/error.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,20 @@ pub enum AudioError {
88
// File data related errors
99
/// Attempting to read/write an abnormally large amount of data
1010
TooMuchData,
11+
/// Expected the data to be a different size than provided
12+
///
13+
/// This occurs when the size of an item is written as one value, but that size is either too
14+
/// big or small to be valid within the bounds of that item.
15+
// TODO: Should probably have context
16+
SizeMismatch,
1117

1218
/// Errors that arise while decoding text
1319
TextDecode(&'static str),
1420

21+
// Format-specific
22+
/// Arises when an MP4 atom contains invalid data
23+
BadAtom(&'static str),
24+
1525
// Conversions for external errors
1626
/// Represents all cases of [`std::io::Error`].
1727
Io(std::io::Error),
@@ -72,6 +82,13 @@ impl Display for AudioError {
7282
f,
7383
"Attempted to read/write an abnormally large amount of data"
7484
),
85+
AudioError::SizeMismatch => write!(
86+
f,
87+
"Encountered an invalid item size, either too big or too small to be valid"
88+
),
89+
90+
// Format-specific
91+
AudioError::BadAtom(message) => write!(f, "MP4 Atom: {message}"),
7592
}
7693
}
7794
}

aud_io/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ pub mod math;
55
pub mod io;
66
pub mod config;
77
pub mod alloc;
8+
pub mod mp4;

aud_io/src/macros.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
#[macro_export]
2+
macro_rules! try_vec {
3+
($elem:expr; $size:expr) => {{ $crate::alloc::fallible_vec_from_element($elem, $size)? }};
4+
}
5+
16
// Shorthand for `return Err(AudioError::Foo)`
27
//
38
// Usage:

lofty/src/mp4/atom_info.rs renamed to aud_io/src/mp4/atom_info.rs

Lines changed: 19 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
use crate::config::ParsingMode;
2-
use crate::error::{ErrorKind, LoftyError, Result};
3-
use crate::macros::{err, try_vec};
4-
use crate::tag::{ItemKey, TagType};
2+
use crate::error::{AudioError, Result};
3+
use crate::text::utf8_decode;
4+
use crate::{err, try_vec};
55

66
use std::borrow::Cow;
77
use std::io::{Read, Seek, SeekFrom};
88

9-
use aud_io::text::utf8_decode;
10-
use aud_io::err as io_err;
119
use byteorder::{BigEndian, ReadBytesExt};
1210

13-
pub(super) const FOURCC_LEN: u64 = 4;
14-
pub(super) const IDENTIFIER_LEN: u64 = 4;
15-
pub(super) const ATOM_HEADER_LEN: u64 = FOURCC_LEN + IDENTIFIER_LEN;
11+
pub const FOURCC_LEN: u64 = 4;
12+
pub const IDENTIFIER_LEN: u64 = 4;
13+
pub const ATOM_HEADER_LEN: u64 = FOURCC_LEN + IDENTIFIER_LEN;
1614

1715
/// Represents an `MP4` atom identifier
1816
#[derive(Eq, PartialEq, Debug, Clone)]
@@ -64,55 +62,12 @@ impl<'a> AtomIdent<'a> {
6462
}
6563
}
6664

67-
impl<'a> TryFrom<&'a ItemKey> for AtomIdent<'a> {
68-
type Error = LoftyError;
69-
70-
fn try_from(value: &'a ItemKey) -> std::result::Result<Self, Self::Error> {
71-
if let Some(mapped_key) = value.map_key(TagType::Mp4Ilst) {
72-
if mapped_key.starts_with("----") {
73-
let mut split = mapped_key.split(':');
74-
75-
split.next();
76-
77-
let mean = split.next();
78-
let name = split.next();
79-
80-
if let (Some(mean), Some(name)) = (mean, name) {
81-
return Ok(AtomIdent::Freeform {
82-
mean: Cow::Borrowed(mean),
83-
name: Cow::Borrowed(name),
84-
});
85-
}
86-
} else {
87-
let fourcc = mapped_key.chars().map(|c| c as u8).collect::<Vec<_>>();
88-
89-
if let Ok(fourcc) = TryInto::<[u8; 4]>::try_into(fourcc) {
90-
return Ok(AtomIdent::Fourcc(fourcc));
91-
}
92-
}
93-
}
94-
95-
io_err!(TextDecode(
96-
"ItemKey does not map to a freeform or fourcc identifier"
97-
))
98-
}
99-
}
100-
101-
impl TryFrom<ItemKey> for AtomIdent<'static> {
102-
type Error = LoftyError;
103-
104-
fn try_from(value: ItemKey) -> std::result::Result<Self, Self::Error> {
105-
let ret: AtomIdent<'_> = (&value).try_into()?;
106-
Ok(ret.into_owned())
107-
}
108-
}
109-
11065
#[derive(Debug)]
111-
pub(crate) struct AtomInfo {
112-
pub(crate) start: u64,
113-
pub(crate) len: u64,
114-
pub(crate) extended: bool,
115-
pub(crate) ident: AtomIdent<'static>,
66+
pub struct AtomInfo {
67+
pub start: u64,
68+
pub len: u64,
69+
pub extended: bool,
70+
pub ident: AtomIdent<'static>,
11671
}
11772

11873
// The spec permits any characters to be used in atom identifiers. This doesn't
@@ -125,7 +80,7 @@ fn is_valid_identifier_byte(b: u8) -> bool {
12580
}
12681

12782
impl AtomInfo {
128-
pub(crate) fn read<R>(
83+
pub fn read<R>(
12984
data: &mut R,
13085
mut reader_size: u64,
13186
parse_mode: ParsingMode,
@@ -214,7 +169,7 @@ impl AtomInfo {
214169
}))
215170
}
216171

217-
pub(crate) fn header_size(&self) -> u64 {
172+
pub fn header_size(&self) -> u64 {
218173
if !self.extended {
219174
return ATOM_HEADER_LEN;
220175
}
@@ -261,10 +216,10 @@ where
261216

262217
match atom {
263218
Some(AtomInfo {
264-
ident: AtomIdent::Fourcc(ref fourcc),
265-
len,
266-
..
267-
}) if fourcc == name => {
219+
ident: AtomIdent::Fourcc(ref fourcc),
220+
len,
221+
..
222+
}) if fourcc == name => {
268223
if len < 12 {
269224
err!(BadAtom("Found an incomplete freeform identifier chunk"));
270225
}
@@ -284,9 +239,9 @@ where
284239
*reader_size -= len;
285240

286241
utf8_decode(content).map_err(|_| {
287-
LoftyError::new(ErrorKind::BadAtom(
242+
AudioError::BadAtom(
288243
"Found a non UTF-8 string while reading freeform identifier",
289-
))
244+
)
290245
})
291246
},
292247
_ => err!(BadAtom(

aud_io/src/mp4/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
mod atom_info;
2+
pub use atom_info::*;

lofty/src/mp4/ilst/mod.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use std::borrow::Cow;
2424
use std::io::Write;
2525
use std::ops::Deref;
2626

27+
use aud_io::err as io_err;
2728
use aud_io::io::{FileLike, Length, Truncate};
2829
use lofty_attr::tag;
2930

@@ -885,6 +886,49 @@ impl From<Tag> for Ilst {
885886
}
886887
}
887888

889+
impl<'a> TryFrom<&'a ItemKey> for AtomIdent<'a> {
890+
type Error = LoftyError;
891+
892+
fn try_from(value: &'a ItemKey) -> std::result::Result<Self, Self::Error> {
893+
if let Some(mapped_key) = value.map_key(TagType::Mp4Ilst) {
894+
if mapped_key.starts_with("----") {
895+
let mut split = mapped_key.split(':');
896+
897+
split.next();
898+
899+
let mean = split.next();
900+
let name = split.next();
901+
902+
if let (Some(mean), Some(name)) = (mean, name) {
903+
return Ok(AtomIdent::Freeform {
904+
mean: Cow::Borrowed(mean),
905+
name: Cow::Borrowed(name),
906+
});
907+
}
908+
} else {
909+
let fourcc = mapped_key.chars().map(|c| c as u8).collect::<Vec<_>>();
910+
911+
if let Ok(fourcc) = TryInto::<[u8; 4]>::try_into(fourcc) {
912+
return Ok(AtomIdent::Fourcc(fourcc));
913+
}
914+
}
915+
}
916+
917+
io_err!(TextDecode(
918+
"ItemKey does not map to a freeform or fourcc identifier"
919+
))
920+
}
921+
}
922+
923+
impl TryFrom<ItemKey> for AtomIdent<'static> {
924+
type Error = LoftyError;
925+
926+
fn try_from(value: ItemKey) -> std::result::Result<Self, Self::Error> {
927+
let ret: AtomIdent<'_> = (&value).try_into()?;
928+
Ok(ret.into_owned())
929+
}
930+
}
931+
888932
#[cfg(test)]
889933
mod tests {
890934
use crate::config::{ParseOptions, ParsingMode, WriteOptions};

lofty/src/mp4/ilst/read.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use crate::config::{ParseOptions, ParsingMode};
55
use crate::error::{LoftyError, Result};
66
use crate::id3::v1::constants::GENRES;
77
use crate::macros::{err, try_vec};
8-
use crate::mp4::atom_info::{ATOM_HEADER_LEN, AtomInfo};
98
use crate::mp4::ilst::atom::AtomDataStorage;
109
use crate::mp4::read::{AtomReader, skip_atom};
1110
use crate::picture::{MimeType, Picture, PictureType};
@@ -15,6 +14,7 @@ use std::borrow::Cow;
1514
use std::io::{Cursor, Read, Seek, SeekFrom};
1615

1716
use aud_io::text::{utf8_decode, utf16_decode_bytes};
17+
use aud_io::mp4::{ATOM_HEADER_LEN, AtomInfo};
1818

1919
pub(in crate::mp4) fn parse_ilst<R>(
2020
reader: &mut AtomReader<R>,

lofty/src/mp4/ilst/write.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ use crate::error::{FileEncodingError, LoftyError, Result};
55
use crate::file::FileType;
66
use crate::macros::{decode_err, try_vec};
77
use crate::mp4::AtomData;
8-
use crate::mp4::atom_info::{ATOM_HEADER_LEN, AtomIdent, AtomInfo, FOURCC_LEN};
98
use crate::mp4::ilst::r#ref::AtomRef;
109
use crate::mp4::read::{AtomReader, atom_tree, find_child_atom, meta_is_full, verify_mp4};
1110
use crate::mp4::write::{AtomWriter, AtomWriterCompanion, ContextualAtom};
1211
use crate::picture::{MimeType, Picture};
1312

1413
use std::io::{Cursor, Seek, SeekFrom, Write};
1514

15+
use aud_io::mp4::{ATOM_HEADER_LEN, AtomIdent, AtomInfo, FOURCC_LEN};
1616
use aud_io::err as io_err;
1717
use aud_io::io::{FileLike, Length, Truncate};
1818
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};

lofty/src/mp4/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
//! ## File notes
44
//!
55
//! The only supported tag format is [`Ilst`].
6-
mod atom_info;
76
pub(crate) mod ilst;
87
mod moov;
98
mod properties;
@@ -22,7 +21,7 @@ pub mod constants {
2221
}
2322

2423
pub use crate::mp4::properties::{AudioObjectType, Mp4Codec, Mp4Properties};
25-
pub use atom_info::AtomIdent;
24+
pub use aud_io::mp4::AtomIdent;
2625
pub use ilst::Ilst;
2726
pub use ilst::advisory_rating::AdvisoryRating;
2827
pub use ilst::atom::{Atom, AtomData};

lofty/src/mp4/moov.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use super::atom_info::{AtomIdent, AtomInfo};
21
use super::ilst::Ilst;
32
use super::ilst::read::parse_ilst;
43
use super::read::{AtomReader, find_child_atom, meta_is_full, skip_atom};
@@ -8,6 +7,8 @@ use crate::macros::decode_err;
87

98
use std::io::{Read, Seek};
109

10+
use aud_io::mp4::{AtomIdent, AtomInfo};
11+
1112
pub(crate) struct Moov {
1213
// Represents the trak.mdia atom
1314
pub(crate) traks: Vec<AtomInfo>,

0 commit comments

Comments
 (0)