diff --git a/src/decoder/FLACDecoderPlugin.cxx b/src/decoder/FLACDecoderPlugin.cxx index d541e6990..5de0ccef3 100644 --- a/src/decoder/FLACDecoderPlugin.cxx +++ b/src/decoder/FLACDecoderPlugin.cxx @@ -366,27 +366,22 @@ static bool oggflac_scan_file(const char *file, const struct tag_handler *handler, void *handler_ctx) { - FLAC__Metadata_Iterator *it; - FLAC__StreamMetadata *block; - FLAC__Metadata_Chain *chain = FLAC__metadata_chain_new(); - - if (!(FLAC__metadata_chain_read_ogg(chain, file))) { - FLAC__metadata_chain_delete(chain); + FLACMetadataChain chain; + if (!chain.ReadOgg(file)) { + g_debug("Failed to read OggFLAC tags: %s", + chain.GetStatusString()); return false; } - it = FLAC__metadata_iterator_new(); - FLAC__metadata_iterator_init(it, chain); - + FLACMetadataIterator iterator(chain); do { - if (!(block = FLAC__metadata_iterator_get_block(it))) + FLAC__StreamMetadata *block = iterator.GetBlock(); + if (block == nullptr) break; flac_scan_metadata(block, handler, handler_ctx); - } while (FLAC__metadata_iterator_next(it)); - FLAC__metadata_iterator_delete(it); + } while (iterator.Next()); - FLAC__metadata_chain_delete(chain); return true; } diff --git a/src/decoder/FLACMetaData.hxx b/src/decoder/FLACMetaData.hxx index 6e8f0ef6e..d474def62 100644 --- a/src/decoder/FLACMetaData.hxx +++ b/src/decoder/FLACMetaData.hxx @@ -20,9 +20,71 @@ #ifndef MPD_FLAC_METADATA_H #define MPD_FLAC_METADATA_H +#include "gcc.h" + +#include + #include #include -#include + +class FLACMetadataChain { + FLAC__Metadata_Chain *chain; + +public: + FLACMetadataChain():chain(::FLAC__metadata_chain_new()) {} + + ~FLACMetadataChain() { + ::FLAC__metadata_chain_delete(chain); + } + + explicit operator FLAC__Metadata_Chain *() { + return chain; + } + + bool Read(const char *path) { + return ::FLAC__metadata_chain_read(chain, path); + } + + bool ReadOgg(const char *path) { + return ::FLAC__metadata_chain_read_ogg(chain, path); + } + + gcc_pure + FLAC__Metadata_ChainStatus GetStatus() const { + return ::FLAC__metadata_chain_status(chain); + } + + gcc_pure + const char *GetStatusString() const { + return FLAC__Metadata_ChainStatusString[GetStatus()]; + } +}; + +class FLACMetadataIterator { + FLAC__Metadata_Iterator *iterator; + +public: + FLACMetadataIterator():iterator(::FLAC__metadata_iterator_new()) {} + + FLACMetadataIterator(FLACMetadataChain &chain) + :iterator(::FLAC__metadata_iterator_new()) { + ::FLAC__metadata_iterator_init(iterator, + (FLAC__Metadata_Chain *)chain); + } + + ~FLACMetadataIterator() { + ::FLAC__metadata_iterator_delete(iterator); + } + + bool Next() { + return ::FLAC__metadata_iterator_next(iterator); + } + + gcc_pure + FLAC__StreamMetadata *GetBlock() { + return ::FLAC__metadata_iterator_get_block(iterator); + } +}; struct tag_handler; struct tag;