From 38b258bea2c6fc003ecb0e741b71c7b01fdeca77 Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Sun, 19 Jan 2020 20:59:42 +0100 Subject: Add option to remove v1 tags --- src/id3v1.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/id3v1.rs (limited to 'src/id3v1.rs') diff --git a/src/id3v1.rs b/src/id3v1.rs new file mode 100644 index 0000000..ccade4a --- /dev/null +++ b/src/id3v1.rs @@ -0,0 +1,61 @@ +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(()) +} -- cgit v1.2.3