Commit f30adc35 authored by Max Kellermann's avatar Max Kellermann

flac: always allocate tag object

Free the tag object when it turns out to be empty. This simplifies several functions and APIs.
parent ccea3654
...@@ -99,10 +99,9 @@ static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber"; ...@@ -99,10 +99,9 @@ static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber";
static const char *VORBIS_COMMENT_DISC_KEY = "discnumber"; static const char *VORBIS_COMMENT_DISC_KEY = "discnumber";
static bool static bool
flac_copy_vorbis_comment(const flac_copy_vorbis_comment(struct tag *tag,
FLAC__StreamMetadata_VorbisComment_Entry * entry, const FLAC__StreamMetadata_VorbisComment_Entry *entry,
enum tag_type type, enum tag_type type)
struct tag ** tag)
{ {
const char *str; const char *str;
size_t slen; size_t slen;
...@@ -123,10 +122,7 @@ flac_copy_vorbis_comment(const ...@@ -123,10 +122,7 @@ flac_copy_vorbis_comment(const
if ((vlen > 0) && (0 == strncasecmp(str, (char *)entry->entry, slen)) if ((vlen > 0) && (0 == strncasecmp(str, (char *)entry->entry, slen))
&& (*(entry->entry + slen) == '=')) { && (*(entry->entry + slen) == '=')) {
if (!*tag) tag_add_item_n(tag, type,
*tag = tag_new();
tag_add_item_n(*tag, type,
(char *)(entry->entry + slen + 1), vlen); (char *)(entry->entry + slen + 1), vlen);
return true; return true;
...@@ -135,9 +131,9 @@ flac_copy_vorbis_comment(const ...@@ -135,9 +131,9 @@ flac_copy_vorbis_comment(const
return false; return false;
} }
struct tag * void
flac_vorbis_comments_to_tag(const FLAC__StreamMetadata * block, flac_vorbis_comments_to_tag(struct tag *tag,
struct tag * tag) const FLAC__StreamMetadata *block)
{ {
unsigned int i, j; unsigned int i, j;
FLAC__StreamMetadata_VorbisComment_Entry *comments; FLAC__StreamMetadata_VorbisComment_Entry *comments;
...@@ -146,13 +142,11 @@ flac_vorbis_comments_to_tag(const FLAC__StreamMetadata * block, ...@@ -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 (i = block->data.vorbis_comment.num_comments; i != 0; --i) {
for (j = TAG_NUM_OF_ITEM_TYPES; j--;) { 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; break;
} }
comments++; comments++;
} }
return tag;
} }
void flac_metadata_common_cb(const FLAC__StreamMetadata * block, void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
......
...@@ -166,9 +166,9 @@ void flac_error_common_cb(const char *plugin, ...@@ -166,9 +166,9 @@ void flac_error_common_cb(const char *plugin,
FLAC__StreamDecoderErrorStatus status, FLAC__StreamDecoderErrorStatus status,
struct flac_data *data); struct flac_data *data);
struct tag * void
flac_vorbis_comments_to_tag(const FLAC__StreamMetadata * block, flac_vorbis_comments_to_tag(struct tag *tag,
struct tag *tag); const FLAC__StreamMetadata *block);
FLAC__StreamDecoderWriteStatus FLAC__StreamDecoderWriteStatus
flac_common_write(struct flac_data *data, const FLAC__Frame * frame, flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
......
...@@ -225,7 +225,7 @@ flac_write_cb(const flac_decoder *dec, const FLAC__Frame *frame, ...@@ -225,7 +225,7 @@ flac_write_cb(const flac_decoder *dec, const FLAC__Frame *frame,
static struct tag * static struct tag *
flac_tag_load(const char *file) flac_tag_load(const char *file)
{ {
struct tag *ret = NULL; struct tag *tag;
FLAC__Metadata_SimpleIterator *it; FLAC__Metadata_SimpleIterator *it;
FLAC__StreamMetadata *block = NULL; FLAC__StreamMetadata *block = NULL;
...@@ -252,27 +252,31 @@ flac_tag_load(const char *file) ...@@ -252,27 +252,31 @@ flac_tag_load(const char *file)
g_debug("Reading '%s' metadata gave the following error: %s\n", g_debug("Reading '%s' metadata gave the following error: %s\n",
file, err); file, err);
FLAC__metadata_simple_iterator_delete(it); FLAC__metadata_simple_iterator_delete(it);
return ret; return NULL;
} }
tag = tag_new();
do { do {
block = FLAC__metadata_simple_iterator_get_block(it); block = FLAC__metadata_simple_iterator_get_block(it);
if (!block) if (!block)
break; break;
if (block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { 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) { } else if (block->type == FLAC__METADATA_TYPE_STREAMINFO) {
if (!ret) tag->time = ((float)block->data.stream_info.total_samples) /
ret = tag_new();
ret->time = ((float)block->data.stream_info.
total_samples) /
block->data.stream_info.sample_rate + 0.5; block->data.stream_info.sample_rate + 0.5;
} }
FLAC__metadata_object_delete(block); FLAC__metadata_object_delete(block);
} while (FLAC__metadata_simple_iterator_next(it)); } while (FLAC__metadata_simple_iterator_next(it));
FLAC__metadata_simple_iterator_delete(it); FLAC__metadata_simple_iterator_delete(it);
return ret;
if (!tag_is_defined(tag)) {
tag_free(tag);
tag = NULL;
}
return tag;
} }
static struct tag * static struct tag *
...@@ -419,20 +423,26 @@ oggflac_tag_dup(const char *file) ...@@ -419,20 +423,26 @@ oggflac_tag_dup(const char *file)
goto out; goto out;
it = FLAC__metadata_iterator_new(); it = FLAC__metadata_iterator_new();
FLAC__metadata_iterator_init(it, chain); FLAC__metadata_iterator_init(it, chain);
ret = tag_new();
do { do {
if (!(block = FLAC__metadata_iterator_get_block(it))) if (!(block = FLAC__metadata_iterator_get_block(it)))
break; break;
if (block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { 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) { } else if (block->type == FLAC__METADATA_TYPE_STREAMINFO) {
if (!ret)
ret = tag_new();
ret->time = ((float)block->data.stream_info. ret->time = ((float)block->data.stream_info.
total_samples) / total_samples) /
block->data.stream_info.sample_rate + 0.5; block->data.stream_info.sample_rate + 0.5;
} }
} while (FLAC__metadata_iterator_next(it)); } while (FLAC__metadata_iterator_next(it));
FLAC__metadata_iterator_delete(it); FLAC__metadata_iterator_delete(it);
if (!tag_is_defined(ret)) {
tag_free(ret);
ret = NULL;
}
out: out:
FLAC__metadata_chain_delete(chain); FLAC__metadata_chain_delete(chain);
return ret; return ret;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <glib.h> #include <glib.h>
#include <OggFLAC/seekable_stream_decoder.h> #include <OggFLAC/seekable_stream_decoder.h>
#include <assert.h>
#include <unistd.h> #include <unistd.h>
static void oggflac_cleanup(struct flac_data *data, static void oggflac_cleanup(struct flac_data *data,
...@@ -168,16 +169,16 @@ static void of_metadata_dup_cb(G_GNUC_UNUSED const OggFLAC__SeekableStreamDecode ...@@ -168,16 +169,16 @@ static void of_metadata_dup_cb(G_GNUC_UNUSED const OggFLAC__SeekableStreamDecode
{ {
struct flac_data *data = (struct flac_data *) vdata; struct flac_data *data = (struct flac_data *) vdata;
assert(data->tag != NULL);
switch (block->type) { switch (block->type) {
case FLAC__METADATA_TYPE_STREAMINFO: case FLAC__METADATA_TYPE_STREAMINFO:
if (!data->tag)
data->tag = tag_new();
data->tag->time = ((float)block->data.stream_info. data->tag->time = ((float)block->data.stream_info.
total_samples) / total_samples) /
block->data.stream_info.sample_rate + 0.5; block->data.stream_info.sample_rate + 0.5;
return; return;
case FLAC__METADATA_TYPE_VORBIS_COMMENT: case FLAC__METADATA_TYPE_VORBIS_COMMENT:
flac_vorbis_comments_to_tag(block, data->tag); flac_vorbis_comments_to_tag(data->tag, block);
default: default:
break; break;
} }
...@@ -271,6 +272,8 @@ oggflac_tag_dup(const char *file) ...@@ -271,6 +272,8 @@ oggflac_tag_dup(const char *file)
flac_data_init(&data, NULL, &input_stream); flac_data_init(&data, NULL, &input_stream);
data.tag = tag_new();
/* errors here won't matter, /* errors here won't matter,
* data.tag will be set or unset, that's all we care about */ * data.tag will be set or unset, that's all we care about */
decoder = full_decoder_init_and_read_metadata(&data, 1); decoder = full_decoder_init_and_read_metadata(&data, 1);
...@@ -278,6 +281,11 @@ oggflac_tag_dup(const char *file) ...@@ -278,6 +281,11 @@ oggflac_tag_dup(const char *file)
oggflac_cleanup(&data, decoder); oggflac_cleanup(&data, decoder);
input_stream_close(&input_stream); input_stream_close(&input_stream);
if (!tag_is_defined(data.tag)) {
tag_free(data.tag);
data.tag = NULL;
}
return data.tag; return data.tag;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment