namespace
{
- List<const FileRef::FileTypeResolver *> fileTypeResolvers;
+ typedef List<const FileRef::FileTypeResolver *> ResolverList;
+ ResolverList fileTypeResolvers;
// Templatized internal functions. T should be String or IOStream*.
}
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
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);
}
#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);
CPPUNIT_TEST(testAPE);
CPPUNIT_TEST(testWav);
CPPUNIT_TEST(testUnsupported);
+ CPPUNIT_TEST(testFileResolver);
CPPUNIT_TEST_SUITE_END();
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);