#include <config.h>
#endif
+#include <tpropertymap.h>
#include "asftag.h"
using namespace TagLib;
d->attributeListMap.isEmpty();
}
+static const char *keyTranslation[][2] = {
+ { "WM/AlbumTitle", "ALBUM" },
+ { "WM/Composer", "COMPOSER" },
+ { "WM/Writer", "WRITER" },
+ { "WM/Conductor", "CONDUCTOR" },
+ { "WM/ModifiedBy", "REMIXER" },
+ { "WM/Year", "DATE" },
+ { "WM/OriginalReleaseYear", "ORIGINALDATE" },
+ { "WM/Producer", "PRODUCER" },
+ { "WM/ContentGroupDescription", "GROUPING" },
+ { "WM/SubTitle", "SUBTITLE" },
+ { "WM/SetSubTitle", "DISCSUBTITLE" },
+ { "WM/TrackNumber", "TRACKNUMBER" },
+ { "WM/PartOfSet", "DISCNUMBER" },
+ { "WM/Genre", "GENRE" },
+ { "WM/BeatsPerMinute", "BPM" },
+ { "WM/Mood", "MOOD" },
+ { "WM/ISRC", "ISRC" },
+ { "WM/Lyrics", "LYRICS" },
+ { "WM/Media", "MEDIA" },
+ { "WM/Publisher", "LABEL" },
+ { "WM/CatalogNo", "CATALOGNUMBER" },
+ { "WM/Barcode", "BARCODE" },
+ { "WM/EncodedBy", "ENCODEDBY" },
+ { "WM/AlbumSortOrder", "ALBUMSORT" },
+ { "WM/AlbumArtistSortOrder", "ALBUMARTISTSORT" },
+ { "WM/ArtistSortOrder", "ARTISTSORT" },
+ { "WM/TitleSortOrder", "TITLESORT" },
+ { "WM/Script", "SCRIPT" },
+ { "WM/Language", "LANGUAGE" },
+ { "MusicBrainz/Track Id", "MUSICBRAINZ_TRACKID" },
+ { "MusicBrainz/Artist Id", "MUSICBRAINZ_ARTISTID" },
+ { "MusicBrainz/Album Id", "MUSICBRAINZ_ALBUMID" },
+ { "MusicBrainz/Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
+ { "MusicBrainz/Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
+ { "MusicBrainz/Work Id", "MUSICBRAINZ_WORKID" },
+ { "MusicIP/PUID", "MUSICIP_PUID" },
+ { "Acoustid/Id", "ACOUSTID_ID" },
+ { "Acoustid/Fingerprint", "ACOUSTID_FINGERPRINT" },
+};
+
+PropertyMap ASF::Tag::properties() const
+{
+ static Map<String, String> keyMap;
+ if(keyMap.isEmpty()) {
+ int numKeys = sizeof(keyTranslation) / sizeof(keyTranslation[0]);
+ for(int i = 0; i < numKeys; i++) {
+ keyMap[keyTranslation[i][0]] = keyTranslation[i][1];
+ }
+ }
+
+ PropertyMap props;
+
+ if(!d->title.isEmpty()) {
+ props["TITLE"] = d->title;
+ }
+ if(!d->artist.isEmpty()) {
+ props["ARTIST"] = d->artist;
+ }
+ if(!d->copyright.isEmpty()) {
+ props["COPYRIGHT"] = d->copyright;
+ }
+ if(!d->comment.isEmpty()) {
+ props["COMMENT"] = d->comment;
+ }
+
+ ASF::AttributeListMap::ConstIterator it = d->attributeListMap.begin();
+ for(; it != d->attributeListMap.end(); ++it) {
+ if(keyMap.contains(it->first)) {
+ String key = keyMap[it->first];
+ AttributeList::ConstIterator it2 = it->second.begin();
+ for(; it2 != it->second.end(); ++it2) {
+ if(key == "TRACKNUMBER") {
+ if(it2->type() == ASF::Attribute::DWordType)
+ props.insert(key, String::number(it2->toUInt()));
+ else
+ props.insert(key, it2->toString());
+ }
+ else {
+ props.insert(key, it2->toString());
+ }
+ }
+ }
+ else {
+ props.unsupportedData().append(it->first);
+ }
+ }
+ return props;
+}
+
+void ASF::Tag::removeUnsupportedProperties(const StringList &props)
+{
+ StringList::ConstIterator it = props.begin();
+ for(; it != props.end(); ++it)
+ d->attributeListMap.erase(*it);
+}
+
+PropertyMap ASF::Tag::setProperties(const PropertyMap &props)
+{
+ static Map<String, String> reverseKeyMap;
+ if(reverseKeyMap.isEmpty()) {
+ int numKeys = sizeof(keyTranslation) / sizeof(keyTranslation[0]);
+ for(int i = 0; i < numKeys; i++) {
+ reverseKeyMap[keyTranslation[i][1]] = keyTranslation[i][0];
+ }
+ }
+
+ PropertyMap origProps = properties();
+ PropertyMap::ConstIterator it = origProps.begin();
+ for(; it != origProps.end(); ++it) {
+ if(!props.contains(it->first) || props[it->first].isEmpty()) {
+ if(it->first == "TITLE") {
+ d->title = String::null;
+ }
+ else if(it->first == "ARTIST") {
+ d->artist = String::null;
+ }
+ else if(it->first == "COMMENT") {
+ d->comment = String::null;
+ }
+ else if(it->first == "COPYRIGHT") {
+ d->copyright = String::null;
+ }
+ else {
+ d->attributeListMap.erase(reverseKeyMap[it->first]);
+ }
+ }
+ }
+
+ PropertyMap ignoredProps;
+ it = props.begin();
+ for(; it != props.end(); ++it) {
+ if(reverseKeyMap.contains(it->first)) {
+ String name = reverseKeyMap[it->first];
+ removeItem(name);
+ StringList::ConstIterator it2 = it->second.begin();
+ for(; it2 != it->second.end(); ++it2) {
+ addAttribute(name, *it2);
+ }
+ }
+ else if(it->first == "TITLE") {
+ d->title = it->second.toString();
+ }
+ else if(it->first == "ARTIST") {
+ d->artist = it->second.toString();
+ }
+ else if(it->first == "COMMENT") {
+ d->comment = it->second.toString();
+ }
+ else if(it->first == "COPYRIGHT") {
+ d->copyright = it->second.toString();
+ }
+ else {
+ ignoredProps.insert(it->first, it->second);
+ }
+ }
+
+ return ignoredProps;
+}
#include <tag.h>
#include <tstringlist.h>
#include <tbytevectorlist.h>
+#include <tpropertymap.h>
#include <asffile.h>
#include <cppunit/extensions/HelperMacros.h>
#include "utils.h"
class TestASF : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestASF);
- CPPUNIT_TEST(testProperties);
+ CPPUNIT_TEST(testAudioProperties);
CPPUNIT_TEST(testRead);
CPPUNIT_TEST(testSaveMultipleValues);
CPPUNIT_TEST(testSaveStream);
CPPUNIT_TEST(testSaveLargeValue);
CPPUNIT_TEST(testSavePicture);
CPPUNIT_TEST(testSaveMultiplePictures);
+ CPPUNIT_TEST(testProperties);
CPPUNIT_TEST_SUITE_END();
public:
- void testProperties()
+ void testAudioProperties()
{
ASF::File f(TEST_FILE_PATH_C("silence-1.wma"));
CPPUNIT_ASSERT_EQUAL(4, f.audioProperties()->length());
delete f;
}
+ void testProperties()
+ {
+ ASF::File f(TEST_FILE_PATH_C("silence-1.wma"));
+
+ PropertyMap tags = f.properties();
+
+ tags["TRACKNUMBER"] = StringList("2");
+ tags["DISCNUMBER"] = StringList("3");
+ tags["BPM"] = StringList("123");
+ tags["ARTIST"] = StringList("Foo Bar");
+ f.setProperties(tags);
+
+ tags = f.properties();
+
+ CPPUNIT_ASSERT_EQUAL(String("Foo Bar"), f.tag()->artist());
+ CPPUNIT_ASSERT_EQUAL(StringList("Foo Bar"), tags["ARTIST"]);
+
+ CPPUNIT_ASSERT(f.tag()->attributeListMap().contains("WM/BeatsPerMinute"));
+ CPPUNIT_ASSERT_EQUAL(1u, f.tag()->attributeListMap()["WM/BeatsPerMinute"].size());
+ CPPUNIT_ASSERT_EQUAL(String("123"), f.tag()->attributeListMap()["WM/BeatsPerMinute"].front().toString());
+ CPPUNIT_ASSERT_EQUAL(StringList("123"), tags["BPM"]);
+
+ CPPUNIT_ASSERT(f.tag()->attributeListMap().contains("WM/TrackNumber"));
+ CPPUNIT_ASSERT_EQUAL(1u, f.tag()->attributeListMap()["WM/TrackNumber"].size());
+ CPPUNIT_ASSERT_EQUAL(String("2"), f.tag()->attributeListMap()["WM/TrackNumber"].front().toString());
+ CPPUNIT_ASSERT_EQUAL(StringList("2"), tags["TRACKNUMBER"]);
+
+ CPPUNIT_ASSERT(f.tag()->attributeListMap().contains("WM/PartOfSet"));
+ CPPUNIT_ASSERT_EQUAL(1u, f.tag()->attributeListMap()["WM/PartOfSet"].size());
+ CPPUNIT_ASSERT_EQUAL(String("3"), f.tag()->attributeListMap()["WM/PartOfSet"].front().toString());
+ CPPUNIT_ASSERT_EQUAL(StringList("3"), tags["DISCNUMBER"]);
+ }
+
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestASF);