Added some functions, started to fix bugs.

This commit is contained in:
Michael Helmling
2012-02-19 12:15:28 +01:00
parent 70c3264279
commit 6c054af3ed
8 changed files with 118 additions and 13 deletions

View File

@ -25,7 +25,7 @@
#include <tbytevectorlist.h>
#include <id3v2tag.h>
#include <tdebug.h>
#include "textidentificationframe.h"
#include "tpropertymap.h"
#include "id3v1genres.h"
@ -321,6 +321,14 @@ UserTextIdentificationFrame::UserTextIdentificationFrame(const ByteVector &data)
checkFields();
}
UserTextIdentificationFrame::UserTextIdentificationFrame(const String &description, const StringList &values, String::Type encoding) :
TextIdentificationFrame("TXXX", encoding),
d(0)
{
setDescription(description);
setText(values);
}
String UserTextIdentificationFrame::toString() const
{
return "[" + description() + "] " + fieldList().toString();
@ -378,10 +386,12 @@ PropertyMap UserTextIdentificationFrame::asProperties() const
String key = map.prepareKey(tagName);
if(key.isNull()) // this frame's description is not a valid PropertyMap key -> add to unsupported list
map.unsupportedData().append(L"TXXX/" + description());
else
for(StringList::ConstIterator it = fieldList().begin(); it != fieldList().end(); ++it)
else {
StringList v = fieldList();
for(StringList::ConstIterator it = v.begin(); it != v.end(); ++it)
if(*it != description())
map.insert(key, *it);
}
return map;
}

View File

@ -253,9 +253,9 @@ namespace TagLib {
/*!
* Creates a user defined text identification frame with the given \a description
* and \a text.
* and \a values.
*/
UserTextIdentificationFrame(const String &description, const StringList &values, String::Type encoding = String::Latin1);
UserTextIdentificationFrame(const String &description, const StringList &values, String::Type encoding = String::UTF8);
virtual String toString() const;

View File

@ -26,6 +26,7 @@
***************************************************************************/
#include "urllinkframe.h"
#include "id3v2tag.h"
#include <tdebug.h>
#include <tstringlist.h>
#include <tpropertymap.h>
@ -167,6 +168,17 @@ PropertyMap UserUrlLinkFrame::asProperties() const
return map;
}
UserUrlLinkFrame *UserUrlLinkFrame::find(ID3v2::Tag *tag, const String &description) // static
{
FrameList l = tag->frameList("WXXX");
for(FrameList::Iterator it = l.begin(); it != l.end(); ++it) {
UserUrlLinkFrame *f = dynamic_cast<UserUrlLinkFrame *>(*it);
if(f && f->description() == description)
return f;
}
return 0;
}
void UserUrlLinkFrame::parseFields(const ByteVector &data)
{
if(data.size() < 2) {

View File

@ -161,6 +161,12 @@ namespace TagLib {
*/
PropertyMap asProperties() const;
/*!
* Searches for the user defined url frame with the description \a description
* in \a tag. This returns null if no matching frames were found.
*/
static UserUrlLinkFrame *find(Tag *tag, const String &description);
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;

View File

@ -337,11 +337,42 @@ void ID3v2::Tag::removeFrames(const ByteVector &id)
PropertyMap ID3v2::Tag::properties() const
{
PropertyMap properties;
for(FrameList::ConstIterator it = frameList().begin(); it != frameList().end(); ++it)
properties.merge((*it)->asProperties());
for(FrameList::ConstIterator it = frameList().begin(); it != frameList().end(); ++it) {
PropertyMap props = (*it)->asProperties();
debug(props);
properties.merge(props);
}
return properties;
}
void ID3v2::Tag::removeUnsupportedProperties(const StringList &properties)
{
// entries of unsupportedData() are usually frame IDs which are not supported
// by the PropertyMap interface. Three special cases exist: TXXX, WXXX, and COMM
// frames may also be unsupported if their description() is not a valid key.
for(StringList::ConstIterator it = properties.begin(); it != properties.end(); ++it){
ByteVector id = it->substr(0,4).data(String::Latin1);
if(id == "TXXX") {
String description = it->substr(5);
Frame *frame = UserTextIdentificationFrame::find(this, description);
if(frame)
removeFrame(frame);
} else if(id == "WXXX") {
String description = it->substr(5);
Frame *frame = UserUrlLinkFrame::find(this, description);
if(frame)
removeFrame(frame);
} else if(id == "COMM") {
String description = it->substr(5);
Frame *frame = CommentsFrame::findByDescription(this, description);
if(frame)
removeFrame(frame);
} else
removeFrames(id); // there should be only one frame with "id"
}
}
PropertyMap ID3v2::Tag::setProperties(const PropertyMap &origProps)
{
FrameList framesToDelete;

View File

@ -227,6 +227,11 @@ namespace TagLib {
*/
bool operator==(const List<T> &l) const;
/*!
* Compares this list with \a l and returns true if the lists differ.
*/
bool operator!=(const List<T> &l) const;
protected:
/*
* If this List is being shared via implicit sharing, do a deep copy of the

View File

@ -300,6 +300,12 @@ bool List<T>::operator==(const List<T> &l) const
return d->list == l.d->list;
}
template <class T>
bool List<T>::operator!=(const List<T> &l) const
{
return d->list != l.d->list;
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////

View File

@ -20,7 +20,6 @@
***************************************************************************/
#include "tpropertymap.h"
using namespace TagLib;
@ -90,18 +89,34 @@ PropertyMap::ConstIterator PropertyMap::find(const String &key) const
bool PropertyMap::contains(const String &key) const
{
String realKey = prepareKey(key);
// we consider keys with empty value list as not present
if(realKey.isNull() || SimplePropertyMap::operator[](realKey).isEmpty())
if(realKey.isNull())
return false;
return SimplePropertyMap::contains(realKey);
}
bool PropertyMap::contains(const PropertyMap &other) const
{
for(ConstIterator it = other.begin(); it != other.end(); ++it) {
if(!SimplePropertyMap::contains(it->first))
return false;
if ((*this)[it->first] != it->second)
return false;
}
return true;
}
PropertyMap &PropertyMap::erase(const String &key)
{
String realKey = prepareKey(key);
if(realKey.isNull())
return *this;
SimplePropertyMap::erase(realKey);
if(!realKey.isNull())
SimplePropertyMap::erase(realKey);
return *this;
}
PropertyMap &PropertyMap::erase(const PropertyMap &other)
{
for(ConstIterator it = other.begin(); it != other.end(); ++it)
erase(it->first);
return *this;
}
@ -126,6 +141,26 @@ StringList &PropertyMap::operator[](const String &key)
return SimplePropertyMap::operator[](realKey);
}
bool PropertyMap::operator==(const PropertyMap &other) const
{
for(ConstIterator it = other.begin(); it != other.end(); ++it) {
ConstIterator thisFind = find(it->first);
if( thisFind == end() || (thisFind->second != it->second) )
return false;
}
for(ConstIterator it = begin(); it != end(); ++it) {
ConstIterator otherFind = other.find(it->first);
if( otherFind == other.end() || (otherFind->second != it->second) )
return false;
}
return unsupported == other.unsupported;
}
bool PropertyMap::operator!=(const PropertyMap &other) const
{
return !(*this == other);
}
void PropertyMap::removeEmpty()
{
StringList emptyKeys;