|
1 /******************************************************************** |
|
2 * * |
|
3 * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * |
|
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * |
|
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * |
|
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * |
|
7 * * |
|
8 * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 * |
|
9 * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * |
|
10 * * |
|
11 ******************************************************************** |
|
12 |
|
13 function: |
|
14 last mod: $Id: info.c 16503 2009-08-22 18:14:02Z giles $ |
|
15 |
|
16 ********************************************************************/ |
|
17 |
|
18 #include <stdlib.h> |
|
19 #include <ctype.h> |
|
20 #include <string.h> |
|
21 #include "internal.h" |
|
22 |
|
23 |
|
24 |
|
25 /*This is more or less the same as strncasecmp, but that doesn't exist |
|
26 everywhere, and this is a fairly trivial function, so we include it. |
|
27 Note: We take advantage of the fact that we know _n is less than or equal to |
|
28 the length of at least one of the strings.*/ |
|
29 static int oc_tagcompare(const char *_s1,const char *_s2,int _n){ |
|
30 int c; |
|
31 for(c=0;c<_n;c++){ |
|
32 if(toupper(_s1[c])!=toupper(_s2[c]))return !0; |
|
33 } |
|
34 return _s1[c]!='='; |
|
35 } |
|
36 |
|
37 |
|
38 |
|
39 void th_info_init(th_info *_info){ |
|
40 memset(_info,0,sizeof(*_info)); |
|
41 _info->version_major=TH_VERSION_MAJOR; |
|
42 _info->version_minor=TH_VERSION_MINOR; |
|
43 _info->version_subminor=TH_VERSION_SUB; |
|
44 _info->keyframe_granule_shift=6; |
|
45 } |
|
46 |
|
47 void th_info_clear(th_info *_info){ |
|
48 memset(_info,0,sizeof(*_info)); |
|
49 } |
|
50 |
|
51 |
|
52 |
|
53 void th_comment_init(th_comment *_tc){ |
|
54 memset(_tc,0,sizeof(*_tc)); |
|
55 } |
|
56 |
|
57 void th_comment_add(th_comment *_tc,char *_comment){ |
|
58 char **user_comments; |
|
59 int *comment_lengths; |
|
60 int comment_len; |
|
61 user_comments=_ogg_realloc(_tc->user_comments, |
|
62 (_tc->comments+2)*sizeof(*_tc->user_comments)); |
|
63 if(user_comments==NULL)return; |
|
64 _tc->user_comments=user_comments; |
|
65 comment_lengths=_ogg_realloc(_tc->comment_lengths, |
|
66 (_tc->comments+2)*sizeof(*_tc->comment_lengths)); |
|
67 if(comment_lengths==NULL)return; |
|
68 _tc->comment_lengths=comment_lengths; |
|
69 comment_len=strlen(_comment); |
|
70 comment_lengths[_tc->comments]=comment_len; |
|
71 user_comments[_tc->comments]=_ogg_malloc(comment_len+1); |
|
72 if(user_comments[_tc->comments]==NULL)return; |
|
73 memcpy(_tc->user_comments[_tc->comments],_comment,comment_len+1); |
|
74 _tc->comments++; |
|
75 _tc->user_comments[_tc->comments]=NULL; |
|
76 } |
|
77 |
|
78 void th_comment_add_tag(th_comment *_tc,char *_tag,char *_val){ |
|
79 char *comment; |
|
80 int tag_len; |
|
81 int val_len; |
|
82 tag_len=strlen(_tag); |
|
83 val_len=strlen(_val); |
|
84 /*+2 for '=' and '\0'.*/ |
|
85 comment=_ogg_malloc(tag_len+val_len+2); |
|
86 if(comment==NULL)return; |
|
87 memcpy(comment,_tag,tag_len); |
|
88 comment[tag_len]='='; |
|
89 memcpy(comment+tag_len+1,_val,val_len+1); |
|
90 th_comment_add(_tc,comment); |
|
91 _ogg_free(comment); |
|
92 } |
|
93 |
|
94 char *th_comment_query(th_comment *_tc,char *_tag,int _count){ |
|
95 long i; |
|
96 int found; |
|
97 int tag_len; |
|
98 tag_len=strlen(_tag); |
|
99 found=0; |
|
100 for(i=0;i<_tc->comments;i++){ |
|
101 if(!oc_tagcompare(_tc->user_comments[i],_tag,tag_len)){ |
|
102 /*We return a pointer to the data, not a copy.*/ |
|
103 if(_count==found++)return _tc->user_comments[i]+tag_len+1; |
|
104 } |
|
105 } |
|
106 /*Didn't find anything.*/ |
|
107 return NULL; |
|
108 } |
|
109 |
|
110 int th_comment_query_count(th_comment *_tc,char *_tag){ |
|
111 long i; |
|
112 int tag_len; |
|
113 int count; |
|
114 tag_len=strlen(_tag); |
|
115 count=0; |
|
116 for(i=0;i<_tc->comments;i++){ |
|
117 if(!oc_tagcompare(_tc->user_comments[i],_tag,tag_len))count++; |
|
118 } |
|
119 return count; |
|
120 } |
|
121 |
|
122 void th_comment_clear(th_comment *_tc){ |
|
123 if(_tc!=NULL){ |
|
124 long i; |
|
125 for(i=0;i<_tc->comments;i++)_ogg_free(_tc->user_comments[i]); |
|
126 _ogg_free(_tc->user_comments); |
|
127 _ogg_free(_tc->comment_lengths); |
|
128 _ogg_free(_tc->vendor); |
|
129 memset(_tc,0,sizeof(*_tc)); |
|
130 } |
|
131 } |