diff --git a/taglib/mpeg/id3v2/id3v2tag.cpp b/taglib/mpeg/id3v2/id3v2tag.cpp index be5bfd20..636d9eb2 100644 --- a/taglib/mpeg/id3v2/id3v2tag.cpp +++ b/taglib/mpeg/id3v2/id3v2tag.cpp @@ -55,8 +55,7 @@ class ID3v2::Tag::TagPrivate { public: TagPrivate() : - file(0), - tagOffset(-1), + fileLength(0), extendedHeader(0), footer(0) { @@ -69,8 +68,7 @@ public: delete footer; } - File *file; - long tagOffset; + long fileLength; const FrameFactory *factory; Header header; @@ -124,11 +122,9 @@ ID3v2::Tag::Tag(File *file, long tagOffset, const FrameFactory *factory) : TagLib::Tag(), d(new TagPrivate()) { - d->file = file; - d->tagOffset = tagOffset; d->factory = factory; - read(); + read(file, tagOffset); } ID3v2::Tag::~Tag() @@ -617,7 +613,8 @@ ByteVector ID3v2::Tag::render(int version) const // 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; @@ -625,7 +622,7 @@ ByteVector ID3v2::Tag::render(int version) const 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); @@ -639,6 +636,9 @@ ByteVector ID3v2::Tag::render(int version) const 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()); @@ -663,22 +663,24 @@ void ID3v2::Tag::setLatin1StringHandler(const Latin1StringHandler *handler) // 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. @@ -690,9 +692,9 @@ void ID3v2::Tag::read() 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; diff --git a/taglib/mpeg/id3v2/id3v2tag.h b/taglib/mpeg/id3v2/id3v2tag.h index 76ca73f1..af0efdc3 100644 --- a/taglib/mpeg/id3v2/id3v2tag.h +++ b/taglib/mpeg/id3v2/id3v2tag.h @@ -382,7 +382,7 @@ namespace TagLib { * the Header, the body of the tag (which contains the ExtendedHeader and * frames) and Footer. */ - void read(); + void read(TagLib::File *file, long offset); /*! * This is called by read to parse the body of the tag. It determines if an