Запись тэга с обложкой: старая обложка не читается, новая копируется один раз

- build_tag: ёмкость — только по переносимым фреймам (заменяемая обложка не в счёт), фрейм
  обложки пишется прямо в буфер тэга (write_apic) вместо двух промежуточных массивов
- замена или удаление обложки: старый тэг читается по фреймам без APIC (parse_id3v2_lazy)
- тест: перезапись с обложкой 3 МБ выделяет < 1,5 размера обложки (было 17 МБ, стало 3)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
K1ndWha1eandClaude Opus 5.5 committed 2026-10-11 18:50:55 +03:00
1 parent 6161a7faaa
commit 095499b0fe
2 files changed
+78 -31

No files matched your search

+33
View File
@@ -117,6 +117,39 @@ fn test_read_skips_cover() {
}
}
// Замена обложки: в памяти только новый тэг — старая обложка не читается, новая копируется один раз
fn test_write_cover_allocations() {
path := tmp_copy('test_id3v23.mp3')
defer {
os.rm(path) or {}
}
mut data := []u8{len: 3 * 1024 * 1024, init: u8(index % 251)}
data[0] = 0xFF
data[1] = 0xD8
cover := metadata.Cover{
mime: 'image/jpeg'
data: data
}
tags := metadata.BookTags{
title: 'Глава 1'
album: 'Тень ветра'
}
metadata.write_book_tags(path, tags, cover: cover) or { panic(err) }
before := u64(gc_heap_usage().total_bytes)
metadata.write_book_tags(path, metadata.BookTags{ ...tags, title: 'Глава 2' },
cover: cover
) or {
panic(err)
}
allocated := u64(gc_heap_usage().total_bytes) - before
eprintln(' перезапись с обложкой 3 МБ: выделено ${f64(allocated) / 1048576:.1f} МБ')
assert allocated < u64(data.len) * 3 / 2, 'выделено ${allocated} Б'
t := metadata.read_book_tags(path) or { panic(err) }
assert t.tags.title == 'Глава 2'
assert t.has_cover
assert (metadata.read_cover(path) or { panic(err) }).data == data
}
// В файл без ID3v2 тэг добавляется в начало
fn test_write_without_id3v2() {
path := tmp_copy('test_id3v1.mp3')