mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-11-10 14:44:22 +00:00
ID3v2: Move all header related items to v2::header module
This commit is contained in:
parent
553d16fa88
commit
bdfe1a8cfc
18 changed files with 175 additions and 172 deletions
|
@ -1,8 +1,8 @@
|
|||
use super::header::{ADTSHeader, HEADER_MASK};
|
||||
use super::AacFile;
|
||||
use crate::error::Result;
|
||||
use crate::id3::v2::header::Id3v2Header;
|
||||
use crate::id3::v2::read::parse_id3v2;
|
||||
use crate::id3::v2::read_id3v2_header;
|
||||
use crate::id3::{find_id3v1, ID3FindResults};
|
||||
use crate::macros::{decode_err, parse_mode_choice};
|
||||
use crate::mpeg::header::{cmp_header, search_for_frame_sync, HeaderCmpResult};
|
||||
|
@ -43,7 +43,7 @@ where
|
|||
// Seek back to read the tag in full
|
||||
reader.seek(SeekFrom::Current(-4))?;
|
||||
|
||||
let header = read_id3v2_header(reader)?;
|
||||
let header = Id3v2Header::parse(reader)?;
|
||||
let skip_footer = header.flags.footer;
|
||||
|
||||
stream_len -= u64::from(header.size);
|
||||
|
|
|
@ -8,7 +8,7 @@ pub mod v2;
|
|||
|
||||
use crate::error::{ErrorKind, LoftyError, Result};
|
||||
use crate::macros::try_vec;
|
||||
use v2::{read_id3v2_header, Id3v2Header};
|
||||
use v2::header::Id3v2Header;
|
||||
|
||||
use std::io::{Read, Seek, SeekFrom};
|
||||
use std::ops::Neg;
|
||||
|
@ -92,7 +92,7 @@ where
|
|||
let mut header = None;
|
||||
let mut id3v2 = None;
|
||||
|
||||
if let Ok(id3v2_header) = read_id3v2_header(data) {
|
||||
if let Ok(id3v2_header) = Id3v2Header::parse(data) {
|
||||
if read {
|
||||
let mut tag = try_vec![0; id3v2_header.size as usize];
|
||||
data.read_exact(&mut tag)?;
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
use super::restrictions::TagRestrictions;
|
||||
|
||||
/// Flags that apply to the entire tag
|
||||
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct Id3v2TagFlags {
|
||||
/// Whether or not all frames are unsynchronised. See [`FrameFlags::unsynchronisation`](crate::id3::v2::FrameFlags::unsynchronisation)
|
||||
pub unsynchronisation: bool,
|
||||
/// Indicates if the tag is in an experimental stage
|
||||
pub experimental: bool,
|
||||
/// Indicates that the tag includes a footer
|
||||
///
|
||||
/// A footer will be created if the tag is written
|
||||
pub footer: bool,
|
||||
/// Whether or not to include a CRC-32 in the extended header
|
||||
///
|
||||
/// This is calculated if the tag is written
|
||||
pub crc: bool,
|
||||
/// Restrictions on the tag, written in the extended header
|
||||
///
|
||||
/// In addition to being setting this flag, all restrictions must be provided. See [`TagRestrictions`]
|
||||
pub restrictions: Option<TagRestrictions>,
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
use crate::error::{Id3v2Error, Id3v2ErrorKind, Result};
|
||||
use crate::id3::v2::frame::FrameValue;
|
||||
use crate::id3::v2::header::Id3v2Version;
|
||||
use crate::id3::v2::items::{
|
||||
AttachedPictureFrame, CommentFrame, EventTimingCodesFrame, ExtendedTextFrame, ExtendedUrlFrame,
|
||||
KeyValueFrame, OwnershipFrame, Popularimeter, PrivateFrame, RelativeVolumeAdjustmentFrame,
|
||||
TextInformationFrame, UniqueFileIdentifierFrame, UnsynchronizedTextFrame, UrlLinkFrame,
|
||||
};
|
||||
use crate::id3::v2::Id3v2Version;
|
||||
use crate::macros::err;
|
||||
use crate::probe::ParsingMode;
|
||||
use crate::util::text::TextEncoding;
|
||||
|
|
|
@ -3,13 +3,13 @@ mod header;
|
|||
pub(super) mod id;
|
||||
pub(super) mod read;
|
||||
|
||||
use super::header::Id3v2Version;
|
||||
use super::items::{
|
||||
AttachedPictureFrame, CommentFrame, EventTimingCodesFrame, ExtendedTextFrame, ExtendedUrlFrame,
|
||||
KeyValueFrame, OwnershipFrame, Popularimeter, PrivateFrame, RelativeVolumeAdjustmentFrame,
|
||||
TextInformationFrame, UniqueFileIdentifierFrame, UnsynchronizedTextFrame, UrlLinkFrame,
|
||||
};
|
||||
use super::util::upgrade::{upgrade_v2, upgrade_v3};
|
||||
use super::Id3v2Version;
|
||||
use crate::error::{ErrorKind, Id3v2Error, Id3v2ErrorKind, LoftyError, Result};
|
||||
use crate::tag::item::{ItemKey, ItemValue, TagItem};
|
||||
use crate::tag::TagType;
|
||||
|
|
|
@ -2,8 +2,9 @@ use super::header::{parse_header, parse_v2_header};
|
|||
use super::Frame;
|
||||
use crate::error::{Id3v2Error, Id3v2ErrorKind, Result};
|
||||
use crate::id3::v2::frame::content::parse_content;
|
||||
use crate::id3::v2::header::Id3v2Version;
|
||||
use crate::id3::v2::util::synchsafe::{SynchsafeInteger, UnsynchronizedStream};
|
||||
use crate::id3::v2::{FrameFlags, FrameId, FrameValue, Id3v2Version};
|
||||
use crate::id3::v2::{FrameFlags, FrameId, FrameValue};
|
||||
use crate::macros::try_vec;
|
||||
use crate::probe::ParsingMode;
|
||||
|
||||
|
|
141
src/id3/v2/header.rs
Normal file
141
src/id3/v2/header.rs
Normal file
|
@ -0,0 +1,141 @@
|
|||
use crate::error::{Id3v2Error, Id3v2ErrorKind, Result};
|
||||
use crate::id3::v2::restrictions::TagRestrictions;
|
||||
use crate::id3::v2::util::synchsafe::SynchsafeInteger;
|
||||
use crate::macros::err;
|
||||
|
||||
use std::io::Read;
|
||||
|
||||
use byteorder::{BigEndian, ByteOrder, ReadBytesExt};
|
||||
|
||||
/// The ID3v2 version
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
|
||||
pub enum Id3v2Version {
|
||||
/// ID3v2.2
|
||||
V2,
|
||||
/// ID3v2.3
|
||||
V3,
|
||||
/// ID3v2.4
|
||||
V4,
|
||||
}
|
||||
|
||||
/// Flags that apply to the entire tag
|
||||
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct Id3v2TagFlags {
|
||||
/// Whether or not all frames are unsynchronised. See [`FrameFlags::unsynchronisation`](crate::id3::v2::FrameFlags::unsynchronisation)
|
||||
pub unsynchronisation: bool,
|
||||
/// Indicates if the tag is in an experimental stage
|
||||
pub experimental: bool,
|
||||
/// Indicates that the tag includes a footer
|
||||
///
|
||||
/// A footer will be created if the tag is written
|
||||
pub footer: bool,
|
||||
/// Whether or not to include a CRC-32 in the extended header
|
||||
///
|
||||
/// This is calculated if the tag is written
|
||||
pub crc: bool,
|
||||
/// Restrictions on the tag, written in the extended header
|
||||
///
|
||||
/// In addition to being setting this flag, all restrictions must be provided. See [`TagRestrictions`]
|
||||
pub restrictions: Option<TagRestrictions>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub(crate) struct Id3v2Header {
|
||||
pub version: Id3v2Version,
|
||||
pub flags: Id3v2TagFlags,
|
||||
pub size: u32,
|
||||
pub extended_size: u32,
|
||||
}
|
||||
|
||||
impl Id3v2Header {
|
||||
pub(crate) fn parse<R>(bytes: &mut R) -> Result<Self>
|
||||
where
|
||||
R: Read,
|
||||
{
|
||||
let mut header = [0; 10];
|
||||
bytes.read_exact(&mut header)?;
|
||||
|
||||
if &header[..3] != b"ID3" {
|
||||
err!(FakeTag);
|
||||
}
|
||||
|
||||
// Version is stored as [major, minor], but here we don't care about minor revisions unless there's an error.
|
||||
let version = match header[3] {
|
||||
2 => Id3v2Version::V2,
|
||||
3 => Id3v2Version::V3,
|
||||
4 => Id3v2Version::V4,
|
||||
major => {
|
||||
return Err(
|
||||
Id3v2Error::new(Id3v2ErrorKind::BadId3v2Version(major, header[4])).into(),
|
||||
)
|
||||
},
|
||||
};
|
||||
|
||||
let flags = header[5];
|
||||
|
||||
// Compression was a flag only used in ID3v2.2 (bit 2).
|
||||
// At the time the ID3v2.2 specification was written, a compression scheme wasn't decided.
|
||||
// The spec recommends just ignoring the tag in this case.
|
||||
if version == Id3v2Version::V2 && flags & 0x40 == 0x40 {
|
||||
return Err(Id3v2Error::new(Id3v2ErrorKind::V2Compression).into());
|
||||
}
|
||||
|
||||
let mut flags_parsed = Id3v2TagFlags {
|
||||
unsynchronisation: flags & 0x80 == 0x80,
|
||||
experimental: (version == Id3v2Version::V4 || version == Id3v2Version::V3)
|
||||
&& flags & 0x20 == 0x20,
|
||||
footer: (version == Id3v2Version::V4 || version == Id3v2Version::V3)
|
||||
&& flags & 0x10 == 0x10,
|
||||
crc: false, // Retrieved later if applicable
|
||||
restrictions: None, // Retrieved later if applicable
|
||||
};
|
||||
|
||||
let size = BigEndian::read_u32(&header[6..]).unsynch();
|
||||
let mut extended_size = 0;
|
||||
|
||||
let extended_header =
|
||||
(version == Id3v2Version::V4 || version == Id3v2Version::V3) && flags & 0x40 == 0x40;
|
||||
|
||||
if extended_header {
|
||||
extended_size = bytes.read_u32::<BigEndian>()?.unsynch();
|
||||
|
||||
if extended_size < 6 {
|
||||
return Err(Id3v2Error::new(Id3v2ErrorKind::BadExtendedHeaderSize).into());
|
||||
}
|
||||
|
||||
// Useless byte since there's only 1 byte for flags
|
||||
let _num_flag_bytes = bytes.read_u8()?;
|
||||
|
||||
let extended_flags = bytes.read_u8()?;
|
||||
|
||||
// The only flags we care about here are the CRC and restrictions
|
||||
|
||||
if extended_flags & 0x20 == 0x20 {
|
||||
flags_parsed.crc = true;
|
||||
|
||||
// We don't care about the existing CRC (5) or its length byte (1)
|
||||
let mut crc = [0; 6];
|
||||
bytes.read_exact(&mut crc)?;
|
||||
}
|
||||
|
||||
if extended_flags & 0x10 == 0x10 {
|
||||
// We don't care about the length byte, it is always 1
|
||||
let _data_length = bytes.read_u8()?;
|
||||
|
||||
flags_parsed.restrictions = Some(TagRestrictions::from_byte(bytes.read_u8()?));
|
||||
}
|
||||
}
|
||||
|
||||
if extended_size > 0 && extended_size >= size {
|
||||
return Err(Id3v2Error::new(Id3v2ErrorKind::BadExtendedHeaderSize).into());
|
||||
}
|
||||
|
||||
Ok(Id3v2Header {
|
||||
version,
|
||||
flags: flags_parsed,
|
||||
size,
|
||||
extended_size,
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
use crate::error::{Id3v2Error, Id3v2ErrorKind, Result};
|
||||
use crate::id3::v2::Id3v2Version;
|
||||
use crate::id3::v2::header::Id3v2Version;
|
||||
use crate::macros::err;
|
||||
use crate::picture::{MimeType, Picture, PictureType};
|
||||
use crate::util::text::{encode_text, TextEncoding};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::error::{Id3v2Error, Id3v2ErrorKind, LoftyError, Result};
|
||||
use crate::id3::v2::frame::content::verify_encoding;
|
||||
use crate::id3::v2::Id3v2Version;
|
||||
use crate::id3::v2::header::Id3v2Version;
|
||||
use crate::util::text::{decode_text, encode_text, read_to_terminator, utf16_decode, TextEncoding};
|
||||
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::error::Result;
|
||||
use crate::id3::v2::frame::content::verify_encoding;
|
||||
use crate::id3::v2::Id3v2Version;
|
||||
use crate::id3::v2::header::Id3v2Version;
|
||||
use crate::util::text::{decode_text, encode_text, TextEncoding};
|
||||
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::error::Result;
|
||||
use crate::id3::v2::frame::content::verify_encoding;
|
||||
use crate::id3::v2::Id3v2Version;
|
||||
use crate::id3::v2::header::Id3v2Version;
|
||||
use crate::util::text::{decode_text, encode_text, TextEncoding};
|
||||
|
||||
use byteorder::ReadBytesExt;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::error::{Id3v2Error, Id3v2ErrorKind, Result};
|
||||
use crate::id3::v2::frame::content::verify_encoding;
|
||||
use crate::id3::v2::Id3v2Version;
|
||||
use crate::id3::v2::header::Id3v2Version;
|
||||
use crate::util::text::{decode_text, encode_text, TextEncoding};
|
||||
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::error::Result;
|
||||
use crate::id3::v2::frame::content::verify_encoding;
|
||||
use crate::id3::v2::Id3v2Version;
|
||||
use crate::id3::v2::header::Id3v2Version;
|
||||
use crate::util::text::{decode_text, encode_text, TextEncoding};
|
||||
|
||||
use byteorder::ReadBytesExt;
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
//! * [`Id3v2Tag`]
|
||||
//! * [`Frame`]
|
||||
|
||||
mod flags;
|
||||
mod frame;
|
||||
pub(crate) mod header;
|
||||
mod items;
|
||||
pub(crate) mod read;
|
||||
mod restrictions;
|
||||
|
@ -16,17 +16,9 @@ pub(crate) mod tag;
|
|||
pub mod util;
|
||||
pub(crate) mod write;
|
||||
|
||||
use crate::error::{Id3v2Error, Id3v2ErrorKind, Result};
|
||||
use crate::macros::err;
|
||||
use util::synchsafe::SynchsafeInteger;
|
||||
|
||||
use std::io::Read;
|
||||
|
||||
use byteorder::{BigEndian, ByteOrder, ReadBytesExt};
|
||||
|
||||
// Exports
|
||||
|
||||
pub use flags::Id3v2TagFlags;
|
||||
pub use header::{Id3v2TagFlags, Id3v2Version};
|
||||
pub use util::upgrade::{upgrade_v2, upgrade_v3};
|
||||
|
||||
pub use tag::Id3v2Tag;
|
||||
|
@ -39,110 +31,3 @@ pub use frame::{Frame, FrameFlags, FrameValue};
|
|||
pub use restrictions::{
|
||||
ImageSizeRestrictions, TagRestrictions, TagSizeRestrictions, TextSizeRestrictions,
|
||||
};
|
||||
|
||||
/// The ID3v2 version
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
|
||||
pub enum Id3v2Version {
|
||||
/// ID3v2.2
|
||||
V2,
|
||||
/// ID3v2.3
|
||||
V3,
|
||||
/// ID3v2.4
|
||||
V4,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub(crate) struct Id3v2Header {
|
||||
pub version: Id3v2Version,
|
||||
pub flags: Id3v2TagFlags,
|
||||
pub size: u32,
|
||||
pub extended_size: u32,
|
||||
}
|
||||
|
||||
pub(crate) fn read_id3v2_header<R>(bytes: &mut R) -> Result<Id3v2Header>
|
||||
where
|
||||
R: Read,
|
||||
{
|
||||
let mut header = [0; 10];
|
||||
bytes.read_exact(&mut header)?;
|
||||
|
||||
if &header[..3] != b"ID3" {
|
||||
err!(FakeTag);
|
||||
}
|
||||
|
||||
// Version is stored as [major, minor], but here we don't care about minor revisions unless there's an error.
|
||||
let version = match header[3] {
|
||||
2 => Id3v2Version::V2,
|
||||
3 => Id3v2Version::V3,
|
||||
4 => Id3v2Version::V4,
|
||||
major => {
|
||||
return Err(Id3v2Error::new(Id3v2ErrorKind::BadId3v2Version(major, header[4])).into())
|
||||
},
|
||||
};
|
||||
|
||||
let flags = header[5];
|
||||
|
||||
// Compression was a flag only used in ID3v2.2 (bit 2).
|
||||
// At the time the ID3v2.2 specification was written, a compression scheme wasn't decided.
|
||||
// The spec recommends just ignoring the tag in this case.
|
||||
if version == Id3v2Version::V2 && flags & 0x40 == 0x40 {
|
||||
return Err(Id3v2Error::new(Id3v2ErrorKind::V2Compression).into());
|
||||
}
|
||||
|
||||
let mut flags_parsed = Id3v2TagFlags {
|
||||
unsynchronisation: flags & 0x80 == 0x80,
|
||||
experimental: (version == Id3v2Version::V4 || version == Id3v2Version::V3)
|
||||
&& flags & 0x20 == 0x20,
|
||||
footer: (version == Id3v2Version::V4 || version == Id3v2Version::V3)
|
||||
&& flags & 0x10 == 0x10,
|
||||
crc: false, // Retrieved later if applicable
|
||||
restrictions: None, // Retrieved later if applicable
|
||||
};
|
||||
|
||||
let size = BigEndian::read_u32(&header[6..]).unsynch();
|
||||
let mut extended_size = 0;
|
||||
|
||||
let extended_header =
|
||||
(version == Id3v2Version::V4 || version == Id3v2Version::V3) && flags & 0x40 == 0x40;
|
||||
|
||||
if extended_header {
|
||||
extended_size = bytes.read_u32::<BigEndian>()?.unsynch();
|
||||
|
||||
if extended_size < 6 {
|
||||
return Err(Id3v2Error::new(Id3v2ErrorKind::BadExtendedHeaderSize).into());
|
||||
}
|
||||
|
||||
// Useless byte since there's only 1 byte for flags
|
||||
let _num_flag_bytes = bytes.read_u8()?;
|
||||
|
||||
let extended_flags = bytes.read_u8()?;
|
||||
|
||||
// The only flags we care about here are the CRC and restrictions
|
||||
|
||||
if extended_flags & 0x20 == 0x20 {
|
||||
flags_parsed.crc = true;
|
||||
|
||||
// We don't care about the existing CRC (5) or its length byte (1)
|
||||
let mut crc = [0; 6];
|
||||
bytes.read_exact(&mut crc)?;
|
||||
}
|
||||
|
||||
if extended_flags & 0x10 == 0x10 {
|
||||
// We don't care about the length byte, it is always 1
|
||||
let _data_length = bytes.read_u8()?;
|
||||
|
||||
flags_parsed.restrictions = Some(TagRestrictions::from_byte(bytes.read_u8()?));
|
||||
}
|
||||
}
|
||||
|
||||
if extended_size > 0 && extended_size >= size {
|
||||
return Err(Id3v2Error::new(Id3v2ErrorKind::BadExtendedHeaderSize).into());
|
||||
}
|
||||
|
||||
Ok(Id3v2Header {
|
||||
version,
|
||||
flags: flags_parsed,
|
||||
size,
|
||||
extended_size,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::frame::read::ParsedFrame;
|
||||
use super::header::Id3v2Header;
|
||||
use super::tag::Id3v2Tag;
|
||||
use super::Id3v2Header;
|
||||
use crate::error::{Id3v2Error, Id3v2ErrorKind, Result};
|
||||
use crate::id3::v2::util::synchsafe::UnsynchronizedStream;
|
||||
use crate::probe::ParsingMode;
|
||||
|
@ -74,18 +74,18 @@ where
|
|||
|
||||
#[test]
|
||||
fn zero_size_id3v2() {
|
||||
use crate::id3::v2::read_id3v2_header;
|
||||
use crate::id3::v2::header::Id3v2Header;
|
||||
use crate::ParsingMode;
|
||||
use std::io::Cursor;
|
||||
|
||||
let mut f = Cursor::new(std::fs::read("tests/tags/assets/id3v2/zero.id3v2").unwrap());
|
||||
let header = read_id3v2_header(&mut f).unwrap();
|
||||
let header = Id3v2Header::parse(&mut f).unwrap();
|
||||
assert!(parse_id3v2(&mut f, header, ParsingMode::Strict).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bad_frame_id_relaxed_id3v2() {
|
||||
use crate::id3::v2::read_id3v2_header;
|
||||
use crate::id3::v2::header::Id3v2Header;
|
||||
use crate::{Accessor, ParsingMode, TagExt};
|
||||
use std::io::Cursor;
|
||||
|
||||
|
@ -94,7 +94,7 @@ fn bad_frame_id_relaxed_id3v2() {
|
|||
let mut f = Cursor::new(
|
||||
std::fs::read("tests/tags/assets/id3v2/bad_frame_otherwise_valid.id3v24").unwrap(),
|
||||
);
|
||||
let header = read_id3v2_header(&mut f).unwrap();
|
||||
let header = Id3v2Header::parse(&mut f).unwrap();
|
||||
let id3v2 = parse_id3v2(&mut f, header, ParsingMode::Relaxed);
|
||||
assert!(id3v2.is_ok());
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use super::flags::Id3v2TagFlags;
|
||||
use super::frame::id::FrameId;
|
||||
use super::frame::{Frame, FrameFlags, FrameValue, EMPTY_CONTENT_DESCRIPTOR, UNKNOWN_LANGUAGE};
|
||||
use super::Id3v2Version;
|
||||
use super::header::{Id3v2TagFlags, Id3v2Version};
|
||||
use crate::error::{LoftyError, Result};
|
||||
use crate::id3::v2::frame::{FrameRef, MUSICBRAINZ_UFID_OWNER};
|
||||
use crate::id3::v2::items::{
|
||||
|
@ -1223,13 +1222,13 @@ mod tests {
|
|||
use std::borrow::Cow;
|
||||
|
||||
use crate::id3::v2::frame::MUSICBRAINZ_UFID_OWNER;
|
||||
use crate::id3::v2::header::{Id3v2Header, Id3v2Version};
|
||||
use crate::id3::v2::items::{ExtendedUrlFrame, Popularimeter, UniqueFileIdentifierFrame};
|
||||
use crate::id3::v2::tag::{filter_comment_frame_by_description, new_text_frame};
|
||||
use crate::id3::v2::util::pairs::DEFAULT_NUMBER_IN_PAIR;
|
||||
use crate::id3::v2::{
|
||||
read_id3v2_header, AttachedPictureFrame, CommentFrame, ExtendedTextFrame, Frame,
|
||||
FrameFlags, FrameId, FrameValue, Id3v2Tag, Id3v2Version, TextInformationFrame,
|
||||
UrlLinkFrame,
|
||||
AttachedPictureFrame, CommentFrame, ExtendedTextFrame, Frame, FrameFlags, FrameId,
|
||||
FrameValue, Id3v2Tag, TextInformationFrame, UrlLinkFrame,
|
||||
};
|
||||
use crate::tag::utils::test_utils::read_path;
|
||||
use crate::util::text::TextEncoding;
|
||||
|
@ -1245,7 +1244,7 @@ mod tests {
|
|||
|
||||
let mut reader = std::io::Cursor::new(&tag_bytes[..]);
|
||||
|
||||
let header = read_id3v2_header(&mut reader).unwrap();
|
||||
let header = Id3v2Header::parse(&mut reader).unwrap();
|
||||
crate::id3::v2::read::parse_id3v2(&mut reader, header, ParsingMode::Strict).unwrap()
|
||||
}
|
||||
|
||||
|
@ -1356,7 +1355,7 @@ mod tests {
|
|||
|
||||
let temp_reader = &mut &*writer;
|
||||
|
||||
let temp_header = read_id3v2_header(temp_reader).unwrap();
|
||||
let temp_header = Id3v2Header::parse(temp_reader).unwrap();
|
||||
let temp_parsed_tag =
|
||||
crate::id3::v2::read::parse_id3v2(temp_reader, temp_header, ParsingMode::Strict)
|
||||
.unwrap();
|
||||
|
@ -1608,7 +1607,7 @@ mod tests {
|
|||
|
||||
let mut reader = &mut &writer[..];
|
||||
|
||||
let header = read_id3v2_header(&mut reader).unwrap();
|
||||
let header = Id3v2Header::parse(&mut reader).unwrap();
|
||||
assert!(crate::id3::v2::read::parse_id3v2(reader, header, ParsingMode::Strict).is_ok());
|
||||
|
||||
assert_eq!(writer[3..10], writer[writer.len() - 7..])
|
||||
|
@ -1633,7 +1632,7 @@ mod tests {
|
|||
|
||||
let mut reader = &mut &writer[..];
|
||||
|
||||
let header = read_id3v2_header(&mut reader).unwrap();
|
||||
let header = Id3v2Header::parse(&mut reader).unwrap();
|
||||
let tag = crate::id3::v2::read::parse_id3v2(reader, header, ParsingMode::Strict).unwrap();
|
||||
|
||||
assert_eq!(tag.len(), 1);
|
||||
|
@ -1950,7 +1949,7 @@ mod tests {
|
|||
// And verify we can reread the tag
|
||||
let mut reader = std::io::Cursor::new(&content[..]);
|
||||
|
||||
let header = read_id3v2_header(&mut reader).unwrap();
|
||||
let header = Id3v2Header::parse(&mut reader).unwrap();
|
||||
let reparsed =
|
||||
crate::id3::v2::read::parse_id3v2(&mut reader, header, ParsingMode::Strict).unwrap();
|
||||
|
||||
|
|
|
@ -96,14 +96,14 @@ impl<B: ByteOrder> Chunks<B> {
|
|||
where
|
||||
R: Read + Seek,
|
||||
{
|
||||
use crate::id3::v2::header::Id3v2Header;
|
||||
use crate::id3::v2::read::parse_id3v2;
|
||||
use crate::id3::v2::read_id3v2_header;
|
||||
|
||||
let content = self.content(data)?;
|
||||
|
||||
let reader = &mut &*content;
|
||||
|
||||
let header = read_id3v2_header(reader)?;
|
||||
let header = Id3v2Header::parse(reader)?;
|
||||
let id3v2 = parse_id3v2(reader, header, parse_mode)?;
|
||||
|
||||
// Skip over the footer
|
||||
|
|
|
@ -2,8 +2,8 @@ use super::header::{cmp_header, search_for_frame_sync, Header, HeaderCmpResult,
|
|||
use super::{MpegFile, MpegProperties};
|
||||
use crate::ape::header::read_ape_header;
|
||||
use crate::error::Result;
|
||||
use crate::id3::v2::header::Id3v2Header;
|
||||
use crate::id3::v2::read::parse_id3v2;
|
||||
use crate::id3::v2::read_id3v2_header;
|
||||
use crate::id3::{find_id3v1, find_lyrics3v2, ID3FindResults};
|
||||
use crate::macros::{decode_err, err};
|
||||
use crate::mpeg::header::HEADER_MASK;
|
||||
|
@ -36,7 +36,7 @@ where
|
|||
// Seek back to read the tag in full
|
||||
reader.seek(SeekFrom::Current(-4))?;
|
||||
|
||||
let header = read_id3v2_header(reader)?;
|
||||
let header = Id3v2Header::parse(reader)?;
|
||||
let skip_footer = header.flags.footer;
|
||||
|
||||
let id3v2 = parse_id3v2(reader, header, parse_options.parsing_mode)?;
|
||||
|
|
Loading…
Reference in a new issue