ref: 046b089dfd1995bd97825c11d12a9755a039f931
parent: 0e4b81e15f2ccb8cf437f055e50d1a989237d3ec
author: Timothy B. Terriberry <tterribe@xiph.org>
date: Sat Aug 24 08:05:38 EDT 2013
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.
--- a/examples/opusfile_example.c
+++ b/examples/opusfile_example.c
@@ -93,24 +93,6 @@
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 @@
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);
--- a/include/opusfile.h
+++ b/include/opusfile.h
@@ -547,6 +547,32 @@
\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
--- a/src/info.c
+++ b/src/info.c
@@ -251,12 +251,17 @@
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){
char **user_comments;
int tag_len;
@@ -268,7 +273,7 @@
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 @@
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;
}