]> granicus.if.org Git - taglib/commitdiff
Rebuild TRDC from v2.3 fields
authorScott Wheeler <scott@directededge.com>
Thu, 25 Sep 2014 20:19:09 +0000 (22:19 +0200)
committerScott Wheeler <scott@directededge.com>
Thu, 25 Sep 2014 21:07:09 +0000 (23:07 +0200)
This fixes an issue that was reported to me via email with the recording
date being thrown away from v2.3 tags.

taglib/mpeg/id3v2/id3v2framefactory.cpp
taglib/mpeg/id3v2/id3v2framefactory.h
taglib/mpeg/id3v2/id3v2tag.cpp
tests/test_id3v2.cpp

index fbf38adbd9d008894343b180ba76ef0c1fe4037b..507a24d3044263c2ddf088fb912c918809bdebb3 100644 (file)
@@ -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<TextIdentificationFrame *>(tag->frameList("TDRC").front());
+    UnknownFrame *tdat =
+      static_cast<UnknownFrame *>(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;
index 762d7eb3e6b454fa6b06abb03db25f2e880dee76..d991fb2b573edf356136d781b6b9c144fc767be4 100644 (file)
@@ -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
index 715cb1bc2627dc61cee03a0889f78aabe2f75974..c6aa4f930a4dac25bd0c59bbf2dbf4dafa4d4547 100644 (file)
@@ -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)
index ac8de33bc33b582b38b0f35cb6766875cdb97fbe..ebe86fc398b1e239a2e2d1697c1772361022be35 100644 (file)
@@ -687,7 +687,7 @@ public:
       tf = static_cast<ID3v2::TextIdentificationFrame *>(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<ID3v2::TextIdentificationFrame *>(bar.ID3v2Tag()->frameList("TIPL").front());
       CPPUNIT_ASSERT(tf);
       CPPUNIT_ASSERT_EQUAL(TagLib::uint(8), tf->fieldList().size());