aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--taglib/mpeg/id3v2/id3v2frame.cpp9
-rw-r--r--taglib/mpeg/id3v2/id3v2framefactory.cpp5
-rw-r--r--tests/test_id3v2.cpp28
3 files changed, 36 insertions, 6 deletions
diff --git a/taglib/mpeg/id3v2/id3v2frame.cpp b/taglib/mpeg/id3v2/id3v2frame.cpp
index 4f88dec1..af4136af 100644
--- a/taglib/mpeg/id3v2/id3v2frame.cpp
+++ b/taglib/mpeg/id3v2/id3v2frame.cpp
@@ -111,8 +111,8 @@ Frame *Frame::createTextualFrame(const String &key, const StringList &values) //
// check if the key is contained in the key<=>frameID mapping
ByteVector frameID = keyToFrameID(key);
if(!frameID.isEmpty()) {
- // Apple proprietary WFED (Podcast URL), MVNM (Movement Name), MVIN (Movement Number) are in fact text frames.
- if(frameID[0] == 'T' || frameID == "WFED" || frameID == "MVNM" || frameID == "MVIN"){ // text frame
+ // Apple proprietary WFED (Podcast URL), MVNM (Movement Name), MVIN (Movement Number), GRP1 (Grouping) are in fact text frames.
+ if(frameID[0] == 'T' || frameID == "WFED" || frameID == "MVNM" || frameID == "MVIN" || frameID == "GRP1"){ // text frame
TextIdentificationFrame *frame = new TextIdentificationFrame(frameID, String::UTF8);
frame->setText(values);
return frame;
@@ -394,6 +394,7 @@ namespace
{ "WFED", "PODCASTURL" },
{ "MVNM", "MOVEMENTNAME" },
{ "MVIN", "MOVEMENTNUMBER" },
+ { "GRP1", "GROUPING" },
};
const size_t frameTranslationSize = sizeof(frameTranslation) / sizeof(frameTranslation[0]);
@@ -476,8 +477,8 @@ PropertyMap Frame::asProperties() const
// workaround until this function is virtual
if(id == "TXXX")
return dynamic_cast< const UserTextIdentificationFrame* >(this)->asProperties();
- // Apple proprietary WFED (Podcast URL), MVNM (Movement Name), MVIN (Movement Number) are in fact text frames.
- else if(id[0] == 'T' || id == "WFED" || id == "MVNM" || id == "MVIN")
+ // Apple proprietary WFED (Podcast URL), MVNM (Movement Name), MVIN (Movement Number), GRP1 (Grouping) are in fact text frames.
+ else if(id[0] == 'T' || id == "WFED" || id == "MVNM" || id == "MVIN" || id == "GRP1")
return dynamic_cast< const TextIdentificationFrame* >(this)->asProperties();
else if(id == "WXXX")
return dynamic_cast< const UserUrlLinkFrame* >(this)->asProperties();
diff --git a/taglib/mpeg/id3v2/id3v2framefactory.cpp b/taglib/mpeg/id3v2/id3v2framefactory.cpp
index 9347ab86..155d0a9d 100644
--- a/taglib/mpeg/id3v2/id3v2framefactory.cpp
+++ b/taglib/mpeg/id3v2/id3v2framefactory.cpp
@@ -198,8 +198,8 @@ Frame *FrameFactory::createFrame(const ByteVector &origData, Header *tagHeader)
// Text Identification (frames 4.2)
- // Apple proprietary WFED (Podcast URL), MVNM (Movement Name), MVIN (Movement Number) are in fact text frames.
- if(frameID.startsWith("T") || frameID == "WFED" || frameID == "MVNM" || frameID == "MVIN") {
+ // Apple proprietary WFED (Podcast URL), MVNM (Movement Name), MVIN (Movement Number), GRP1 (Grouping) are in fact text frames.
+ if(frameID.startsWith("T") || frameID == "WFED" || frameID == "MVNM" || frameID == "MVIN" || frameID == "GRP1") {
TextIdentificationFrame *f = frameID != "TXXX"
? new TextIdentificationFrame(data, header)
@@ -459,6 +459,7 @@ namespace
{ "WFD", "WFED" },
{ "MVN", "MVNM" },
{ "MVI", "MVIN" },
+ { "GP1", "GRP1" },
};
const size_t frameConversion2Size = sizeof(frameConversion2) / sizeof(frameConversion2[0]);
diff --git a/tests/test_id3v2.cpp b/tests/test_id3v2.cpp
index 7d94af06..8c6f67dc 100644
--- a/tests/test_id3v2.cpp
+++ b/tests/test_id3v2.cpp
@@ -110,6 +110,7 @@ class TestID3v2 : public CppUnit::TestFixture
CPPUNIT_TEST(testPropertyInterface);
CPPUNIT_TEST(testPropertyInterface2);
CPPUNIT_TEST(testPropertiesMovement);
+ CPPUNIT_TEST(testPropertyGrouping);
CPPUNIT_TEST(testDeleteFrame);
CPPUNIT_TEST(testSaveAndStripID3v1ShouldNotAddFrameFromID3v1ToId3v2);
CPPUNIT_TEST(testParseChapterFrame);
@@ -966,6 +967,33 @@ public:
tag.addFrame(parsedFrameMvin);
}
+ void testPropertyGrouping()
+ {
+ ID3v2::Tag tag;
+ ID3v2::TextIdentificationFrame *frameGrp1 = new ID3v2::TextIdentificationFrame("GRP1");
+ frameGrp1->setText("Grouping");
+ tag.addFrame(frameGrp1);
+
+ PropertyMap properties = tag.properties();
+ CPPUNIT_ASSERT(properties.contains("GROUPING"));
+ CPPUNIT_ASSERT_EQUAL(String("Grouping"), properties["GROUPING"].front());
+
+ ByteVector frameDataGrp1("GRP1"
+ "\x00\x00\x00\x09"
+ "\x00\x00"
+ "\x00"
+ "Grouping", 19);
+ CPPUNIT_ASSERT_EQUAL(frameDataGrp1, frameGrp1->render());
+
+ ID3v2::FrameFactory *factory = ID3v2::FrameFactory::instance();
+ ID3v2::TextIdentificationFrame *parsedFrameGrp1 =
+ dynamic_cast<ID3v2::TextIdentificationFrame *>(factory->createFrame(frameDataGrp1));
+ CPPUNIT_ASSERT(parsedFrameGrp1);
+ CPPUNIT_ASSERT_EQUAL(String("Grouping"), parsedFrameGrp1->toString());
+
+ tag.addFrame(parsedFrameGrp1);
+ }
+
void testDeleteFrame()
{
ScopedFileCopy copy("rare_frames", ".mp3");