From f30adc352627d5aaaa933340dee24308e5920f15 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 15 Jan 2009 22:43:39 +0100 Subject: flac: always allocate tag object Free the tag object when it turns out to be empty. This simplifies several functions and APIs. --- src/decoder/_flac_common.c | 22 ++++++++-------------- src/decoder/_flac_common.h | 6 +++--- src/decoder/flac_plugin.c | 32 +++++++++++++++++++++----------- src/decoder/oggflac_plugin.c | 14 +++++++++++--- 4 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/decoder/_flac_common.c b/src/decoder/_flac_common.c index ddce994de..2cf17ca40 100644 --- a/src/decoder/_flac_common.c +++ b/src/decoder/_flac_common.c @@ -99,10 +99,9 @@ static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber"; static const char *VORBIS_COMMENT_DISC_KEY = "discnumber"; static bool -flac_copy_vorbis_comment(const - FLAC__StreamMetadata_VorbisComment_Entry * entry, - enum tag_type type, - struct tag ** tag) +flac_copy_vorbis_comment(struct tag *tag, + const FLAC__StreamMetadata_VorbisComment_Entry *entry, + enum tag_type type) { const char *str; size_t slen; @@ -123,10 +122,7 @@ flac_copy_vorbis_comment(const if ((vlen > 0) && (0 == strncasecmp(str, (char *)entry->entry, slen)) && (*(entry->entry + slen) == '=')) { - if (!*tag) - *tag = tag_new(); - - tag_add_item_n(*tag, type, + tag_add_item_n(tag, type, (char *)(entry->entry + slen + 1), vlen); return true; @@ -135,9 +131,9 @@ flac_copy_vorbis_comment(const return false; } -struct tag * -flac_vorbis_comments_to_tag(const FLAC__StreamMetadata * block, - struct tag * tag) +void +flac_vorbis_comments_to_tag(struct tag *tag, + const FLAC__StreamMetadata *block) { unsigned int i, j; FLAC__StreamMetadata_VorbisComment_Entry *comments; @@ -146,13 +142,11 @@ flac_vorbis_comments_to_tag(const FLAC__StreamMetadata * block, for (i = block->data.vorbis_comment.num_comments; i != 0; --i) { for (j = TAG_NUM_OF_ITEM_TYPES; j--;) { - if (flac_copy_vorbis_comment(comments, j, &tag)) + if (flac_copy_vorbis_comment(tag, comments, j)) break; } comments++; } - - return tag; } void flac_metadata_common_cb(const FLAC__StreamMetadata * block, diff --git a/src/decoder/_flac_common.h b/src/decoder/_flac_common.h index 08b84c337..817f4ba5a 100644 --- a/src/decoder/_flac_common.h +++ b/src/decoder/_flac_common.h @@ -166,9 +166,9 @@ void flac_error_common_cb(const char *plugin, FLAC__StreamDecoderErrorStatus status, struct flac_data *data); -struct tag * -flac_vorbis_comments_to_tag(const FLAC__StreamMetadata * block, - struct tag *tag); +void +flac_vorbis_comments_to_tag(struct tag *tag, + const FLAC__StreamMetadata *block); FLAC__StreamDecoderWriteStatus flac_common_write(struct flac_data *data, const FLAC__Frame * frame, diff --git a/src/decoder/flac_plugin.c b/src/decoder/flac_plugin.c index edf268331..e02c13638 100644 --- a/src/decoder/flac_plugin.c +++ b/src/decoder/flac_plugin.c @@ -225,7 +225,7 @@ flac_write_cb(const flac_decoder *dec, const FLAC__Frame *frame, static struct tag * flac_tag_load(const char *file) { - struct tag *ret = NULL; + struct tag *tag; FLAC__Metadata_SimpleIterator *it; FLAC__StreamMetadata *block = NULL; @@ -252,27 +252,31 @@ flac_tag_load(const char *file) g_debug("Reading '%s' metadata gave the following error: %s\n", file, err); FLAC__metadata_simple_iterator_delete(it); - return ret; + return NULL; } + tag = tag_new(); do { block = FLAC__metadata_simple_iterator_get_block(it); if (!block) break; if (block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { - flac_vorbis_comments_to_tag(block, ret); + flac_vorbis_comments_to_tag(tag, block); } else if (block->type == FLAC__METADATA_TYPE_STREAMINFO) { - if (!ret) - ret = tag_new(); - ret->time = ((float)block->data.stream_info. - total_samples) / + tag->time = ((float)block->data.stream_info.total_samples) / block->data.stream_info.sample_rate + 0.5; } FLAC__metadata_object_delete(block); } while (FLAC__metadata_simple_iterator_next(it)); FLAC__metadata_simple_iterator_delete(it); - return ret; + + if (!tag_is_defined(tag)) { + tag_free(tag); + tag = NULL; + } + + return tag; } static struct tag * @@ -419,20 +423,26 @@ oggflac_tag_dup(const char *file) goto out; it = FLAC__metadata_iterator_new(); FLAC__metadata_iterator_init(it, chain); + + ret = tag_new(); do { if (!(block = FLAC__metadata_iterator_get_block(it))) break; if (block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { - ret = flac_vorbis_comments_to_tag(block, ret); + flac_vorbis_comments_to_tag(ret, block); } else if (block->type == FLAC__METADATA_TYPE_STREAMINFO) { - if (!ret) - ret = tag_new(); ret->time = ((float)block->data.stream_info. total_samples) / block->data.stream_info.sample_rate + 0.5; } } while (FLAC__metadata_iterator_next(it)); FLAC__metadata_iterator_delete(it); + + if (!tag_is_defined(ret)) { + tag_free(ret); + ret = NULL; + } + out: FLAC__metadata_chain_delete(chain); return ret; diff --git a/src/decoder/oggflac_plugin.c b/src/decoder/oggflac_plugin.c index 237f826d3..667f8b17e 100644 --- a/src/decoder/oggflac_plugin.c +++ b/src/decoder/oggflac_plugin.c @@ -24,6 +24,7 @@ #include #include +#include #include static void oggflac_cleanup(struct flac_data *data, @@ -168,16 +169,16 @@ static void of_metadata_dup_cb(G_GNUC_UNUSED const OggFLAC__SeekableStreamDecode { struct flac_data *data = (struct flac_data *) vdata; + assert(data->tag != NULL); + switch (block->type) { case FLAC__METADATA_TYPE_STREAMINFO: - if (!data->tag) - data->tag = tag_new(); data->tag->time = ((float)block->data.stream_info. total_samples) / block->data.stream_info.sample_rate + 0.5; return; case FLAC__METADATA_TYPE_VORBIS_COMMENT: - flac_vorbis_comments_to_tag(block, data->tag); + flac_vorbis_comments_to_tag(data->tag, block); default: break; } @@ -271,6 +272,8 @@ oggflac_tag_dup(const char *file) flac_data_init(&data, NULL, &input_stream); + data.tag = tag_new(); + /* errors here won't matter, * data.tag will be set or unset, that's all we care about */ decoder = full_decoder_init_and_read_metadata(&data, 1); @@ -278,6 +281,11 @@ oggflac_tag_dup(const char *file) oggflac_cleanup(&data, decoder); input_stream_close(&input_stream); + if (!tag_is_defined(data.tag)) { + tag_free(data.tag); + data.tag = NULL; + } + return data.tag; } -- cgit v1.2.3