]> granicus.if.org Git - taglib/commitdiff
Make FileRef::FileTypeResolver work properly.
authorTsuda Kageyu <tsuda.kageyu@gmail.com>
Sat, 21 Nov 2015 09:29:41 +0000 (18:29 +0900)
committerTsuda Kageyu <tsuda.kageyu@gmail.com>
Sat, 21 Nov 2015 09:29:41 +0000 (18:29 +0900)
taglib/fileref.cpp
tests/test_fileref.cpp

index 0be65603824b2f90886b292bce097a83ab17e472..7cf78803458c5350042739260a27922076d714db 100644 (file)
@@ -56,7 +56,8 @@ using namespace TagLib;
 
 namespace
 {
-  List<const FileRef::FileTypeResolver *> fileTypeResolvers;
+  typedef List<const FileRef::FileTypeResolver *> ResolverList;
+  ResolverList fileTypeResolvers;
 
   // Templatized internal functions. T should be String or IOStream*.
 
@@ -79,8 +80,41 @@ namespace
   }
 
   template <typename T>
-  File* createInternal(T arg, bool readAudioProperties, AudioProperties::ReadStyle audioPropertiesStyle)
+  inline File *resolveFileType(T arg, bool readProperties,
+                               AudioProperties::ReadStyle style)
   {
+    // Should never be called.
+  }
+
+  template <>
+  inline File *resolveFileType<IOStream *>(IOStream *arg, bool readProperties,
+                                           AudioProperties::ReadStyle style)
+  {
+    return 0;
+  }
+
+  template <>
+  inline File *resolveFileType<FileName>(FileName arg, bool readProperties,
+                                         AudioProperties::ReadStyle style)
+  {
+    ResolverList::ConstIterator it = fileTypeResolvers.begin();
+    for(; it != fileTypeResolvers.end(); ++it) {
+      File *file = (*it)->createFile(arg, readProperties, style);
+      if(file)
+        return file;
+    }
+
+    return 0;
+  }
+
+  template <typename T>
+  File* createInternal(T arg, bool readAudioProperties,
+                       AudioProperties::ReadStyle audioPropertiesStyle)
+  {
+    File *file = resolveFileType(arg, readAudioProperties, audioPropertiesStyle);
+    if(file)
+      return file;
+
 #ifdef _WIN32
     const String s = toFileName(arg).toString();
 #else
@@ -302,14 +336,5 @@ bool FileRef::operator!=(const FileRef &ref) const
 File *FileRef::create(FileName fileName, bool readAudioProperties,
                       AudioProperties::ReadStyle audioPropertiesStyle) // static
 {
-
-  List<const FileTypeResolver *>::ConstIterator it = fileTypeResolvers.begin();
-
-  for(; it != fileTypeResolvers.end(); ++it) {
-    File *file = (*it)->createFile(fileName, readAudioProperties, audioPropertiesStyle);
-    if(file)
-      return file;
-  }
-
   return createInternal(fileName, readAudioProperties, audioPropertiesStyle);
 }
index a51b868c33026ef87fb8d86f640ac230baf7aeba..a389cfd3363d392a812626e644f1ee007e53667b 100644 (file)
@@ -4,6 +4,7 @@
 #include <fileref.h>
 #include <oggflacfile.h>
 #include <vorbisfile.h>
+#include <mpegfile.h>
 #include <cppunit/extensions/HelperMacros.h>
 #include "utils.h"
 #include <tfilestream.h>
 using namespace std;
 using namespace TagLib;
 
+namespace
+{
+  class DummyResolver : public FileRef::FileTypeResolver
+  {
+  public:
+    virtual File *createFile(FileName fileName, bool, AudioProperties::ReadStyle) const
+    {
+      return new Ogg::Vorbis::File(fileName);
+    }
+  };
+}
+
 class TestFileRef : public CppUnit::TestFixture
 {
   CPPUNIT_TEST_SUITE(TestFileRef);
@@ -29,6 +42,7 @@ class TestFileRef : public CppUnit::TestFixture
   CPPUNIT_TEST(testAPE);
   CPPUNIT_TEST(testWav);
   CPPUNIT_TEST(testUnsupported);
+  CPPUNIT_TEST(testFileResolver);
   CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -168,10 +182,25 @@ public:
   {
     FileRef f1(TEST_FILE_PATH_C("no-extension"));
     CPPUNIT_ASSERT(f1.isNull());
-    
+
     FileRef f2(TEST_FILE_PATH_C("unsupported-extension.xxx"));
     CPPUNIT_ASSERT(f2.isNull());
   }
+
+  void testFileResolver()
+  {
+    FileRef *f = new FileRef(TEST_FILE_PATH_C("xing.mp3"));
+    CPPUNIT_ASSERT(dynamic_cast<MPEG::File *>(f->file()) != NULL);
+    delete f;
+
+    DummyResolver resolver;
+    FileRef::addFileTypeResolver(&resolver);
+
+    f = new FileRef(TEST_FILE_PATH_C("xing.mp3"));
+    CPPUNIT_ASSERT(dynamic_cast<Ogg::Vorbis::File *>(f->file()) != NULL);
+    delete f;
+  }
+
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(TestFileRef);