bsdconv_malloc(size_t size)1 void *bsdconv_malloc(size_t size){
2 return malloc(size);
3 }
4
bsdconv_free(void * p)5 void bsdconv_free(void *p){
6 free(p);
7 }
8
bsdconv_mkstemp(char * template)9 int bsdconv_mkstemp(char *template){
10 return mkstemp(template);
11 }
12
getCodecDir()13 char * getCodecDir(){
14 char *c;
15 char *b;
16 if((c=getenv("BSDCONV_PATH"))==NULL){
17 c=BSDCONV_PATH;
18 }
19 b=malloc(strlen(c)+strlen(MODULES_SUBPATH)+2);
20 sprintf(b, "%s/%s", c, MODULES_SUBPATH);
21 return b;
22 }
23
str2datum(const char * s,struct data_rt * d)24 int str2datum(const char *s, struct data_rt *d){
25 d->data=NULL;
26 d->len=0;
27 if(!s)
28 return EINVAL;
29 d->data=malloc(strlen(s)/2);
30 d->flags=F_FREE;
31 d->next=NULL;
32 char f=0;
33 while(*s){
34 if(hex[(unsigned char) *s]<0){
35 free(d->data);
36 d->data=NULL;
37 return EINVAL;
38 }
39 switch(f){
40 case 0:
41 f=1;
42 UCP(d->data)[d->len]=hex[(unsigned char)*s];
43 break;
44 case 1:
45 f=0;
46 UCP(d->data)[d->len]*=16;
47 UCP(d->data)[d->len]+=hex[(unsigned char)*s];
48 d->len+=1;
49 break;
50 }
51 s+=1;
52 }
53 return 0;
54 }
55
str2data(const char * _s,int * r,struct bsdconv_instance * ins)56 struct data_rt * str2data(const char *_s, int *r, struct bsdconv_instance *ins){
57 struct data_rt ph;
58 struct data_rt *t=&ph;
59 char *k, *cur;
60 char *s;
61 char f;
62
63 ph.next=NULL;
64 if(!_s){
65 *r=EINVAL;
66 return NULL;
67 }
68 if(!*_s){
69 *r=0;
70 return NULL;
71 }
72
73 s=strdup(_s);
74
75 cur=s;
76 while((k=strsep(&cur, "."))!=NULL){
77 t->next=malloc(sizeof(struct data_rt));
78 t=t->next;
79 t->next=NULL;
80 t->len=0;
81 t->flags=F_FREE;
82 t->data=malloc(strlen(k)/2);
83 f=0;
84 while(*k){
85 if(hex[(unsigned char) *k]<0){
86 DATA_FREE(ins, ph.next);
87 *r=EINVAL;
88 free(s);
89 return NULL;
90 }
91 switch(f){
92 case 0:
93 f=1;
94 UCP(t->data)[t->len]=hex[(unsigned char)*k];
95 break;
96 case 1:
97 f=0;
98 UCP(t->data)[t->len]*=16;
99 UCP(t->data)[t->len]+=hex[(unsigned char)*k];
100 t->len+=1;
101 break;
102 }
103 k+=1;
104 }
105 }
106
107 free(s);
108
109 *r=0;
110 return ph.next;
111 }
112
bsdconv_get_phase_index(struct bsdconv_instance * ins,int phasen)113 int bsdconv_get_phase_index(struct bsdconv_instance *ins, int phasen){
114 /*
115 * phase[0] is a place holder for _INPUT
116 * real phases range is [1,len]=[1,phasen]
117 */
118 /* logical new index = len */
119 if(phasen /* logical */ >= ins->phasen /* len */){
120 /* real = logical + 1 */
121 return ins->phasen + 1;
122 }else{
123 /* real = (n + len) % (len) + 1*/
124 return (phasen + ins->phasen) % (ins->phasen) + 1;
125 }
126 }
127
bsdconv_get_codec_index(struct bsdconv_instance * ins,int phasen,int codecn)128 int bsdconv_get_codec_index(struct bsdconv_instance *ins, int phasen, int codecn){
129 /*
130 * codecn is -=1 for convenient use as boundary
131 * real phases range is [0,len)=[0,codecn]
132 */
133 phasen=bsdconv_get_phase_index(ins, phasen);
134
135 /* logical new index = len */
136 if(codecn /* logical */ >= ins->phase[phasen].codecn+1 /* len */ ){
137 /* real = logical */
138 return ins->phase[phasen].codecn+1;
139 }else{
140 /* real = (n + len) % (len) */
141 return (codecn + ins->phase[phasen].codecn+1) % (ins->phase[phasen].codecn+1);
142 }
143 }
144
bsdconv_insert_phase(const char * conversion,const char * codec,int phase_type,int ophasen)145 char * bsdconv_insert_phase(const char *conversion, const char *codec, int phase_type, int ophasen){
146 struct bsdconv_instance *ins;
147 int i,j;
148 char *ret;
149
150 ins=bsdconv_unpack(conversion);
151 if(!ins){
152 return NULL;
153 }
154
155 int phasen=bsdconv_get_phase_index(ins, ophasen);
156
157 ins->phasen+=1;
158 ins->phase=realloc(ins->phase, sizeof(struct bsdconv_phase) * (ins->phasen+1));
159
160 for(i=ins->phasen /* shifted index */;i>phasen;--i){
161 ins->phase[i]=ins->phase[i-1];
162 }
163 ins->phase[phasen].type=phase_type;
164 ins->phase[phasen].codec=malloc(sizeof(struct bsdconv_codec));
165 ins->phase[phasen].codecn=0 /* trimmed length */;
166
167 ins->phase[phasen].codec[0].desc=strdup(codec);
168 ins->phase[phasen].codec[0].argv=NULL;
169
170 ret=bsdconv_pack(ins);
171
172 for(i=1;i<=ins->phasen;++i){
173 for(j=0;j<=ins->phase[i].codecn;++j){
174 free(ins->phase[i].codec[j].desc);
175 }
176 free(ins->phase[i].codec);
177 }
178 free(ins->phase);
179 free(ins);
180
181 return ret;
182 }
183
bsdconv_insert_codec(const char * conversion,const char * codec,int ophasen,int ocodecn)184 char * bsdconv_insert_codec(const char *conversion, const char *codec, int ophasen, int ocodecn){
185 struct bsdconv_instance *ins;
186 int i,j;
187 char *ret;
188
189 ins=bsdconv_unpack(conversion);
190 if(!ins){
191 return NULL;
192 }
193
194 int phasen=bsdconv_get_phase_index(ins, ophasen);
195 int codecn=bsdconv_get_codec_index(ins, ophasen, ocodecn);
196
197 ++ins->phase[phasen].codecn;
198 ins->phase[phasen].codec=realloc(ins->phase[phasen].codec, sizeof(struct bsdconv_codec)*(ins->phase[phasen].codecn+1));
199
200 for(i=ins->phase[phasen].codecn;i>codecn;--i){
201 ins->phase[phasen].codec[i]=ins->phase[phasen].codec[i-1];
202 }
203 ins->phase[phasen].codec[codecn].desc=strdup(codec);
204 ins->phase[phasen].codec[codecn].argv=NULL;
205
206 ret=bsdconv_pack(ins);
207
208 for(i=1;i<=ins->phasen;++i){
209 for(j=0;j<=ins->phase[i].codecn;++j){
210 free(ins->phase[i].codec[j].desc);
211 }
212 free(ins->phase[i].codec);
213 }
214 free(ins->phase);
215 free(ins);
216
217 return ret;
218 }
219
bsdconv_replace_phase(const char * conversion,const char * codec,int phase_type,int ophasen)220 char * bsdconv_replace_phase(const char *conversion, const char *codec, int phase_type, int ophasen){
221 struct bsdconv_instance *ins;
222 int i,j;
223 char *ret;
224
225 ins=bsdconv_unpack(conversion);
226 if(!ins){
227 return NULL;
228 }
229
230 int phasen=bsdconv_get_phase_index(ins, ophasen);
231
232 for(j=0;j<=ins->phase[phasen].codecn;++j){
233 free(ins->phase[phasen].codec[j].desc);
234 }
235
236 ins->phase[phasen].type=phase_type;
237 ins->phase[phasen].codecn=0 /* trimmed length */;
238 ins->phase[phasen].codec[0].desc=strdup(codec);
239 ins->phase[phasen].codec[0].argv=NULL;
240
241 ret=bsdconv_pack(ins);
242
243 for(i=1;i<=ins->phasen;++i){
244 for(j=0;j<=ins->phase[i].codecn;++j){
245 free(ins->phase[i].codec[j].desc);
246 }
247 free(ins->phase[i].codec);
248 }
249 free(ins->phase);
250 free(ins);
251
252 return ret;
253 }
254
bsdconv_replace_codec(const char * conversion,const char * codec,int ophasen,int ocodecn)255 char * bsdconv_replace_codec(const char *conversion, const char *codec, int ophasen, int ocodecn){
256 struct bsdconv_instance *ins;
257 int i,j;
258 char *ret;
259
260 ins=bsdconv_unpack(conversion);
261 if(!ins){
262 return NULL;
263 }
264
265 int phasen=bsdconv_get_phase_index(ins, ophasen);
266 int codecn=bsdconv_get_codec_index(ins, ophasen, ocodecn);
267
268 free(ins->phase[phasen].codec[codecn].desc);
269 ins->phase[phasen].codec[codecn].desc=strdup(codec);
270 ins->phase[phasen].codec[codecn].argv=NULL;
271
272 ret=bsdconv_pack(ins);
273
274 for(i=1;i<=ins->phasen;++i){
275 for(j=0;j<=ins->phase[i].codecn;++j){
276 free(ins->phase[i].codec[j].desc);
277 }
278 free(ins->phase[i].codec);
279 }
280 free(ins->phase);
281 free(ins);
282
283 return ret;
284 }
285