]> granicus.if.org Git - taglib/commitdiff
Efficient lookup for the ID3v2 frame ID table.
authorTsuda Kageyu <tsuda.kageyu@gmail.com>
Thu, 19 Nov 2015 01:07:10 +0000 (10:07 +0900)
committerTsuda Kageyu <tsuda.kageyu@gmail.com>
Thu, 19 Nov 2015 01:07:10 +0000 (10:07 +0900)
Linear lookup is much faster and memory efficient when an array is very small.

taglib/mpeg/id3v2/frames/textidentificationframe.cpp
taglib/mpeg/id3v2/frames/urllinkframe.cpp
taglib/mpeg/id3v2/id3v2frame.cpp
taglib/mpeg/id3v2/id3v2frame.h

index b77dd547536373b4838d360ea73e862e8d0a9116..07bf0edea584e0b4ddb0cad3f69532ee6c6d96a0 100644 (file)
@@ -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;
   }
index 1225b524710090982522f1ad758301ababacf015..e42d64d177c5f06715a6b6622691044e70baaf82 100644 (file)
@@ -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
index 4313bcc6ac08edfc393e18a6b26002e5b032c2c7..a130d0030982953fe19c014d4331978438131c2a 100644 (file)
@@ -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();
index 3771f4f03920443013f37eefa0caee870841d8c6..ae1e2473bf24debc2fa1a32ffabfaca6ab1bead5 100644 (file)
@@ -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 &);