mirror of
https://github.com/taglib/taglib.git
synced 2025-05-27 21:20:26 -04:00
Efficient lookup for the ID3v2 frame ID table.
Linear lookup is much faster and memory efficient when an array is very small.
This commit is contained in:
parent
74cb6f3fc7
commit
21788f4a26
@ -146,7 +146,7 @@ PropertyMap TextIdentificationFrame::asProperties() const
|
||||
return makeTMCLProperties();
|
||||
PropertyMap map;
|
||||
String tagName = frameIDToKey(frameID());
|
||||
if(tagName.isNull()) {
|
||||
if(tagName.isEmpty()) {
|
||||
map.unsupportedData().append(frameID());
|
||||
return map;
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ PropertyMap UrlLinkFrame::asProperties() const
|
||||
{
|
||||
String key = frameIDToKey(frameID());
|
||||
PropertyMap map;
|
||||
if(key.isNull())
|
||||
if(key.isEmpty())
|
||||
// unknown W*** frame - this normally shouldn't happen
|
||||
map.unsupportedData().append(frameID());
|
||||
else
|
||||
|
@ -116,7 +116,7 @@ Frame *Frame::createTextualFrame(const String &key, const StringList &values) //
|
||||
{
|
||||
// check if the key is contained in the key<=>frameID mapping
|
||||
ByteVector frameID = keyToFrameID(key);
|
||||
if(!frameID.isNull()) {
|
||||
if(!frameID.isEmpty()) {
|
||||
// Apple proprietary WFED (Podcast URL) is in fact a text frame.
|
||||
if(frameID[0] == 'T' || frameID == "WFED"){ // text frame
|
||||
TextIdentificationFrame *frame = new TextIdentificationFrame(frameID, String::UTF8);
|
||||
@ -364,7 +364,7 @@ String::Type Frame::checkTextEncoding(const StringList &fields, String::Type enc
|
||||
return checkEncoding(fields, encoding, header()->version());
|
||||
}
|
||||
|
||||
static const TagLib::uint frameTranslationSize = 51;
|
||||
static const size_t frameTranslationSize = 51;
|
||||
static const char *frameTranslation[][2] = {
|
||||
// Text information frames
|
||||
{ "TALB", "ALBUM"},
|
||||
@ -436,41 +436,20 @@ static const char *frameTranslation[][2] = {
|
||||
{ "WFED", "PODCASTURL" },
|
||||
};
|
||||
|
||||
static const TagLib::uint txxxFrameTranslationSize = 8;
|
||||
static const size_t txxxFrameTranslationSize = 8;
|
||||
static const char *txxxFrameTranslation[][2] = {
|
||||
{ "MusicBrainz Album Id", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "MusicBrainz Artist Id", "MUSICBRAINZ_ARTISTID" },
|
||||
{ "MusicBrainz Album Artist Id", "MUSICBRAINZ_ALBUMARTISTID" },
|
||||
{ "MusicBrainz Release Group Id", "MUSICBRAINZ_RELEASEGROUPID" },
|
||||
{ "MusicBrainz Work Id", "MUSICBRAINZ_WORKID" },
|
||||
{ "Acoustid Id", "ACOUSTID_ID" },
|
||||
{ "Acoustid Fingerprint", "ACOUSTID_FINGERPRINT" },
|
||||
{ "MusicIP PUID", "MUSICIP_PUID" },
|
||||
{ "MUSICBRAINZ ALBUM ID", "MUSICBRAINZ_ALBUMID" },
|
||||
{ "MUSICBRAINZ ARTIST ID", "MUSICBRAINZ_ARTISTID" },
|
||||
{ "MUSICBRAINZ ALBUM ARTIST ID", "MUSICBRAINZ_ALBUMARTISTID" },
|
||||
{ "MUSICBRAINZ RELEASE GROUP ID", "MUSICBRAINZ_RELEASEGROUPID" },
|
||||
{ "MUSICBRAINZ WORK ID", "MUSICBRAINZ_WORKID" },
|
||||
{ "ACOUSTID ID", "ACOUSTID_ID" },
|
||||
{ "ACOUSTID FINGERPRINT", "ACOUSTID_FINGERPRINT" },
|
||||
{ "MUSICIP PUID", "MUSICIP_PUID" },
|
||||
};
|
||||
|
||||
Map<ByteVector, String> &idMap()
|
||||
{
|
||||
static Map<ByteVector, String> m;
|
||||
if(m.isEmpty())
|
||||
for(size_t i = 0; i < frameTranslationSize; ++i)
|
||||
m[frameTranslation[i][0]] = frameTranslation[i][1];
|
||||
return m;
|
||||
}
|
||||
|
||||
Map<String, String> &txxxMap()
|
||||
{
|
||||
static Map<String, String> m;
|
||||
if(m.isEmpty()) {
|
||||
for(size_t i = 0; i < txxxFrameTranslationSize; ++i) {
|
||||
String key = String(txxxFrameTranslation[i][0]).upper();
|
||||
m[key] = txxxFrameTranslation[i][1];
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
// list of deprecated frames and their successors
|
||||
static const TagLib::uint deprecatedFramesSize = 4;
|
||||
static const size_t deprecatedFramesSize = 4;
|
||||
static const char *deprecatedFrames[][2] = {
|
||||
{"TRDA", "TDRC"}, // 2.3 -> 2.4 (http://en.wikipedia.org/wiki/ID3)
|
||||
{"TDAT", "TDRC"}, // 2.3 -> 2.4
|
||||
@ -478,53 +457,49 @@ static const char *deprecatedFrames[][2] = {
|
||||
{"TIME", "TDRC"}, // 2.3 -> 2.4
|
||||
};
|
||||
|
||||
Map<ByteVector,ByteVector> &deprecationMap()
|
||||
{
|
||||
static Map<ByteVector,ByteVector> depMap;
|
||||
if(depMap.isEmpty())
|
||||
for(TagLib::uint i = 0; i < deprecatedFramesSize; ++i)
|
||||
depMap[deprecatedFrames[i][0]] = deprecatedFrames[i][1];
|
||||
return depMap;
|
||||
}
|
||||
|
||||
String Frame::frameIDToKey(const ByteVector &id)
|
||||
{
|
||||
Map<ByteVector, String> &m = idMap();
|
||||
if(m.contains(id))
|
||||
return m[id];
|
||||
if(deprecationMap().contains(id))
|
||||
return m[deprecationMap()[id]];
|
||||
return String::null;
|
||||
ByteVector id24 = id;
|
||||
for(size_t i = 0; i < deprecatedFramesSize; ++i) {
|
||||
if(id24 == deprecatedFrames[i][0]) {
|
||||
id24 = deprecatedFrames[i][1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(size_t i = 0; i < frameTranslationSize; ++i) {
|
||||
if(id24 == frameTranslation[i][0])
|
||||
return frameTranslation[i][1];
|
||||
}
|
||||
return String();
|
||||
}
|
||||
|
||||
ByteVector Frame::keyToFrameID(const String &s)
|
||||
{
|
||||
static Map<String, ByteVector> m;
|
||||
if(m.isEmpty())
|
||||
for(size_t i = 0; i < frameTranslationSize; ++i)
|
||||
m[frameTranslation[i][1]] = frameTranslation[i][0];
|
||||
if(m.contains(s.upper()))
|
||||
return m[s];
|
||||
return ByteVector::null;
|
||||
const String key = s.upper();
|
||||
for(size_t i = 0; i < frameTranslationSize; ++i) {
|
||||
if(key == frameTranslation[i][1])
|
||||
return frameTranslation[i][0];
|
||||
}
|
||||
return ByteVector();
|
||||
}
|
||||
|
||||
String Frame::txxxToKey(const String &description)
|
||||
{
|
||||
Map<String, String> &m = txxxMap();
|
||||
String d = description.upper();
|
||||
if(m.contains(d))
|
||||
return m[d];
|
||||
const String d = description.upper();
|
||||
for(size_t i = 0; i < txxxFrameTranslationSize; ++i) {
|
||||
if(d == txxxFrameTranslation[i][0])
|
||||
return txxxFrameTranslation[i][1];
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
String Frame::keyToTXXX(const String &s)
|
||||
{
|
||||
static Map<String, String> m;
|
||||
if(m.isEmpty())
|
||||
for(size_t i = 0; i < txxxFrameTranslationSize; ++i)
|
||||
m[txxxFrameTranslation[i][1]] = txxxFrameTranslation[i][0];
|
||||
if(m.contains(s.upper()))
|
||||
return m[s];
|
||||
const String key = s.upper();
|
||||
for(size_t i = 0; i < txxxFrameTranslationSize; ++i) {
|
||||
if(key == txxxFrameTranslation[i][1])
|
||||
return txxxFrameTranslation[i][0];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -560,7 +535,6 @@ PropertyMap Frame::asProperties() const
|
||||
void Frame::splitProperties(const PropertyMap &original, PropertyMap &singleFrameProperties,
|
||||
PropertyMap &tiplProperties, PropertyMap &tmclProperties)
|
||||
{
|
||||
|
||||
singleFrameProperties.clear();
|
||||
tiplProperties.clear();
|
||||
tmclProperties.clear();
|
||||
|
@ -264,13 +264,13 @@ namespace TagLib {
|
||||
|
||||
/*!
|
||||
* Returns an appropriate ID3 frame ID for the given free-form tag key. This method
|
||||
* will return ByteVector::null if no specialized translation is found.
|
||||
* will return an empty ByteVector if no specialized translation is found.
|
||||
*/
|
||||
static ByteVector keyToFrameID(const String &);
|
||||
|
||||
/*!
|
||||
* Returns a free-form tag name for the given ID3 frame ID. Note that this does not work
|
||||
* for general frame IDs such as TXXX or WXXX; in such a case String::null is returned.
|
||||
* for general frame IDs such as TXXX or WXXX; in such a case an empty string is returned.
|
||||
*/
|
||||
static String frameIDToKey(const ByteVector &);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user