use std::fs::File; use std::io::{self, Read, Seek}; #[derive(Copy, Clone, Debug)] pub enum TagType { /// An ID3v1.0 tag TAGv10, /// An ID3v1.1 enhanced tag (TAG+) in addition to the v1.0 tag TAGv11, /// An ID3v1.2 extended tag (EXT) in addition to the v1.0 tag TAGv12, } pub fn recognise(file: &mut File) -> io::Result> { let length = file.seek(io::SeekFrom::End(0))?; if length < 128 { return Ok(None); } let mut buf4 = [0u8; 4]; // Check whether we have a v1.0 tag file.seek(io::SeekFrom::End(-128))?; file.read_exact(&mut buf4[0..3])?; if &buf4[0..3] == b"TAG" { // Check whether we also have a v1.1 tag if length >= 128 + 227 { file.seek(io::SeekFrom::End(-128 - 227))?; file.read_exact(&mut buf4)?; if &buf4 == b"TAG+" { return Ok(Some(TagType::TAGv11)); } } // Otherwise, check whether we also have a v1.2 tag if length >= 128 + 128 { file.seek(io::SeekFrom::End(-128 - 128))?; file.read_exact(&mut buf4[0..3])?; if &buf4[0..3] == b"EXT" { return Ok(Some(TagType::TAGv12)); } } // Nope, just v1.0 Ok(Some(TagType::TAGv10)) } else { Ok(None) } } pub fn remove_tag(file: &mut File, typ: TagType) -> io::Result<()> { let tag_len = match typ { TagType::TAGv10 => 128, TagType::TAGv11 => 128 + 227, TagType::TAGv12 => 128 + 128, }; let length = file.seek(io::SeekFrom::End(0))?; eprintln!("remove_tag: Resizing file from {} to {} bytes", length, length - tag_len); file.set_len(length - tag_len)?; Ok(()) }