mirror of
https://github.com/taglib/taglib.git
synced 2025-11-12 20:52:52 -05:00
Migration to new PropertyMap ... done ape to mod.
This commit is contained in:
@ -109,23 +109,31 @@ TagLib::Tag *APE::File::tag() const
|
||||
return &d->tag;
|
||||
}
|
||||
|
||||
TagLib::TagDict APE::File::toDict(void) const
|
||||
PropertyMap APE::File::properties() const
|
||||
{
|
||||
if (d->hasAPE)
|
||||
return d->tag.access<APE::Tag>(APEIndex, false)->toDict();
|
||||
if (d->hasID3v1)
|
||||
return d->tag.access<ID3v1::Tag>(ID3v1Index, false)->toDict();
|
||||
return TagLib::TagDict();
|
||||
if(d->hasAPE)
|
||||
return d->tag.access<APE::Tag>(APEIndex, false)->properties();
|
||||
if(d->hasID3v1)
|
||||
return d->tag.access<ID3v1::Tag>(ID3v1Index, false)->properties();
|
||||
return PropertyMap();
|
||||
}
|
||||
|
||||
void APE::File::fromDict(const TagDict &dict)
|
||||
void APE::File::removeUnsupportedProperties(const StringList &properties)
|
||||
{
|
||||
if (d->hasAPE)
|
||||
d->tag.access<APE::Tag>(APEIndex, false)->fromDict(dict);
|
||||
else if (d->hasID3v1)
|
||||
d->tag.access<ID3v1::Tag>(ID3v1Index, false)->fromDict(dict);
|
||||
if(d->hasAPE)
|
||||
d->tag.access<APE::Tag>(APEIndex, false)->removeUnsupportedProperties(properties);
|
||||
if(d->hasID3v1)
|
||||
d->tag.access<ID3v1::Tag>(ID3v1Index, false)->removeUnsupportedProperties(properties);
|
||||
}
|
||||
|
||||
PropertyMap APE::File::setProperties(const PropertyMap &properties)
|
||||
{
|
||||
if(d->hasAPE)
|
||||
return d->tag.access<APE::Tag>(APEIndex, false)->setProperties(properties);
|
||||
else if(d->hasID3v1)
|
||||
return d->tag.access<ID3v1::Tag>(ID3v1Index, false)->setProperties(properties);
|
||||
else
|
||||
d->tag.access<APE::Tag>(APE, true)->fromDict(dict);
|
||||
return d->tag.access<APE::Tag>(APE, true)->setProperties(properties);
|
||||
}
|
||||
|
||||
APE::Properties *APE::File::audioProperties() const
|
||||
|
||||
@ -111,18 +111,24 @@ namespace TagLib {
|
||||
virtual TagLib::Tag *tag() const;
|
||||
|
||||
/*!
|
||||
* Implements the unified tag dictionary interface -- export function.
|
||||
* Implements the unified property interface -- export function.
|
||||
* If the file contains both an APE and an ID3v1 tag, only APE
|
||||
* will be converted to the TagDict.
|
||||
* will be converted to the PropertyMap.
|
||||
*/
|
||||
TagDict toDict() const;
|
||||
PropertyMap properties() const;
|
||||
|
||||
/*!
|
||||
* Implements the unified tag dictionary interface -- import function.
|
||||
* Removes unsupported properties. Forwards to the actual Tag's
|
||||
* removeUnsupportedProperties() function.
|
||||
*/
|
||||
void removeUnsupportedProperties(const StringList &properties);
|
||||
|
||||
/*!
|
||||
* Implements the unified property interface -- import function.
|
||||
* As for the export, only one tag is taken into account. If the file
|
||||
* has no tag at all, APE will be created.
|
||||
*/
|
||||
void fromDict(const TagDict &);
|
||||
PropertyMap setProperties(const PropertyMap &);
|
||||
/*!
|
||||
* Returns the APE::Properties for this file. If no audio properties
|
||||
* were read then this will return a null pointer.
|
||||
|
||||
@ -174,61 +174,73 @@ void APE::Tag::setTrack(uint i)
|
||||
addValue("TRACK", String::number(i), true);
|
||||
}
|
||||
|
||||
TagDict APE::Tag::toDict() const
|
||||
// conversions of tag keys between what we use in PropertyMap and what's usual
|
||||
// for APE tags
|
||||
static const uint keyConversionsSize = 5; //usual, APE
|
||||
static const char *keyConversions[][2] = {{"TRACKNUMBER", "TRACK" },
|
||||
{"DATE", "YEAR" },
|
||||
{"ALBUMARTIST", "ALBUM ARTIST"},
|
||||
{"DISCNUMBER", "DISC" },
|
||||
{"REMIXER", "MIXARTIST" }};
|
||||
|
||||
PropertyMap APE::Tag::properties() const
|
||||
{
|
||||
TagDict dict;
|
||||
PropertyMap properties;
|
||||
ItemListMap::ConstIterator it = itemListMap().begin();
|
||||
for (; it != itemListMap().end(); ++it) {
|
||||
String tagName = it->first.upper();
|
||||
// These two tags need to be handled specially; in APE tags the track number is usually
|
||||
// named TRACK instead of TRACKNUMBER, the date tag is YEAR instead of DATE
|
||||
//
|
||||
if (tagName == "TRACK")
|
||||
tagName = "TRACKNUMBER";
|
||||
else if (tagName == "YEAR")
|
||||
tagName = "DATE";
|
||||
else if (tagName == "ALBUM ARTIST")
|
||||
tagName = "ALBUMARTIST";
|
||||
if (it->second.type() == Item::Text)
|
||||
dict[tagName].append(it->second.toStringList());
|
||||
for(; it != itemListMap().end(); ++it) {
|
||||
String tagName = PropertyMap::prepareKey(it->first);
|
||||
// if the item is Binary or Locator, or if the key is an invalid string,
|
||||
// add to unsupportedData
|
||||
if(it->second.type() != Item::Text || tagName.isNull())
|
||||
properties.unsupportedData().append(it->first);
|
||||
else {
|
||||
// Some tags need to be handled specially
|
||||
for(uint i = 0; i < keyConversionsSize; ++i)
|
||||
if(tagName == keyConversions[i][1])
|
||||
tagName = keyConversions[i][0];
|
||||
properties[tagName].append(it->second.toStringList());
|
||||
}
|
||||
}
|
||||
return dict;
|
||||
return properties;
|
||||
}
|
||||
|
||||
void APE::Tag::fromDict(const TagDict &origDict)
|
||||
void APE::Tag::removeUnsupportedProperties(const StringList &properties)
|
||||
{
|
||||
TagDict dict(origDict); // make a local copy that can be modified
|
||||
StringList::ConstIterator it = properties.begin();
|
||||
for(; it != properties.end(); ++it)
|
||||
removeItem(*it);
|
||||
}
|
||||
|
||||
// see comment in toDict() about TRACKNUMBER and YEAR
|
||||
if (dict.contains("TRACKNUMBER")) {
|
||||
dict.insert("TRACK", dict["TRACKNUMBER"]);
|
||||
dict.erase("TRACKNUMBER");
|
||||
}
|
||||
if (dict.contains("DATE")) {
|
||||
dict.insert("YEAR", dict["DATE"]);
|
||||
dict.erase("DATE");
|
||||
}
|
||||
PropertyMap APE::Tag::setProperties(const PropertyMap &origProps)
|
||||
{
|
||||
PropertyMap properties(origProps); // make a local copy that can be modified
|
||||
|
||||
// see comment in properties()
|
||||
for(uint i = 0; i < keyConversionsSize; ++i)
|
||||
if(properties.contains(keyConversions[i][0])) {
|
||||
properties.insert(keyConversions[i][1], properties[keyConversions[i][0]]);
|
||||
properties.erase(keyConversions[i][0]);
|
||||
}
|
||||
|
||||
// first check if tags need to be removed completely
|
||||
StringList toRemove;
|
||||
ItemListMap::ConstIterator remIt = itemListMap().begin();
|
||||
for (; remIt != itemListMap().end(); ++remIt) {
|
||||
if (remIt->second.type() != APE::Item::Text)
|
||||
// ignore binary and locator APE items
|
||||
continue;
|
||||
if (!dict.contains(remIt->first.upper()))
|
||||
for(; remIt != itemListMap().end(); ++remIt) {
|
||||
String key = PropertyMap::prepareKey(remIt->first);
|
||||
// only remove if a) key is valid, b) type is text, c) key not contained in new properties
|
||||
if(!key.isNull() && remIt->second.type() == APE::Item::Text && !properties.contains(key))
|
||||
toRemove.append(remIt->first);
|
||||
}
|
||||
|
||||
for (StringList::Iterator removeIt = toRemove.begin(); removeIt != toRemove.end(); removeIt++)
|
||||
removeItem(*removeIt);
|
||||
|
||||
// now sync in the "forward direction
|
||||
TagDict::ConstIterator it = dict.begin();
|
||||
for (; it != dict.end(); ++it) {
|
||||
// now sync in the "forward direction"
|
||||
PropertyMap::ConstIterator it = properties.begin();
|
||||
for(; it != properties.end(); ++it) {
|
||||
const String &tagName = it->first;
|
||||
if (!(itemListMap().contains(tagName)) || !(itemListMap()[tagName].values() == it->second)) {
|
||||
if (it->second.size() == 0)
|
||||
if(!(itemListMap().contains(tagName)) || !(itemListMap()[tagName].values() == it->second)) {
|
||||
if(it->second.size() == 0)
|
||||
removeItem(tagName);
|
||||
else {
|
||||
StringList::ConstIterator valueIt = it->second.begin();
|
||||
@ -239,6 +251,7 @@ void APE::Tag::fromDict(const TagDict &origDict)
|
||||
}
|
||||
}
|
||||
}
|
||||
return PropertyMap;
|
||||
}
|
||||
|
||||
APE::Footer *APE::Tag::footer() const
|
||||
|
||||
@ -107,20 +107,25 @@ namespace TagLib {
|
||||
* Implements the unified tag dictionary interface -- export function.
|
||||
* APE tags are perfectly compatible with the dictionary interface because they
|
||||
* support both arbitrary tag names and multiple values. Currently only
|
||||
* APE items of type *Text* are handled by the dictionary interface, while
|
||||
* *Binary* and *Locator* items are simply ignored.
|
||||
* APE items of type *Text* are handled by the dictionary interface; all *Binary*
|
||||
* and *Locator* items will be put into the unsupportedData list and can be
|
||||
* deleted on request using removeUnsupportedProperties(). The same happens
|
||||
* to Text items if their key is invalid for PropertyMap (which should actually
|
||||
* never happen).
|
||||
*
|
||||
* The only conversion done by this export function is to rename the APE tags
|
||||
* TRACK to TRACKNUMBER and YEAR to DATE, respectively, in order to be compliant
|
||||
* with the names used in other formats.
|
||||
* TRACK to TRACKNUMBER, YEAR to DATE, and ALBUM ARTIST to ALBUMARTIST, respectively,
|
||||
* in order to be compliant with the names used in other formats.
|
||||
*/
|
||||
TagDict toDict() const;
|
||||
PropertyMap properties() const;
|
||||
|
||||
void removeUnsupportedProperties(const StringList &properties);
|
||||
|
||||
/*!
|
||||
* Implements the unified tag dictionary interface -- import function. The same
|
||||
* comments as for the export function apply.
|
||||
*/
|
||||
void fromDict(const TagDict &);
|
||||
PropertyMap setProperties(const PropertyMap &);
|
||||
|
||||
/*!
|
||||
* Returns a pointer to the tag's footer.
|
||||
|
||||
Reference in New Issue
Block a user