mirror of
https://github.com/taglib/taglib.git
synced 2025-06-03 09:08:09 -04:00
Basic implementation of a PropertyMap.
Implemented key/valuelist property map with case-insensitive ASCII keys and StringList values. Todo: - subclass StringList to add flags indicating whether a value could be written to the specific file format - add member attribute indicating list of frames that could not be parsed into the PropertyMap representation.
This commit is contained in:
parent
67d896e6a7
commit
d11189b975
@ -48,6 +48,7 @@ set(tag_HDRS
|
||||
toolkit/tfilestream.h
|
||||
toolkit/tmap.h
|
||||
toolkit/tmap.tcc
|
||||
toolkit/tpropertymap.h
|
||||
mpeg/mpegfile.h
|
||||
mpeg/mpegproperties.h
|
||||
mpeg/mpegheader.h
|
||||
@ -277,6 +278,7 @@ set(toolkit_SRCS
|
||||
toolkit/tfile.cpp
|
||||
toolkit/tfilestream.cpp
|
||||
toolkit/tdebug.cpp
|
||||
toolkit/tpropertymap.cpp
|
||||
toolkit/unicode.cpp
|
||||
)
|
||||
|
||||
|
@ -134,6 +134,33 @@ namespace TagLib {
|
||||
return m;
|
||||
}
|
||||
|
||||
// list of TXXX frame description conversions
|
||||
static const uint txxxConversionSize = 4;
|
||||
static const char *txxxConversionFrames[][2] = {
|
||||
{"MusicBrainz Artist Id", "MUSICBRAINZ_ARTISTID"},
|
||||
{"MusicBrainz Disc Id", "MUSICBRAINZ_DISCID"},
|
||||
{"MusicBrainz Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID"},
|
||||
{"MusicBrainz Album Id", "MUSICBRAINZ_ALBUMID"},
|
||||
{"MusicMagic Fingerprint", "MUSICIP_FINGERPRINT"},
|
||||
{"MusicIP PUID", "MUSICIP_PUID"},
|
||||
{"MusicBrainz Album Release Country", "RELEASECOUNTRY"},
|
||||
{"MusicBrainz Album Status", "MUSICBRAINZ_ALBUMSTATUS"},
|
||||
{"MusicBrainz Album Type", "MUSICBRAINZ_ALBUMTYPE"},
|
||||
{"MusicBrainz Release Group Id", "MUSICBRAINZ_RELEASE_GROUPID"},
|
||||
{"MusicBrainz Work Id", "MUSICBRAINZ_WORKID"},
|
||||
{"MusicBrainz Original Album Id", "MUSICBRAINZ_ORIGINALALBUMID"},
|
||||
{"Acoustid Fingerprint", "ACOUSTID_FINGERPRINT"},
|
||||
{"Acoustid Id", "ACOUSTID_ID"}
|
||||
};
|
||||
|
||||
FrameIDMap &txxxConversionMap()
|
||||
{
|
||||
static FrameIDMap txxxMap;
|
||||
if (txxxMap.isEmpty())
|
||||
for(uint i = 0; i < txxxConversionSize; ++i)
|
||||
txxxMap[txxxConversionFrames[i][0]] = txxxConversionFrames[i][1];
|
||||
return txxxMap;
|
||||
}
|
||||
String frameIDToTagName(const ByteVector &id)
|
||||
{
|
||||
Map<ByteVector, String> &m = idMap();
|
||||
|
120
taglib/toolkit/tpropertymap.cpp
Normal file
120
taglib/toolkit/tpropertymap.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2012 by Michael Helmling
|
||||
email : helmling@mathematik.uni-kl.de
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License version *
|
||||
* 2.1 as published by the Free Software Foundation. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301 USA *
|
||||
***************************************************************************/
|
||||
|
||||
#include "tpropertymap.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
typedef Map<String,StringList> supertype;
|
||||
|
||||
PropertyMap::PropertyMap() : Map<String,StringList>()
|
||||
{
|
||||
}
|
||||
|
||||
PropertyMap::PropertyMap(const PropertyMap &m) : Map<String,StringList>(m)
|
||||
{
|
||||
}
|
||||
|
||||
PropertyMap::~PropertyMap()
|
||||
{
|
||||
}
|
||||
|
||||
bool PropertyMap::insert(const String &key, const StringList &values)
|
||||
{
|
||||
String realKey = prepareKey(key);
|
||||
if (realKey.isNull())
|
||||
return false;
|
||||
|
||||
supertype::operator[](realKey).append(values);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyMap::replace(const String &key, const StringList &values)
|
||||
{
|
||||
String realKey = prepareKey(key);
|
||||
if (realKey.isNull())
|
||||
return false;
|
||||
supertype::erase(realKey);
|
||||
supertype::insert(realKey, values);
|
||||
return true;
|
||||
}
|
||||
|
||||
PropertyMap::Iterator PropertyMap::find(const String &key)
|
||||
{
|
||||
String realKey = prepareKey(key);
|
||||
if (realKey.isNull())
|
||||
return end();
|
||||
return supertype::find(realKey);
|
||||
}
|
||||
|
||||
PropertyMap::ConstIterator PropertyMap::find(const String &key) const
|
||||
{
|
||||
String realKey = prepareKey(key);
|
||||
if (realKey.isNull())
|
||||
return end();
|
||||
return supertype::find(realKey);
|
||||
}
|
||||
|
||||
bool PropertyMap::contains(const String &key) const
|
||||
{
|
||||
String realKey = prepareKey(key);
|
||||
if (realKey.isNull())
|
||||
return false;
|
||||
return supertype::contains(realKey);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Erase the \a key and its values from the map.
|
||||
*/
|
||||
PropertyMap &PropertyMap::erase(const String &key)
|
||||
{
|
||||
String realKey = prepareKey(key);
|
||||
if (realKey.isNull())
|
||||
return *this;
|
||||
supertype::erase(realKey);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const StringList &PropertyMap::operator[](const String &key) const
|
||||
{
|
||||
String realKey = prepareKey(key);
|
||||
return supertype::operator[](realKey);
|
||||
}
|
||||
|
||||
StringList &PropertyMap::operator[](const String &key)
|
||||
{
|
||||
String realKey = prepareKey(key);
|
||||
if (realKey.isNull())
|
||||
return supertype::operator[](realKey); // invalid case
|
||||
if (!supertype::contains(realKey))
|
||||
supertype::insert(realKey, StringList());
|
||||
return supertype::operator[](realKey);
|
||||
}
|
||||
|
||||
String PropertyMap::prepareKey(const String &proposed) const {
|
||||
if (proposed.isEmpty())
|
||||
return String::null;
|
||||
for (String::ConstIterator it = proposed.begin(); it != proposed.end(); it++)
|
||||
// forbid non-printable, non-ascii, '=' (#61) and '~' (#126)
|
||||
if (*it < 32 || *it >= 128 || *it == 61 || *it == 126)
|
||||
return String::null;
|
||||
return proposed.upper();
|
||||
}
|
118
taglib/toolkit/tpropertymap.h
Normal file
118
taglib/toolkit/tpropertymap.h
Normal file
@ -0,0 +1,118 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2012 by Michael Helmling
|
||||
email : helmling@mathematik.uni-kl.de
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License version *
|
||||
* 2.1 as published by the Free Software Foundation. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
|
||||
* MA 02110-1301 USA *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef PROPERTYMAP_H_
|
||||
#define PROPERTYMAP_H_
|
||||
|
||||
#include "tmap.h"
|
||||
#include "tstringlist.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
|
||||
//! A map for format-independent <key,valuelist> tag representations.
|
||||
|
||||
/*!
|
||||
* This map implements a generic representation of textual audio metadata
|
||||
* ("tags") realized as pairs of a case-insensitive key
|
||||
* and a nonempty list of corresponding values, each value being an an arbitrary
|
||||
* Unicode String.
|
||||
* The key has the same restrictions as in the vorbis comment specification,
|
||||
* i.e. it must contain at least one character; all printable ASCII characters
|
||||
* except '=' and '~' are allowed.
|
||||
*
|
||||
*/
|
||||
|
||||
class PropertyMap: public Map<String,StringList>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Map<String,StringList>::Iterator Iterator;
|
||||
typedef Map<String,StringList>::ConstIterator ConstIterator;
|
||||
|
||||
PropertyMap();
|
||||
|
||||
PropertyMap(const PropertyMap &m);
|
||||
|
||||
virtual ~PropertyMap();
|
||||
|
||||
/*!
|
||||
* Inserts \a values under \a key in the map. If \a key already exists,
|
||||
* then \values will be appended to the existing StringList.
|
||||
* The returned value indicates success, i.e. whether \a key is a
|
||||
* valid key.
|
||||
*/
|
||||
bool insert(const String &key, const StringList &values);
|
||||
|
||||
/*!
|
||||
* Replaces any existing values for \a key with the given \a values,
|
||||
* and simply insert them if \a key did not exist before.
|
||||
* The returned value indicates success, i.e. whether \a key is a
|
||||
* valid key.
|
||||
*/
|
||||
bool replace(const String &key, const StringList &values);
|
||||
|
||||
/*!
|
||||
* Find the first occurrence of \a key.
|
||||
*/
|
||||
Iterator find(const String &key);
|
||||
|
||||
/*!
|
||||
* Find the first occurrence of \a key.
|
||||
*/
|
||||
ConstIterator find(const String &key) const;
|
||||
|
||||
/*!
|
||||
* Returns true if the map contains values for \a key.
|
||||
*/
|
||||
bool contains(const String &key) const;
|
||||
|
||||
/*!
|
||||
* Erase the \a key and its values from the map.
|
||||
*/
|
||||
PropertyMap &erase(const String &key);
|
||||
|
||||
/*!
|
||||
* Returns a reference to the value associated with \a key.
|
||||
*
|
||||
* \note: This has undefined behavior if the key is not valid.
|
||||
*/
|
||||
const StringList &operator[](const String &key) const;
|
||||
|
||||
/*!
|
||||
* Returns a reference to the value associated with \a key.
|
||||
*
|
||||
* If \a key is not present in the map, an empty list is inserted and
|
||||
* returned.
|
||||
*
|
||||
* \note: This has undefined behavior if the key is not valid.
|
||||
*/
|
||||
StringList &operator[](const String &key);
|
||||
|
||||
/*!
|
||||
* Converts \a proposed into another String suitable to be used as
|
||||
* a key, or returns String::null if this is not possible.
|
||||
*/
|
||||
String prepareKey(const String &proposed) const;
|
||||
};
|
||||
|
||||
}
|
||||
#endif /* PROPERTYMAP_H_ */
|
Loading…
x
Reference in New Issue
Block a user