Commit 046b089d authored by Timothy B. Terriberry's avatar Timothy B. Terriberry
Browse files

Expose tag comparison functions.

It seems somewhat silly to have to write your own strcasecmp to
 satisfy the usage pattern found in opusfile_example: scanning the
 whole tags list and handling certain tags specially (as opposed to
 searching for specific tags, as opus_tags_query() does).
Given that we were already using an equivalent function internally
 to implement opus_tags_query, just expose it directly.
parent 0e4b81e1
......@@ -93,24 +93,6 @@ static void print_size(FILE *_fp,opus_int64 _nbytes,int _metric,
else fprintf(_fp,"%li%s%c",(long)val,_spacer,SUFFIXES[shift]);
}
/*A version of strncasecmp() that is guaranteed to only ignore the case of
ASCII characters.*/
static int local_strncasecmp(const char *_a,const char *_b,int _n){
int i;
for(i=0;i<_n;i++){
int a;
int b;
int d;
a=_a[i];
b=_b[i];
if(a>='a'&&a<='z')a-='a'-'A';
if(b>='a'&&b<='z')b-='a'-'A';
d=a-b;
if(d)return d;
}
return 0;
}
static void put_le32(unsigned char *_dst,opus_uint32 _x){
_dst[0]=(unsigned char)(_x&0xFF);
_dst[1]=(unsigned char)(_x>>8&0xFF);
......@@ -304,7 +286,7 @@ int main(int _argc,const char **_argv){
for(ci=0;ci<tags->comments;ci++){
const char *comment;
comment=tags->user_comments[ci];
if(local_strncasecmp(comment,"METADATA_BLOCK_PICTURE=",23)==0){
if(opus_tagncompare("METADATA_BLOCK_PICTURE",22,comment)==0){
OpusPictureTag pic;
int err;
err=opus_picture_tag_parse(&pic,comment);
......
......@@ -547,6 +547,32 @@ int opus_tags_get_track_gain(const OpusTags *_tags,int *_gain_q8)
\param _tags The #OpusTags structure to clear.*/
void opus_tags_clear(OpusTags *_tags) OP_ARG_NONNULL(1);
/**Check if \a _comment is an instance of a \a _tag_name tag.
\see opus_tagncompare
\param _tag_name A NUL-terminated, case-insensitive, ASCII string containing
the name of the tag to check for (without the terminating
'=' character).
\param _comment The comment string to check.
\return An integer less than, equal to, or greater than zero if \a _comment
is found respectively, to be less than, to match, or be greater
than a "tag=value" string whose tag matches \a _tag_name.*/
int opus_tagcompare(const char *_tag_name,const char *_comment);
/**Check if \a _comment is an instance of a \a _tag_name tag.
This version is slightly more efficient than opus_tagcompare() if the length
of the tag name is already known (e.g., because it is a constant).
\see opus_tagcompare
\param _tag_name A case-insensitive ASCII string containing the name of the
tag to check for (without the terminating '=' character).
\param _tag_len The number of characters in the tag name.
This must be non-negative.
\param _comment The comment string to check.
\return An integer less than, equal to, or greater than zero if \a _comment
is found respectively, to be less than, to match, or be greater
than a "tag=value" string whose tag matches the first \a _tag_len
characters of \a _tag_name.*/
int opus_tagncompare(const char *_tag_name,int _tag_len,const char *_comment);
/**Parse a single METADATA_BLOCK_PICTURE tag.
This decodes the BASE64-encoded content of the tag and returns a structure
with the MIME type, description, image parameters (if known), and the
......
......@@ -251,10 +251,15 @@ int opus_tags_add_comment(OpusTags *_tags,const char *_comment){
return 0;
}
/*Is _a a "tag=value" comment whose tag matches _b?
0 if it is, a non-zero value otherwise.*/
static int op_tagcompare(const char *_a,const char *_b,int _n){
return op_strncasecmp(_a,_b,_n)||_a[_n]!='=';
int opus_tagcompare(const char *_tag_name,const char *_comment){
return opus_tagncompare(_tag_name,strlen(_tag_name),_comment);
}
int opus_tagncompare(const char *_tag_name,int _tag_len,const char *_comment){
int ret;
OP_ASSERT(_tag_len>=0);
ret=op_strncasecmp(_tag_name,_comment,_tag_len);
return ret?ret:'='-_comment[_tag_len];
}
const char *opus_tags_query(const OpusTags *_tags,const char *_tag,int _count){
......@@ -268,7 +273,7 @@ const char *opus_tags_query(const OpusTags *_tags,const char *_tag,int _count){
user_comments=_tags->user_comments;
found=0;
for(ci=0;ci<ncomments;ci++){
if(!op_tagcompare(user_comments[ci],_tag,tag_len)){
if(!opus_tagncompare(_tag,tag_len,user_comments[ci])){
/*We return a pointer to the data, not a copy.*/
if(_count==found++)return user_comments[ci]+tag_len+1;
}
......@@ -288,7 +293,7 @@ int opus_tags_query_count(const OpusTags *_tags,const char *_tag){
user_comments=_tags->user_comments;
found=0;
for(ci=0;ci<ncomments;ci++){
if(!op_tagcompare(user_comments[ci],_tag,tag_len))found++;
if(!opus_tagncompare(_tag,tag_len,user_comments[ci]))found++;
}
return found;
}
......
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