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:
		| @@ -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; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann