use std::io::{Read, Seek, SeekFrom};
use std::str;
use error::Result;
pub static APE_PREAMBLE: &'static [u8] = b"APETAGEX";
static ID3V1_HEADER: &'static [u8] = b"TAG";
static LYRICS3V2_HEADER: &'static [u8] = b"LYRICS200";
pub const ID3V1_OFFSET: i64 = -128;
const LYRICS3V2_SIZE: i64 = 6;
pub fn probe_ape<R: Read + Seek>(reader: &mut R, pos: SeekFrom) -> Result<bool> {
let capacity = APE_PREAMBLE.len();
let mut preamble = Vec::<u8>::with_capacity(capacity);
try!(reader.seek(pos));
try!(reader.take(capacity as u64).read_to_end(&mut preamble));
Ok(preamble == APE_PREAMBLE)
}
pub fn probe_id3v1<R: Read + Seek>(reader: &mut R) -> Result<bool> {
let capacity = ID3V1_HEADER.len();
let mut header = Vec::<u8>::with_capacity(capacity);
try!(reader.seek(SeekFrom::End(ID3V1_OFFSET)));
try!(reader.take(capacity as u64).read_to_end(&mut header));
Ok(header == ID3V1_HEADER)
}
pub fn probe_lyrics3v2<R: Read + Seek>(reader: &mut R) -> Result<i64> {
let capacity = LYRICS3V2_HEADER.len();
let mut header = Vec::<u8>::with_capacity(capacity);
try!(reader.seek(SeekFrom::End(ID3V1_OFFSET - capacity as i64)));
try!(reader.take(capacity as u64).read_to_end(&mut header));
try!(reader.seek(SeekFrom::Current(0 - capacity as i64)));
if header == LYRICS3V2_HEADER {
let mut buf = Vec::<u8>::with_capacity(LYRICS3V2_SIZE as usize);
try!(reader.seek(SeekFrom::Current(-LYRICS3V2_SIZE)));
try!(reader.take(LYRICS3V2_SIZE as u64).read_to_end(&mut buf));
let raw_size = try!(str::from_utf8(&buf));
let int_size = try!(raw_size.parse::<i64>());
Ok(int_size + LYRICS3V2_SIZE + capacity as i64)
} else {
Ok(-1)
}
}