1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use crate::error::Result;
use crate::iff::chunk::Chunks;
use std::fs::File;
use std::io::{Read, Seek, SeekFrom, Write};
use byteorder::{ByteOrder, ReadBytesExt, WriteBytesExt};
pub(in crate::id3::v2) fn write_to_chunk_file<B>(data: &mut File, tag: &[u8]) -> Result<()>
where
B: ByteOrder,
{
data.seek(SeekFrom::Current(4))?;
let file_size = data.read_u32::<B>()?;
data.seek(SeekFrom::Current(4))?;
let mut id3v2_chunk = (None, None);
let mut chunks = Chunks::<B>::new(file_size);
while chunks.next(data).is_ok() {
if &chunks.fourcc == b"ID3 " || &chunks.fourcc == b"id3 " {
id3v2_chunk = (
Some(data.seek(SeekFrom::Current(0))? - 8),
Some(chunks.size),
);
break;
}
data.seek(SeekFrom::Current(i64::from(chunks.size)))?;
chunks.correct_position(data)?;
}
if let (Some(chunk_start), Some(mut chunk_size)) = id3v2_chunk {
data.seek(SeekFrom::Start(0))?;
if chunk_size % 2 != 0 {
chunk_size += 1;
}
let mut file_bytes = Vec::new();
data.read_to_end(&mut file_bytes)?;
file_bytes.splice(
chunk_start as usize..(chunk_start + u64::from(chunk_size) + 8) as usize,
[],
);
data.seek(SeekFrom::Start(0))?;
data.set_len(0)?;
data.write_all(&*file_bytes)?;
}
if !tag.is_empty() {
data.seek(SeekFrom::End(0))?;
data.write_all(&[b'I', b'D', b'3', b' '])?;
data.write_u32::<B>(tag.len() as u32)?;
data.write_all(tag)?;
if tag.len() % 2 != 0 {
data.write_u8(0)?;
}
let total_size = data.seek(SeekFrom::Current(0))? - 8;
data.seek(SeekFrom::Start(4))?;
data.write_u32::<B>(total_size as u32)?;
}
Ok(())
}