From: Scott Wheeler Date: Thu, 25 Sep 2014 20:19:09 +0000 (+0200) Subject: Rebuild TRDC from v2.3 fields X-Git-Tag: v1.10beta~144 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bd7419f0bdc9eb818776b6e42e8dad9784dc261f;p=taglib Rebuild TRDC from v2.3 fields This fixes an issue that was reported to me via email with the recording date being thrown away from v2.3 tags. --- diff --git a/taglib/mpeg/id3v2/id3v2framefactory.cpp b/taglib/mpeg/id3v2/id3v2framefactory.cpp index fbf38adb..507a24d3 100644 --- a/taglib/mpeg/id3v2/id3v2framefactory.cpp +++ b/taglib/mpeg/id3v2/id3v2framefactory.cpp @@ -290,6 +290,28 @@ Frame *FrameFactory::createFrame(const ByteVector &origData, Header *tagHeader) return new UnknownFrame(data, header); } +void FrameFactory::rebuildAggregateFrames(Tag *tag) const +{ + if(tag->header()->majorVersion() < 4 && + tag->frameList("TDRC").size() == 1 && + tag->frameList("TDAT").size() == 1) + { + TextIdentificationFrame *trdc = + static_cast(tag->frameList("TDRC").front()); + UnknownFrame *tdat = + static_cast(tag->frameList("TDAT").front()); + + if(trdc->fieldList().size() == 1 && + trdc->fieldList().front().size() == 4 && + tdat->data().size() >= 5) + { + String date(tdat->data().mid(1), String::Type(tdat->data()[0])); + if(date.length() == 4) + trdc->setText(trdc->toString() + '-' + date.substr(2, 2) + '-' + date.substr(0, 2)); + } + } +} + String::Type FrameFactory::defaultTextEncoding() const { return d->defaultEncoding; diff --git a/taglib/mpeg/id3v2/id3v2framefactory.h b/taglib/mpeg/id3v2/id3v2framefactory.h index 762d7eb3..d991fb2b 100644 --- a/taglib/mpeg/id3v2/id3v2framefactory.h +++ b/taglib/mpeg/id3v2/id3v2framefactory.h @@ -93,6 +93,14 @@ namespace TagLib { // BIC: make virtual Frame *createFrame(const ByteVector &data, Header *tagHeader) const; + /*! + * After a tag has been read, this tries to rebuild some of them + * information, most notably the recording date, from frames that + * have been deprecated and can't be upgraded directly. + */ + // BIC: Make virtual + void rebuildAggregateFrames(Tag *tag) const; + /*! * Returns the default text encoding for text frames. If setTextEncoding() * has not been explicitly called this will only be used for new text diff --git a/taglib/mpeg/id3v2/id3v2tag.cpp b/taglib/mpeg/id3v2/id3v2tag.cpp index 715cb1bc..c6aa4f93 100644 --- a/taglib/mpeg/id3v2/id3v2tag.cpp +++ b/taglib/mpeg/id3v2/id3v2tag.cpp @@ -693,7 +693,7 @@ void ID3v2::Tag::parse(const ByteVector &origData) } d->paddingSize = frameDataLength - frameDataPosition; - return; + break; } Frame *frame = d->factory->createFrame(data.mid(frameDataPosition), @@ -712,6 +712,8 @@ void ID3v2::Tag::parse(const ByteVector &origData) frameDataPosition += frame->size() + Frame::headerSize(d->header.majorVersion()); addFrame(frame); } + + d->factory->rebuildAggregateFrames(this); } void ID3v2::Tag::setTextFrame(const ByteVector &id, const String &value) diff --git a/tests/test_id3v2.cpp b/tests/test_id3v2.cpp index ac8de33b..ebe86fc3 100644 --- a/tests/test_id3v2.cpp +++ b/tests/test_id3v2.cpp @@ -687,7 +687,7 @@ public: tf = static_cast(bar.ID3v2Tag()->frameList("TDRC").front()); CPPUNIT_ASSERT(tf); CPPUNIT_ASSERT_EQUAL(TagLib::uint(1), tf->fieldList().size()); - CPPUNIT_ASSERT_EQUAL(String("2012"), tf->fieldList().front()); + CPPUNIT_ASSERT_EQUAL(String("2012-04-17"), tf->fieldList().front()); tf = dynamic_cast(bar.ID3v2Tag()->frameList("TIPL").front()); CPPUNIT_ASSERT(tf); CPPUNIT_ASSERT_EQUAL(TagLib::uint(8), tf->fieldList().size());