flac: always allocate tag object
Free the tag object when it turns out to be empty. This simplifies several functions and APIs.
This commit is contained in:
parent
ccea365494
commit
f30adc3526
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <OggFLAC/seekable_stream_decoder.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user