diff --git a/fileref.cpp b/fileref.cpp index 2da2e71f..6c12749d 100644 --- a/fileref.cpp +++ b/fileref.cpp @@ -39,8 +39,11 @@ public: } File *file; + static List fileTypeResolvers; }; +List FileRef::FileRefPrivate::fileTypeResolvers; + //////////////////////////////////////////////////////////////////////////////// // public members //////////////////////////////////////////////////////////////////////////////// @@ -92,6 +95,11 @@ bool FileRef::save() return d->file->save(); } +void FileRef::addFileTypeResolver(const FileTypeResolver *resolver) // static +{ + FileRefPrivate::fileTypeResolvers.prepend(resolver); +} + bool FileRef::isNull() const { return !d->file || !d->file->isValid(); diff --git a/fileref.h b/fileref.h index ffa7864f..b4e64eea 100644 --- a/fileref.h +++ b/fileref.h @@ -43,32 +43,61 @@ namespace TagLib { * across file types. * * Also note that it is probably a good idea to plug this into your mime - * type system rather than using the constructor that accepts a file name. + * type system rather than using the constructor that accepts a file name using + * the FileTypeResolver. * - * For example in KDE this could be done with: - * - * \code - * - * TagLib::FileRef createFileRef( const QString &fileName ) - * { - * KMimeType::Ptr result = KMimeType::findByPath( fileName, 0, true ); - * - * if( result->name() == "audio/x-mp3" ) - * return FileRef( new MPEG::File( QFile::encodeName( fileName ).data() ) ); - * - * if( result->name() == "application/ogg" ) - * return FileRef( new Vorbis::File( QFile::encodeName( fileName ).data() ) ); - * - * return FileRef( 0 ); - * } - * - * \endcode + * \see FileTypeResolver + * \see addFileTypeResolver() */ class FileRef { public: + //! A class for pluggable file type resolution. + + /*! + * This class is used to add extend TagLib's very basic file name based file + * type resolution. + * + * This can be accomplished with: + * + * \code + * + * class MyFileTypeResolver : FileTypeResolver + * { + * TagLib::File *createFile(const char *fileName) + * { + * if(someCheckForAnMP3File(fileName)) + * return new TagLib::MPEG::File(fileName); + * return 0; + * } + * } + * + * FileRef::addFileTypeResolver(new MyFileTypeResolver); + * + * \endcode + * + * Naturally a less contrived example would be slightly more complex. This + * can be used to plug in mime-type detection systems or to add new file types + * to TagLib. + */ + + class FileTypeResolver + { + public: + /*! + * This method must be overriden to provide an additional file type + * resolver. If the resolver is able to determine the file type it should + * return a valid File object; if not it should return 0. + * + * \note The created file is then owned by the FileRef and should not be + * deleted. Deletion will happen automatically when the FileRef passes + * out of scope. + */ + virtual File *createFile(const char *fileName) = 0; + }; + FileRef(); /*! @@ -139,6 +168,14 @@ namespace TagLib { */ bool save(); + /*! + * Adds a FileTypeResolver to the list of those used by TagLib. Each + * additional FileTypeResolver is added to the front of a list of resolvers + * that are tried. If the FileTypeResolver returns zero the next resolver + * is tried. + */ + static void addFileTypeResolver(const FileTypeResolver *resolver); + /*! * Returns true if the file (and as such other pointers) are null. */ diff --git a/tests/toolkit-test.cpp b/tests/toolkit-test.cpp index aa1042d2..e5b8ae3f 100644 --- a/tests/toolkit-test.cpp +++ b/tests/toolkit-test.cpp @@ -233,11 +233,11 @@ void testList() List l1; List l2; List l3; - l1.append(1); l1.append(2); l2.append(3); l2.append(4); l1.append(l2); + l1.prepend(1); l3.append(1); l3.append(2); l3.append(3); diff --git a/toolkit/tlist.h b/toolkit/tlist.h index 3ea7a669..371543a5 100644 --- a/toolkit/tlist.h +++ b/toolkit/tlist.h @@ -120,6 +120,9 @@ namespace TagLib { */ List &append(const List &l); + List &prepend(const T &item); + List &prepend(const List &l); + /*! * Clears the list. If auto deletion is enabled and this list contains a * pointer type the members are also deleted. diff --git a/toolkit/tlist.tcc b/toolkit/tlist.tcc index ae3f9a22..38a150a8 100644 --- a/toolkit/tlist.tcc +++ b/toolkit/tlist.tcc @@ -164,6 +164,22 @@ List &List::append(const List &l) return *this; } +template +List &List::prepend(const T &item) +{ + detach(); + d->list.push_front(item); + return *this; +} + +template +List &List::prepend(const List &l) +{ + detach(); + d->list.insert(d->list.begin(), l.begin(), l.end()); + return *this; +} + template void List::clear() {