{
public:
TagPrivate() :
- file(0),
- tagOffset(-1),
+ fileLength(0),
extendedHeader(0),
footer(0)
{
delete footer;
}
- File *file;
- long tagOffset;
+ long fileLength;
const FrameFactory *factory;
Header header;
TagLib::Tag(),
d(new TagPrivate())
{
- d->file = file;
- d->tagOffset = tagOffset;
d->factory = factory;
- read();
+ read(file, tagOffset);
}
ID3v2::Tag::~Tag()
// Compute the amount of padding, and append that to tagData.
// TODO: Should be calculated in offset_t in taglib2.
- long paddingSize = d->header.tagSize() - (tagData.size() - Header::size());
+ long originalSize = d->header.tagSize();
+ long paddingSize = originalSize - (tagData.size() - Header::size());
if(paddingSize <= 0) {
paddingSize = MinPaddingSize;
else {
// Padding won't increase beyond 1% of the file size or 1MB.
- long threshold = d->file ? d->file->length() / 100 : 0;
+ long threshold = d->fileLength / 100;
threshold = std::max(threshold, MinPaddingSize);
threshold = std::min(threshold, MaxPaddingSize);
d->header.setMajorVersion(version);
d->header.setTagSize(tagData.size() - Header::size());
+ if(d->fileLength > 0)
+ d->fileLength += (d->header.tagSize() - originalSize);
+
// TODO: This should eventually include d->footer->render().
const ByteVector headerData = d->header.render();
std::copy(headerData.begin(), headerData.end(), tagData.begin());
// protected members
////////////////////////////////////////////////////////////////////////////////
-void ID3v2::Tag::read()
+void ID3v2::Tag::read(TagLib::File *file, long offset)
{
- if(!d->file)
+ if(!file)
return;
- if(!d->file->isOpen())
+ if(!file->isOpen())
return;
- d->file->seek(d->tagOffset);
- d->header.setData(d->file->readBlock(Header::size()));
+ d->fileLength = file->length();
+
+ file->seek(offset);
+ d->header.setData(file->readBlock(Header::size()));
// If the tag size is 0, then this is an invalid tag (tags must contain at
// least one frame)
if(d->header.tagSize() != 0)
- parse(d->file->readBlock(d->header.tagSize()));
+ parse(file->readBlock(d->header.tagSize()));
// Look for duplicate ID3v2 tags and treat them as an extra blank of this one.
// It leads to overwriting them with zero when saving the tag.
while(true) {
- d->file->seek(d->tagOffset + d->header.completeTagSize() + extraSize);
+ file->seek(offset + d->header.completeTagSize() + extraSize);
- const ByteVector data = d->file->readBlock(Header::size());
+ const ByteVector data = file->readBlock(Header::size());
if(data.size() < Header::size() || !data.startsWith(Header::fileIdentifier()))
break;