From 0db487bf61ecece1abbed6d0557b1706410a4cc1 Mon Sep 17 00:00:00 2001 From: Urs Fleisch Date: Sat, 21 Oct 2023 15:24:44 +0200 Subject: [PATCH] Remove deprecated FileRef::create() method In order to achieve this, the TagLib_File type of the C bindings is now a FileRef and no longer a File. The support for the .oga extension has been ported to FileRef(), so that taglib_file_new() should still behave the same, but additionally also support content based file type detection. --- bindings/c/tag_c.cpp | 60 ++++++++++++++++------------ taglib/fileref.cpp | 88 ++++-------------------------------------- taglib/fileref.h | 20 +--------- tests/test_fileref.cpp | 18 --------- 4 files changed, 46 insertions(+), 140 deletions(-) diff --git a/bindings/c/tag_c.cpp b/bindings/c/tag_c.cpp index 88069232..595b6273 100644 --- a/bindings/c/tag_c.cpp +++ b/bindings/c/tag_c.cpp @@ -92,67 +92,79 @@ void taglib_free(void* pointer) } //////////////////////////////////////////////////////////////////////////////// -// TagLib::File wrapper +// TagLib::FileRef wrapper //////////////////////////////////////////////////////////////////////////////// TagLib_File *taglib_file_new(const char *filename) { - return reinterpret_cast(FileRef::create(filename)); + return reinterpret_cast(new FileRef(filename)); } TagLib_File *taglib_file_new_type(const char *filename, TagLib_File_Type type) { + File *file = NULL; switch(type) { case TagLib_File_MPEG: - return reinterpret_cast(new MPEG::File(filename)); + file = new MPEG::File(filename); + break; case TagLib_File_OggVorbis: - return reinterpret_cast(new Ogg::Vorbis::File(filename)); + file = new Ogg::Vorbis::File(filename); + break; case TagLib_File_FLAC: - return reinterpret_cast(new FLAC::File(filename)); + file = new FLAC::File(filename); + break; case TagLib_File_MPC: - return reinterpret_cast(new MPC::File(filename)); + file = new MPC::File(filename); + break; case TagLib_File_OggFlac: - return reinterpret_cast(new Ogg::FLAC::File(filename)); + file = new Ogg::FLAC::File(filename); + break; case TagLib_File_WavPack: - return reinterpret_cast(new WavPack::File(filename)); + file = new WavPack::File(filename); + break; case TagLib_File_Speex: - return reinterpret_cast(new Ogg::Speex::File(filename)); + file = new Ogg::Speex::File(filename); + break; case TagLib_File_TrueAudio: - return reinterpret_cast(new TrueAudio::File(filename)); + file = new TrueAudio::File(filename); + break; case TagLib_File_MP4: - return reinterpret_cast(new MP4::File(filename)); + file = new MP4::File(filename); + break; case TagLib_File_ASF: - return reinterpret_cast(new ASF::File(filename)); + file = new ASF::File(filename); + break; default: - return 0; + break; } + return file ? reinterpret_cast(new FileRef(file)) : NULL; } void taglib_file_free(TagLib_File *file) { - delete reinterpret_cast(file); + delete reinterpret_cast(file); } BOOL taglib_file_is_valid(const TagLib_File *file) { - return reinterpret_cast(file)->isValid(); + return !reinterpret_cast(file)->isNull(); } TagLib_Tag *taglib_file_tag(const TagLib_File *file) { - auto f = reinterpret_cast(file); + auto f = reinterpret_cast(file); return reinterpret_cast(f->tag()); } const TagLib_AudioProperties *taglib_file_audioproperties(const TagLib_File *file) { - auto f = reinterpret_cast(file); + auto f = reinterpret_cast(file); return reinterpret_cast(f->audioProperties()); } BOOL taglib_file_save(TagLib_File *file) { - return reinterpret_cast(file)->save(); + return reinterpret_cast(file)->save(); } //////////////////////////////////////////////////////////////////////////////// @@ -330,7 +342,7 @@ void _taglib_property_set(TagLib_File *file, const char* prop, const char* value if(file == NULL || prop == NULL) return; - auto tfile = reinterpret_cast(file); + auto tfile = reinterpret_cast(file); PropertyMap map = tfile->tag()->properties(); if(value) { @@ -371,7 +383,7 @@ char** taglib_property_keys(TagLib_File *file) if(file == NULL) return NULL; - const PropertyMap map = reinterpret_cast(file)->properties(); + const PropertyMap map = reinterpret_cast(file)->properties(); if(map.isEmpty()) return NULL; @@ -391,7 +403,7 @@ char **taglib_property_get(TagLib_File *file, const char *prop) if(file == NULL || prop == NULL) return NULL; - const PropertyMap map = reinterpret_cast(file)->properties(); + const PropertyMap map = reinterpret_cast(file)->properties(); auto property = map.find(prop); if(property == map.end()) @@ -434,7 +446,7 @@ bool _taglib_complex_property_set( if(file == NULL || key == NULL) return false; - auto tfile = reinterpret_cast(file); + auto tfile = reinterpret_cast(file); if(value == NULL) { return tfile->setComplexProperties(key, {}); @@ -516,7 +528,7 @@ char** taglib_complex_property_keys(TagLib_File *file) return NULL; } - const StringList strs = reinterpret_cast(file)->complexPropertyKeys(); + const StringList strs = reinterpret_cast(file)->complexPropertyKeys(); if(strs.isEmpty()) { return NULL; } @@ -539,7 +551,7 @@ TagLib_Complex_Property_Attribute*** taglib_complex_property_get( return NULL; } - const auto variantMaps = reinterpret_cast(file)->complexProperties(key); + const auto variantMaps = reinterpret_cast(file)->complexProperties(key); if(variantMaps.isEmpty()) { return NULL; } diff --git a/taglib/fileref.cpp b/taglib/fileref.cpp index 195c69c9..a7e690b7 100644 --- a/taglib/fileref.cpp +++ b/taglib/fileref.cpp @@ -138,6 +138,14 @@ namespace file = new MPEG::File(stream, ID3v2::FrameFactory::instance(), readAudioProperties, audioPropertiesStyle); else if(ext == "OGG") file = new Ogg::Vorbis::File(stream, readAudioProperties, audioPropertiesStyle); + else if(ext == "OGA") { + /* .oga can be any audio in the Ogg container. First try FLAC, then Vorbis. */ + file = new Ogg::FLAC::File(stream, readAudioProperties, audioPropertiesStyle); + if(!file->isValid()) { + delete file; + file = new Ogg::Vorbis::File(stream, readAudioProperties, audioPropertiesStyle); + } + } else if(ext == "FLAC") file = new FLAC::File(stream, ID3v2::FrameFactory::instance(), readAudioProperties, audioPropertiesStyle); else if(ext == "MPC") @@ -236,80 +244,6 @@ namespace return nullptr; } - // Internal function that supports FileRef::create(). - // This looks redundant, but necessary in order not to change the previous - // behavior of FileRef::create(). - - File* createInternal(FileName fileName, bool readAudioProperties, - AudioProperties::ReadStyle audioPropertiesStyle) - { - if(auto file = detectByResolvers(fileName, readAudioProperties, audioPropertiesStyle)) - return file; - -#ifdef _WIN32 - const String s = fileName.toString(); -#else - const String s(fileName); -#endif - - String ext; - const int pos = s.rfind("."); - if(pos != -1) - ext = s.substr(pos + 1).upper(); - - if(ext.isEmpty()) - return nullptr; - - if(ext == "MP3") - return new MPEG::File(fileName, ID3v2::FrameFactory::instance(), readAudioProperties, audioPropertiesStyle); - if(ext == "OGG") - return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "OGA") { - /* .oga can be any audio in the Ogg container. First try FLAC, then Vorbis. */ - auto file = new Ogg::FLAC::File(fileName, readAudioProperties, audioPropertiesStyle); - if(file->isValid()) - return file; - delete file; - return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle); - } - if(ext == "FLAC") - return new FLAC::File(fileName, ID3v2::FrameFactory::instance(), readAudioProperties, audioPropertiesStyle); - if(ext == "MPC") - return new MPC::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "WV") - return new WavPack::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "SPX") - return new Ogg::Speex::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "OPUS") - return new Ogg::Opus::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "TTA") - return new TrueAudio::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "M4A" || ext == "M4R" || ext == "M4B" || ext == "M4P" || ext == "MP4" || ext == "3G2" || ext == "M4V") - return new MP4::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "WMA" || ext == "ASF") - return new ASF::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "AIF" || ext == "AIFF" || ext == "AFC" || ext == "AIFC") - return new RIFF::AIFF::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "WAV") - return new RIFF::WAV::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "APE") - return new APE::File(fileName, readAudioProperties, audioPropertiesStyle); - // module, nst and wow are possible but uncommon extensions - if(ext == "MOD" || ext == "MODULE" || ext == "NST" || ext == "WOW") - return new Mod::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "S3M") - return new S3M::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "IT") - return new IT::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "XM") - return new XM::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "DSF") - return new DSF::File(fileName, readAudioProperties, audioPropertiesStyle); - if(ext == "DFF" || ext == "DSDIFF") - return new DSDIFF::File(fileName, readAudioProperties, audioPropertiesStyle); - - return nullptr; - } } // namespace class FileRef::FileRefPrivate @@ -529,12 +463,6 @@ bool FileRef::operator!=(const FileRef &ref) const return (ref.d->file != d->file); } -File *FileRef::create(FileName fileName, bool readAudioProperties, - AudioProperties::ReadStyle audioPropertiesStyle) // static -{ - return createInternal(fileName, readAudioProperties, audioPropertiesStyle); -} - //////////////////////////////////////////////////////////////////////////////// // private members //////////////////////////////////////////////////////////////////////////////// diff --git a/taglib/fileref.h b/taglib/fileref.h index 08c48272..316555f6 100644 --- a/taglib/fileref.h +++ b/taglib/fileref.h @@ -63,7 +63,7 @@ namespace TagLib { //! A class for pluggable file type resolution. /*! - * This class is used to add extend TagLib's very basic file name based file + * This class is used to extend TagLib's very basic file name based file * type resolution. * * This can be accomplished with: @@ -104,7 +104,7 @@ namespace TagLib { /*! * This method must be overridden 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. + * return a valid File object; if not it should return nullptr. * * \note The created file is then owned by the FileRef and should not be * deleted. Deletion will happen automatically when the FileRef passes @@ -374,22 +374,6 @@ namespace TagLib { */ bool operator!=(const FileRef &ref) const; - /*! - * A simple implementation of file type guessing. If \a readAudioProperties - * is true then the audio properties will be read using - * \a audioPropertiesStyle. If \a readAudioProperties is false then - * \a audioPropertiesStyle will be ignored. - * - * \note You generally shouldn't use this method, but instead the constructor - * directly. - * - * \deprecated Use FileRef(FileName, bool, AudioProperties::ReadStyle). - */ - // Kept because it is used for the C bindings - static File *create(FileName fileName, - bool readAudioProperties = true, - AudioProperties::ReadStyle audioPropertiesStyle = AudioProperties::Average); - private: void parse(FileName fileName, bool readAudioProperties, AudioProperties::ReadStyle audioPropertiesStyle); void parse(IOStream *stream, bool readAudioProperties, AudioProperties::ReadStyle audioPropertiesStyle); diff --git a/tests/test_fileref.cpp b/tests/test_fileref.cpp index 024ea1a4..2220a4ed 100644 --- a/tests/test_fileref.cpp +++ b/tests/test_fileref.cpp @@ -104,7 +104,6 @@ class TestFileRef : public CppUnit::TestFixture CPPUNIT_TEST(testDSF); CPPUNIT_TEST(testDSDIFF); CPPUNIT_TEST(testUnsupported); - CPPUNIT_TEST(testCreate); CPPUNIT_TEST(testAudioProperties); CPPUNIT_TEST(testDefaultFileExtensions); CPPUNIT_TEST(testFileResolver); @@ -354,23 +353,6 @@ public: CPPUNIT_ASSERT(f2.isNull()); } - void testCreate() - { - // This is deprecated. But worth it to test. - - File *f = FileRef::create(TEST_FILE_PATH_C("empty_vorbis.oga")); - CPPUNIT_ASSERT(dynamic_cast(f)); - delete f; - - f = FileRef::create(TEST_FILE_PATH_C("xing.mp3")); - CPPUNIT_ASSERT(dynamic_cast(f)); - delete f; - - f = FileRef::create(TEST_FILE_PATH_C("test.xm")); - CPPUNIT_ASSERT(dynamic_cast(f)); - delete f; - } - void testAudioProperties() { FileRef f(TEST_FILE_PATH_C("xing.mp3"));