mirror of
https://github.com/taglib/taglib.git
synced 2025-07-21 14:34:23 -04:00
fixed lots of bugs found by 'make'
This commit is contained in:
@ -29,6 +29,7 @@
|
||||
#include <tstringlist.h>
|
||||
|
||||
#include "commentsframe.h"
|
||||
#include "tpropertymap.h"
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include <id3v2tag.h>
|
||||
|
||||
#include "textidentificationframe.h"
|
||||
#include "tpropertymap.h"
|
||||
#include "id3v1genres.h"
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
@ -59,7 +61,7 @@ TextIdentificationFrame::TextIdentificationFrame(const ByteVector &data) :
|
||||
|
||||
TextIdentificationFrame *TextIdentificationFrame::createTIPLFrame(const PropertyMap &properties) // static
|
||||
{
|
||||
TextIdentificationFrame *frame = TextIdentificationFrame("TIPL");
|
||||
TextIdentificationFrame *frame = new TextIdentificationFrame("TIPL");
|
||||
StringList l;
|
||||
for(PropertyMap::ConstIterator it = properties.begin(); it != properties.end(); ++it){
|
||||
l.append(it->first);
|
||||
@ -71,7 +73,7 @@ TextIdentificationFrame *TextIdentificationFrame::createTIPLFrame(const Property
|
||||
|
||||
TextIdentificationFrame *TextIdentificationFrame::createTMCLFrame(const PropertyMap &properties) // static
|
||||
{
|
||||
TextIdentificationFrame *frame = TextIdentificationFrame("TMCL");
|
||||
TextIdentificationFrame *frame = new TextIdentificationFrame("TMCL");
|
||||
StringList l;
|
||||
for(PropertyMap::ConstIterator it = properties.begin(); it != properties.end(); ++it){
|
||||
if(!it->first.startsWith(instrumentPrefix)) // should not happen
|
||||
@ -120,12 +122,12 @@ void TextIdentificationFrame::setTextEncoding(String::Type encoding)
|
||||
|
||||
// array of allowed TIPL prefixes and their corresponding key value
|
||||
static const uint involvedPeopleSize = 5;
|
||||
static const char* involvedPeople[2] = {
|
||||
static const char* involvedPeople[][2] = {
|
||||
{"ARRANGER", "ARRANGER"},
|
||||
{"ENGINEER", "ENGINEER"},
|
||||
{"PRODUCER", "PRODUCER"},
|
||||
{"DJ-MIX", "DJMIXER"},
|
||||
{"MIX", "MIXER"}
|
||||
{"MIX", "MIXER"},
|
||||
};
|
||||
|
||||
const KeyConversionMap &TextIdentificationFrame::involvedPeopleMap() // static
|
||||
@ -144,7 +146,7 @@ PropertyMap TextIdentificationFrame::asProperties() const
|
||||
if(frameID() == "TMCL")
|
||||
return makeTMCLProperties();
|
||||
PropertyMap map;
|
||||
String tagName = frameIDToTagName(frameID());
|
||||
String tagName = frameIDToKey(frameID());
|
||||
if(tagName.isNull()) {
|
||||
map.unsupportedData().append(frameID());
|
||||
return map;
|
||||
@ -168,7 +170,9 @@ PropertyMap TextIdentificationFrame::asProperties() const
|
||||
(*it)[tpos] = ' ';
|
||||
}
|
||||
}
|
||||
return KeyValuePair(tagName, values);
|
||||
PropertyMap ret;
|
||||
ret.insert(tagName, values);
|
||||
return ret;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -261,7 +265,7 @@ PropertyMap TextIdentificationFrame::makeTIPLProperties() const
|
||||
bool found = false;
|
||||
for(uint i = 0; i < involvedPeopleSize; ++i)
|
||||
if(*it == involvedPeople[i][0]) {
|
||||
map.insert(involvedPeople[i][1], (++it).split(","));
|
||||
map.insert(involvedPeople[i][1], (++it)->split(","));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
@ -291,7 +295,7 @@ PropertyMap TextIdentificationFrame::makeTMCLProperties() const
|
||||
map.unsupportedData().append(frameID());
|
||||
return map;
|
||||
}
|
||||
map.insert(L"PERFORMER:" + instrument, (++it).split(","));
|
||||
map.insert(L"PERFORMER:" + instrument, (++it)->split(","));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "unsynchronizedlyricsframe.h"
|
||||
#include <tbytevectorlist.h>
|
||||
#include <tdebug.h>
|
||||
#include <tpropertymap.h>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "urllinkframe.h"
|
||||
#include <tdebug.h>
|
||||
#include <tstringlist.h>
|
||||
#include <tpropertymap.h>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
|
@ -39,6 +39,10 @@
|
||||
#include "id3v2frame.h"
|
||||
#include "id3v2synchdata.h"
|
||||
#include "tpropertymap.h"
|
||||
#include "frames/textidentificationframe.h"
|
||||
#include "frames/urllinkframe.h"
|
||||
#include "frames/unsynchronizedlyricsframe.h"
|
||||
#include "frames/commentsframe.h"
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
@ -96,9 +100,9 @@ ByteVector Frame::textDelimiter(String::Type t)
|
||||
return d;
|
||||
}
|
||||
|
||||
String TextIdentificationFrame::instrumentPrefix("PERFORMER:");
|
||||
String TextIdentificationFrame::commentPrefix("COMMENT:");
|
||||
String TextIdentificationFrame::urlPrefix("URL:");
|
||||
const String Frame::instrumentPrefix("PERFORMER:");
|
||||
const String Frame::commentPrefix("COMMENT:");
|
||||
const String Frame::urlPrefix("URL:");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
@ -110,11 +114,11 @@ Frame *Frame::createTextualFrame(const String &key, const StringList &values) //
|
||||
ByteVector frameID = keyToFrameID(key);
|
||||
if(!frameID.isNull()) {
|
||||
if(frameID[0] == 'T'){ // text frame
|
||||
TextIdentificationFrame* frame = TextIdentificationFrame(frameID, String::UTF8);
|
||||
TextIdentificationFrame *frame = new TextIdentificationFrame(frameID, String::UTF8);
|
||||
frame->setText(values);
|
||||
return frame;
|
||||
} else if(values.size() == 1){ // URL frame (not WXXX); support only one value
|
||||
UrlLinkFrame* frame = UrlLinkFrame(frameID);
|
||||
UrlLinkFrame* frame = new UrlLinkFrame(frameID);
|
||||
frame->setUrl(values.front());
|
||||
return frame;
|
||||
}
|
||||
@ -122,26 +126,26 @@ Frame *Frame::createTextualFrame(const String &key, const StringList &values) //
|
||||
// now we check if it's one of the "special" cases:
|
||||
// -LYRICS: depending on the number of values, use USLT or TXXX (with description=LYRICS)
|
||||
if(key == "LYRICS" && values.size() == 1){
|
||||
UnsynchronizedLyricsFrame *frame = UnsynchronizedLyricsFrame();
|
||||
UnsynchronizedLyricsFrame *frame = new UnsynchronizedLyricsFrame();
|
||||
frame->setText(values.front());
|
||||
return frame;
|
||||
}
|
||||
// -URL: depending on the number of values, use WXXX or TXXX (with description=URL)
|
||||
if((key == "URL" || key.startsWith(urlPrefix)) && values.size() == 1){
|
||||
UserUrlLinkFrame *frame = UserUrlLinkFrame(String::UTF8);
|
||||
UserUrlLinkFrame *frame = new UserUrlLinkFrame(String::UTF8);
|
||||
frame->setDescription(key == "URL" ? key : key.substr(urlPrefix.size()));
|
||||
frame->setUrl(values.front());
|
||||
return frame;
|
||||
}
|
||||
// -COMMENT: depending on the number of values, use COMM or TXXX (with description=COMMENT)
|
||||
if((key == "COMMENT" || key.startsWith(commentPrefix)) && values.size() == 1){
|
||||
CommentsFrame *frame = CommentsFrame(String::UTF8);
|
||||
CommentsFrame *frame = new CommentsFrame(String::UTF8);
|
||||
frame->setDescription(key == "COMMENT" ? key : key.substr(commentPrefix.size()));
|
||||
frame->setText(values.front());
|
||||
return frame;
|
||||
}
|
||||
// if non of the above cases apply, we use a TXXX frame with the key as description
|
||||
return UserTextIdentificationFrame(key, values, String::UTF8);
|
||||
return new UserTextIdentificationFrame(key, values, String::UTF8);
|
||||
}
|
||||
|
||||
Frame::~Frame()
|
||||
@ -391,9 +395,9 @@ static const char *deprecatedFrames[][2] = {
|
||||
{"TIME", "TDRC"}, // 2.3 -> 2.4
|
||||
};
|
||||
|
||||
FrameIDMap &deprecationMap()
|
||||
Map<ByteVector,ByteVector> &deprecationMap()
|
||||
{
|
||||
static FrameIDMap depMap;
|
||||
static Map<ByteVector,ByteVector> depMap;
|
||||
if(depMap.isEmpty())
|
||||
for(uint i = 0; i < deprecatedFramesSize; ++i)
|
||||
depMap[deprecatedFrames[i][0]] = deprecatedFrames[i][1];
|
||||
|
@ -354,17 +354,17 @@ PropertyMap ID3v2::Tag::setProperties(const PropertyMap &origProps)
|
||||
for(FrameListMap::ConstIterator it = frameListMap().begin(); it != frameListMap().end(); ++it){
|
||||
for(FrameList::ConstIterator lit = it->second.begin(); lit != it->second.end(); ++lit){
|
||||
PropertyMap frameProperties = (*lit)->asProperties();
|
||||
if(it->first == "TIPL")
|
||||
if(it->first == "TIPL") {
|
||||
if (tiplProperties != frameProperties)
|
||||
framesToDelete.append(*lit);
|
||||
else
|
||||
tiplProperties.erase(frameProperties);
|
||||
else if(it->first == "TMCL")
|
||||
} else if(it->first == "TMCL") {
|
||||
if (tmclProperties != frameProperties)
|
||||
framesToDelete.append(*lit);
|
||||
else
|
||||
tmclProperties.erase(frameProperties);
|
||||
else if(!properties.contains(frameProperties))
|
||||
} else if(!properties.contains(frameProperties))
|
||||
framesToDelete.append(*lit);
|
||||
else
|
||||
properties.erase(frameProperties);
|
||||
@ -383,7 +383,7 @@ PropertyMap ID3v2::Tag::setProperties(const PropertyMap &origProps)
|
||||
// now create the "one key per frame" frames
|
||||
for(PropertyMap::ConstIterator it = properties.begin(); it != properties.end(); ++it)
|
||||
addFrame(Frame::createTextualFrame(it->first, it->second));
|
||||
return PropertyMap; // ID3 implements the complete PropertyMap interface, so an empty map is returned
|
||||
return PropertyMap(); // ID3 implements the complete PropertyMap interface, so an empty map is returned
|
||||
}
|
||||
|
||||
ByteVector ID3v2::Tag::render() const
|
||||
|
@ -27,9 +27,11 @@
|
||||
|
||||
#include <tstring.h>
|
||||
#include <tdebug.h>
|
||||
#include <tpropertymap.h>
|
||||
|
||||
#include "vorbisfile.h"
|
||||
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class Vorbis::File::FilePrivate
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <tdebug.h>
|
||||
|
||||
#include <xiphcomment.h>
|
||||
#include <tpropertymap.h>
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
@ -188,45 +189,42 @@ const Ogg::FieldListMap &Ogg::XiphComment::fieldListMap() const
|
||||
return d->fieldListMap;
|
||||
}
|
||||
|
||||
TagDict Ogg::XiphComment::toDict() const
|
||||
PropertyMap Ogg::XiphComment::properties() const
|
||||
{
|
||||
return d->fieldListMap;
|
||||
}
|
||||
|
||||
void Ogg::XiphComment::fromDict(const TagDict &tagDict)
|
||||
PropertyMap Ogg::XiphComment::setProperties(const PropertyMap &properties)
|
||||
{
|
||||
// check which keys are to be deleted
|
||||
StringList toRemove;
|
||||
FieldListMap::ConstIterator it = d->fieldListMap.begin();
|
||||
for(; it != d->fieldListMap.end(); ++it) {
|
||||
if (!tagDict.contains(it->first))
|
||||
toRemove.append(it->first);
|
||||
}
|
||||
for(FieldListMap::ConstIterator it = d->fieldListMap.begin(); it != d->fieldListMap.end(); ++it)
|
||||
if (!properties.contains(it->first))
|
||||
toRemove.append(it->first);
|
||||
|
||||
StringList::ConstIterator removeIt = toRemove.begin();
|
||||
for (; removeIt != toRemove.end(); ++removeIt)
|
||||
removeField(*removeIt);
|
||||
for(StringList::ConstIterator it = toRemove.begin(); it != toRemove.end(); ++it)
|
||||
removeField(*it);
|
||||
|
||||
/* now go through keys in tagDict and check that the values match those in the xiph comment */
|
||||
TagDict::ConstIterator tagIt = tagDict.begin();
|
||||
for (; tagIt != tagDict.end(); ++tagIt)
|
||||
// now go through keys in \a properties and check that the values match those in the xiph comment */
|
||||
PropertyMap::ConstIterator it = properties.begin();
|
||||
for(; it != properties.end(); ++it)
|
||||
{
|
||||
if (!d->fieldListMap.contains(tagIt->first) || !(tagIt->second == d->fieldListMap[tagIt->first])) {
|
||||
const StringList &sl = tagIt->second;
|
||||
if(sl.size() == 0) {
|
||||
if(!d->fieldListMap.contains(it->first) || !(it->second == d->fieldListMap[it->first])) {
|
||||
const StringList &sl = it->second;
|
||||
if(sl.size() == 0)
|
||||
// zero size string list -> remove the tag with all values
|
||||
removeField(tagIt->first);
|
||||
}
|
||||
removeField(it->first);
|
||||
else {
|
||||
// replace all strings in the list for the tag
|
||||
StringList::ConstIterator valueIterator = sl.begin();
|
||||
addField(tagIt->first, *valueIterator, true);
|
||||
addField(it->first, *valueIterator, true);
|
||||
++valueIterator;
|
||||
for(; valueIterator != sl.end(); ++valueIterator)
|
||||
addField(tagIt->first, *valueIterator, false);
|
||||
addField(it->first, *valueIterator, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return PropertyMap();
|
||||
}
|
||||
|
||||
String Ogg::XiphComment::vendorID() const
|
||||
|
@ -141,19 +141,19 @@ namespace TagLib {
|
||||
const FieldListMap &fieldListMap() const;
|
||||
|
||||
/*!
|
||||
* Implements the unified tag dictionary interface -- export function.
|
||||
* Implements the unified property interface -- export function.
|
||||
* The result is a one-to-one match of the Xiph comment, since it is
|
||||
* completely compatible with the dictionary interface (in fact, a Xiph
|
||||
* completely compatible with the property interface (in fact, a Xiph
|
||||
* comment is nothing more than a map from tag names to list of values,
|
||||
* as is the dict interface).
|
||||
*/
|
||||
TagDict toDict() const;
|
||||
PropertyMap properties() const;
|
||||
|
||||
/*!
|
||||
* Implements the unified tag dictionary interface -- import function.
|
||||
* The tags from the given dict will be stored one-to-one in the file.
|
||||
* Implements the unified property interface -- import function.
|
||||
* The tags from the given map will be stored one-to-one in the file.
|
||||
*/
|
||||
void fromDict(const TagDict &);
|
||||
PropertyMap setProperties(const PropertyMap&);
|
||||
|
||||
/*!
|
||||
* Returns the vendor ID of the Ogg Vorbis encoder. libvorbis 1.0 as the
|
||||
|
@ -28,10 +28,21 @@ PropertyMap::PropertyMap() : SimplePropertyMap()
|
||||
{
|
||||
}
|
||||
|
||||
PropertyMap::PropertyMap(const PropertyMap &m) : SimplePropertyMap(m)
|
||||
PropertyMap::PropertyMap(const PropertyMap &m) : SimplePropertyMap(m), unsupported(m.unsupported)
|
||||
{
|
||||
}
|
||||
|
||||
PropertyMap::PropertyMap(const SimplePropertyMap &m)
|
||||
{
|
||||
for(SimplePropertyMap::ConstIterator it = m.begin(); it != m.end(); ++it){
|
||||
String key = prepareKey(it->first);
|
||||
if(!key.isNull())
|
||||
insert(it->first, it->second);
|
||||
else
|
||||
unsupported.append(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
PropertyMap::~PropertyMap()
|
||||
{
|
||||
}
|
||||
|
@ -58,6 +58,13 @@ namespace TagLib {
|
||||
|
||||
PropertyMap(const PropertyMap &m);
|
||||
|
||||
/*!
|
||||
* Creates a PropertyMap initialized from a SimplePropertyMap. Copies all
|
||||
* entries from \a m that have valid keys.
|
||||
* Invalid keys will be appended to the unsupportedData() list.
|
||||
*/
|
||||
PropertyMap(const SimplePropertyMap &m);
|
||||
|
||||
virtual ~PropertyMap();
|
||||
|
||||
/*!
|
||||
@ -93,7 +100,8 @@ namespace TagLib {
|
||||
|
||||
/*!
|
||||
* Returns true if this map contains all keys of \a other
|
||||
* and the values coincide for that keys.
|
||||
* and the values coincide for that keys. Does not take
|
||||
* the unsupportedData list into account.
|
||||
*/
|
||||
bool contains(const PropertyMap &other) const;
|
||||
|
||||
@ -131,6 +139,16 @@ namespace TagLib {
|
||||
*/
|
||||
StringList &operator[](const String &key);
|
||||
|
||||
/*!
|
||||
* Returns true if and only if \other has the same contents as this map.
|
||||
*/
|
||||
bool operator==(const PropertyMap &other) const;
|
||||
|
||||
/*!
|
||||
* Returns false if and only \other has the same contents as this map.
|
||||
*/
|
||||
bool operator!=(const PropertyMap &other) const;
|
||||
|
||||
/*!
|
||||
* If a PropertyMap is read from a File object using File::properties(),
|
||||
* the StringList returned from this function will represent metadata
|
||||
|
Reference in New Issue
Block a user