mirror of https://github.com/xiph/flac
add more convenience for manipulating vorbis comments
This commit is contained in:
parent
725829176f
commit
45bb9887e1
|
@ -903,7 +903,9 @@ FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__Metadata_It
|
|||
|
||||
/** Create a new metadata object instance of the given type.
|
||||
*
|
||||
* The object will be "empty"; i.e. values and data pointers will be \c 0.
|
||||
* The object will be "empty"; i.e. values and data pointers will be \c 0,
|
||||
* with the exception of FLAC__METADATA_TYPE_VORBIS_COMMENT, which will have
|
||||
* the vendor string set (but zero comments).
|
||||
*
|
||||
* \param type Type of object to create
|
||||
* \retval FLAC__StreamMetadata*
|
||||
|
@ -1229,6 +1231,69 @@ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_insert_comment(FLAC__Str
|
|||
*/
|
||||
FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_delete_comment(FLAC__StreamMetadata *object, unsigned comment_num);
|
||||
|
||||
/*@@@@ needs unit test still */
|
||||
/** Check if the given Vorbis comment entry's field name matches the given
|
||||
* field name.
|
||||
*
|
||||
* \param entry A pointer to an existing Vorbis comment entry.
|
||||
* \param field_name The field name to check.
|
||||
* \param field_name_length The length of \a field_name, not including the
|
||||
* terminating \c NULL.
|
||||
* \assert
|
||||
* \code entry != NULL \endcode
|
||||
* \code (entry->entry != NULL && entry->length > 0)
|
||||
* \retval FLAC__bool
|
||||
* \c true if the field names match, else \c false
|
||||
*/
|
||||
FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_matches(const FLAC__StreamMetadata_VorbisComment_Entry *entry, const char *field_name, unsigned field_name_length);
|
||||
|
||||
/*@@@@ needs unit test still */
|
||||
/** Find a Vorbis comment with the given field name.
|
||||
*
|
||||
* The search begins at entry number \a offset; use and offset of 0 to
|
||||
* search from the beginning of the comment array.
|
||||
*
|
||||
* \param object A pointer to an existing VORBIS_COMMENT object.
|
||||
* \param offset The offset into the comment array from where to start
|
||||
* the search.
|
||||
* \param field_name The field name of the comment to find.
|
||||
* \assert
|
||||
* \code object != NULL \endcode
|
||||
* \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
|
||||
* \retval int
|
||||
* The offset in the comment array of the first comment whose field
|
||||
* name matches \a field_name, or \c -1 if no match was found.
|
||||
*/
|
||||
FLAC_API int FLAC__metadata_object_vorbiscomment_find_entry_from(FLAC__StreamMetadata *object, unsigned offset, const char *field_name);
|
||||
|
||||
/*@@@@ needs unit test still */
|
||||
/** Remove first Vorbis comment matching the given field name.
|
||||
*
|
||||
* \param object A pointer to an existing VORBIS_COMMENT object.
|
||||
* \param field_name The field name of comment to delete.
|
||||
* \assert
|
||||
* \code object != NULL \endcode
|
||||
* \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
|
||||
* \retval int
|
||||
* \c -1 for memory allocation error, \c 0 for no matching entries,
|
||||
* \c 1 for one matching entry deleted.
|
||||
*/
|
||||
FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entry_matching(FLAC__StreamMetadata *object, const char *field_name);
|
||||
|
||||
/*@@@@ needs unit test still */
|
||||
/** Remove all Vorbis comments matching the given field name.
|
||||
*
|
||||
* \param object A pointer to an existing VORBIS_COMMENT object.
|
||||
* \param field_name The field name of comments to delete.
|
||||
* \assert
|
||||
* \code object != NULL \endcode
|
||||
* \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode
|
||||
* \retval int
|
||||
* \c -1 for memory allocation error, \c 0 for no matching entries,
|
||||
* else the number of matching entries deleted.
|
||||
*/
|
||||
FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entries_matching(FLAC__StreamMetadata *object, const char *field_name);
|
||||
|
||||
/* \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -213,7 +213,18 @@ FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_new(FLAC__MetadataType type
|
|||
case FLAC__METADATA_TYPE_SEEKTABLE:
|
||||
break;
|
||||
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
|
||||
object->length = (FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN + FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN) / 8;
|
||||
{
|
||||
object->data.vorbis_comment.vendor_string.length = (unsigned)strlen(FLAC__VENDOR_STRING);
|
||||
if(!copy_bytes_(&object->data.vorbis_comment.vendor_string.entry, (const FLAC__byte*)FLAC__VENDOR_STRING, object->data.vorbis_comment.vendor_string.length)) {
|
||||
free(object);
|
||||
return 0;
|
||||
}
|
||||
object->length =
|
||||
(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN/8) +
|
||||
object->data.vorbis_comment.vendor_string.length +
|
||||
(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN/8)
|
||||
;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* double protection: */
|
||||
|
@ -257,6 +268,8 @@ FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMet
|
|||
}
|
||||
break;
|
||||
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
|
||||
if(0 != to->data.vorbis_comment.vendor_string.entry)
|
||||
free(to->data.vorbis_comment.vendor_string.entry);
|
||||
if(!copy_vcentry_(&to->data.vorbis_comment.vendor_string, &object->data.vorbis_comment.vendor_string)) {
|
||||
FLAC__metadata_object_delete(to);
|
||||
return 0;
|
||||
|
@ -751,3 +764,72 @@ FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_delete_comment(FLAC__Str
|
|||
|
||||
return FLAC__metadata_object_vorbiscomment_resize_comments(object, vc->num_comments-1);
|
||||
}
|
||||
|
||||
FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_matches(const FLAC__StreamMetadata_VorbisComment_Entry *entry, const char *field_name, unsigned field_name_length)
|
||||
{
|
||||
const FLAC__byte *eq = memchr(entry->entry, '=', entry->length);
|
||||
#if defined _MSC_VER || defined __MINGW32__
|
||||
#define FLAC__STRNCASECMP strnicmp
|
||||
#else
|
||||
#define FLAC__STRNCASECMP strncasecmp
|
||||
#endif
|
||||
return (0 != eq && (unsigned)(eq-entry->entry) == field_name_length && 0 == FLAC__STRNCASECMP(field_name, entry->entry, field_name_length));
|
||||
#undef FLAC__STRNCASECMP
|
||||
}
|
||||
|
||||
FLAC_API int FLAC__metadata_object_vorbiscomment_find_entry_from(FLAC__StreamMetadata *object, unsigned offset, const char *field_name)
|
||||
{
|
||||
const unsigned field_name_length = strlen(field_name);
|
||||
unsigned i;
|
||||
|
||||
FLAC__ASSERT(0 != object);
|
||||
FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||
|
||||
for(i = offset; i < object->data.vorbis_comment.num_comments; i++) {
|
||||
if(FLAC__metadata_object_vorbiscomment_entry_matches(object->data.vorbis_comment.comments + i, field_name, field_name_length))
|
||||
return (int)i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entry_matching(FLAC__StreamMetadata *object, const char *field_name)
|
||||
{
|
||||
const unsigned field_name_length = strlen(field_name);
|
||||
unsigned i;
|
||||
|
||||
FLAC__ASSERT(0 != object);
|
||||
FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||
|
||||
for(i = 0; i < object->data.vorbis_comment.num_comments; i++) {
|
||||
if(FLAC__metadata_object_vorbiscomment_entry_matches(object->data.vorbis_comment.comments + i, field_name, field_name_length)) {
|
||||
if(!FLAC__metadata_object_vorbiscomment_delete_comment(object, i))
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entries_matching(FLAC__StreamMetadata *object, const char *field_name)
|
||||
{
|
||||
FLAC__bool ok = true;
|
||||
unsigned matching = 0;
|
||||
const unsigned field_name_length = strlen(field_name);
|
||||
int i;
|
||||
|
||||
FLAC__ASSERT(0 != object);
|
||||
FLAC__ASSERT(object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT);
|
||||
|
||||
/* must delete from end to start otherwise it will interfere with our iteration */
|
||||
for(i = (int)object->data.vorbis_comment.num_comments - 1; ok && i >= 0; i--) {
|
||||
if(FLAC__metadata_object_vorbiscomment_entry_matches(object->data.vorbis_comment.comments + i, field_name, field_name_length)) {
|
||||
matching++;
|
||||
ok &= FLAC__metadata_object_vorbiscomment_delete_comment(object, (unsigned)i);
|
||||
}
|
||||
}
|
||||
|
||||
return ok? (int)matching : -1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue