Lines 45-65
Link Here
|
45 |
|
45 |
|
46 |
#define WHITES " \n\r\t" |
46 |
#define WHITES " \n\r\t" |
47 |
|
47 |
|
48 |
static void |
48 |
static char * |
49 |
strstrip(char* str) { |
49 |
strstrip(char* str) { |
50 |
char* i; |
50 |
char* i; |
51 |
|
51 |
|
52 |
if (str==NULL) |
52 |
if (str==NULL) |
53 |
return; |
53 |
return; |
54 |
for(i = str ; i[0] != '\0' && strchr(WHITES,i[0]) != NULL; i++) |
54 |
while (str[0] != '\0' && strchr(WHITES,str[0]) != NULL) |
|
|
55 |
++str; |
56 |
i = str + strlen(str); |
57 |
while (i-- != str && strchr(WHITES,i[0]) != NULL) |
55 |
/* NOTHING */; |
58 |
/* NOTHING */; |
56 |
if(i[0] != '\0') { |
59 |
i[1] = '\0'; |
57 |
memmove(str,i,strlen(i) + 1); |
60 |
return str; |
58 |
for(i = str + strlen(str) - 1 ; strchr(WHITES,i[0]) != NULL; i--) |
|
|
59 |
/* NOTHING */; |
60 |
i[1] = '\0'; |
61 |
} else |
62 |
str[0] = '\0'; |
63 |
} |
61 |
} |
64 |
|
62 |
|
65 |
static char* |
63 |
static char* |
Lines 138-143
Link Here
|
138 |
return p->line; |
136 |
return p->line; |
139 |
} |
137 |
} |
140 |
|
138 |
|
|
|
139 |
static char* |
140 |
play_tree_parser_get_stripped_line(play_tree_parser_t* p) { |
141 |
char *str; |
142 |
|
143 |
str = play_tree_parser_get_line(p); |
144 |
if (str) |
145 |
str = strstrip(str); |
146 |
return str; |
147 |
} |
148 |
|
141 |
static void |
149 |
static void |
142 |
play_tree_parser_reset(play_tree_parser_t* p) { |
150 |
play_tree_parser_reset(play_tree_parser_t* p) { |
143 |
p->iter = p->buffer; |
151 |
p->iter = p->buffer; |
Lines 165-174
Link Here
|
165 |
|
173 |
|
166 |
while(1) { |
174 |
while(1) { |
167 |
if(get_line) { |
175 |
if(get_line) { |
168 |
line = play_tree_parser_get_line(p); |
176 |
line = play_tree_parser_get_stripped_line(p); |
169 |
if(!line) |
177 |
if(!line) |
170 |
return NULL; |
178 |
return NULL; |
171 |
strstrip(line); |
|
|
172 |
if(line[0] == '\0') |
179 |
if(line[0] == '\0') |
173 |
continue; |
180 |
continue; |
174 |
} |
181 |
} |
Lines 231-270
Link Here
|
231 |
} |
238 |
} |
232 |
|
239 |
|
233 |
typedef struct pls_entry { |
240 |
typedef struct pls_entry { |
|
|
241 |
int number; |
234 |
char* file; |
242 |
char* file; |
235 |
char* title; |
243 |
char* title; |
236 |
char* length; |
244 |
char* length; |
237 |
} pls_entry_t; |
245 |
} pls_entry_t; |
238 |
|
246 |
|
239 |
static int |
247 |
static int |
240 |
pls_read_entry(char* line,pls_entry_t** _e,int* _max_entry,char** val) { |
248 |
pls_read_entry(char* line,pls_entry_t ** _e,int* _n_entries,const char *prefix,int prefix_len,char **val) |
241 |
int num,max_entry = (*_max_entry); |
249 |
{ |
|
|
250 |
int num,i,entries = (*_n_entries); |
242 |
pls_entry_t* e = (*_e); |
251 |
pls_entry_t* e = (*_e); |
243 |
char* v; |
252 |
char* v; |
244 |
|
253 |
|
|
|
254 |
if(strncasecmp(line,prefix,prefix_len) != 0) |
255 |
return -1; |
256 |
|
257 |
line += prefix_len; |
258 |
|
245 |
v = pls_entry_get_value(line); |
259 |
v = pls_entry_get_value(line); |
246 |
if(!v) { |
260 |
if(!v) { |
247 |
mp_msg(MSGT_PLAYTREE,MSGL_ERR,"No value in entry %s\n",line); |
261 |
mp_msg(MSGT_PLAYTREE,MSGL_ERR,"No value in entry %s\n",line); |
248 |
return 0; |
262 |
return 0; |
249 |
} |
263 |
} |
|
|
264 |
(*val) = v; |
250 |
|
265 |
|
251 |
num = atoi(line); |
266 |
num = atoi(line); |
252 |
if(num < 0) { |
267 |
if(num < 1 || num > entries || e[num-1].number != num) { |
253 |
num = max_entry+1; |
268 |
for(i = 0; i < entries; ++i) { |
254 |
mp_msg(MSGT_PLAYTREE,MSGL_WARN,"No entry index in entry %s\nAssuming %d\n",line,num); |
269 |
if (e[i].number == num) |
255 |
} |
270 |
break; |
256 |
if(num > max_entry) { |
271 |
} |
257 |
e = (pls_entry_t*)realloc(e,num*sizeof(pls_entry_t)); |
272 |
if (i == entries) { |
258 |
memset(&e[max_entry],0,(num-max_entry)*sizeof(pls_entry_t)); |
273 |
e = (pls_entry_t*)realloc(e,(++entries)*sizeof(pls_entry_t)); |
259 |
max_entry = num; |
274 |
memset(&e[i],0,sizeof(pls_entry_t)); |
|
|
275 |
e[i].number = num; |
276 |
(*_n_entries) = entries; |
277 |
(*_e) = e; |
278 |
} |
279 |
num = i+1; |
260 |
} |
280 |
} |
261 |
(*_e) = e; |
|
|
262 |
(*_max_entry) = max_entry; |
263 |
(*val) = v; |
264 |
|
281 |
|
265 |
return num; |
282 |
return num; |
266 |
} |
283 |
} |
267 |
|
284 |
|
|
|
285 |
static int |
286 |
cmp_entry_number(const void *a, const void *b) |
287 |
{ |
288 |
const pls_entry_t *pa = a, *pb = b; |
289 |
return (pa->number < pb->number) ? -1 : |
290 |
(pa->number > pb->number) ? 1 : 0; |
291 |
} |
268 |
|
292 |
|
269 |
static play_tree_t* |
293 |
static play_tree_t* |
270 |
parse_pls(play_tree_parser_t* p) { |
294 |
parse_pls(play_tree_parser_t* p) { |
Lines 274-282
Link Here
|
274 |
play_tree_t *list = NULL, *entry = NULL, *last_entry = NULL; |
298 |
play_tree_t *list = NULL, *entry = NULL, *last_entry = NULL; |
275 |
|
299 |
|
276 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying Winamp playlist...\n"); |
300 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying Winamp playlist...\n"); |
277 |
while((line = play_tree_parser_get_line(p))) { |
301 |
while((line = play_tree_parser_get_stripped_line(p))) { |
278 |
strstrip(line); |
302 |
if(line[0] != '\0') |
279 |
if(strlen(line)) |
|
|
280 |
break; |
303 |
break; |
281 |
} |
304 |
} |
282 |
if (!line) |
305 |
if (!line) |
Lines 285-336
Link Here
|
285 |
return NULL; |
308 |
return NULL; |
286 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected Winamp playlist format\n"); |
309 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected Winamp playlist format\n"); |
287 |
play_tree_parser_stop_keeping(p); |
310 |
play_tree_parser_stop_keeping(p); |
288 |
line = play_tree_parser_get_line(p); |
311 |
line = play_tree_parser_get_stripped_line(p); |
289 |
if(!line) |
312 |
if(!line) |
290 |
return NULL; |
313 |
return NULL; |
291 |
strstrip(line); |
|
|
292 |
if(strncasecmp(line,"NumberOfEntries",15) == 0) { |
314 |
if(strncasecmp(line,"NumberOfEntries",15) == 0) { |
293 |
v = pls_entry_get_value(line); |
315 |
v = pls_entry_get_value(line); |
294 |
n_entries = atoi(v); |
316 |
n_entries = atoi(v); |
295 |
if(n_entries < 0) |
317 |
if(n_entries <= 0 || n_entries > 100000) /* arbitrary big number */ |
296 |
mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Invalid number of entries: very funny!!!\n"); |
318 |
mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Invalid number of entries: very funny!!!\n"); |
297 |
else |
319 |
else |
298 |
mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Playlist claims to have %d entries. Let's see.\n",n_entries); |
320 |
mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Playlist claims to have %d entries. Let's see.\n",n_entries); |
299 |
line = play_tree_parser_get_line(p); |
321 |
line = play_tree_parser_get_stripped_line(p); |
300 |
} |
322 |
} |
301 |
|
323 |
|
302 |
while(line) { |
324 |
while(line) { |
303 |
strstrip(line); |
|
|
304 |
if(line[0] == '\0') { |
325 |
if(line[0] == '\0') { |
305 |
line = play_tree_parser_get_line(p); |
326 |
line = play_tree_parser_get_stripped_line(p); |
306 |
continue; |
327 |
continue; |
307 |
} |
328 |
} |
308 |
if(strncasecmp(line,"File",4) == 0) { |
329 |
if((num = pls_read_entry(line,&entries,&max_entry,"File",4,&v)) > 0) |
309 |
num = pls_read_entry(line+4,&entries,&max_entry,&v); |
330 |
entries[num-1].file = strdup(v); |
310 |
if(num < 0) |
331 |
else if (num < 0 && ((num = pls_read_entry(line,&entries,&max_entry,"Title",5,&v)) > 0)) |
311 |
mp_msg(MSGT_PLAYTREE,MSGL_ERR,"No value in entry %s\n",line); |
332 |
entries[num-1].title = strdup(v); |
312 |
else |
333 |
else if (num < 0 && ((num = pls_read_entry(line,&entries,&max_entry,"Length",6,&v)) > 0)) |
313 |
entries[num-1].file = strdup(v); |
334 |
entries[num-1].length = strdup(v); |
314 |
} else if(strncasecmp(line,"Title",5) == 0) { |
335 |
else if (num < 0) |
315 |
num = pls_read_entry(line+5,&entries,&max_entry,&v); |
|
|
316 |
if(num < 0) |
317 |
mp_msg(MSGT_PLAYTREE,MSGL_ERR,"No value in entry %s\n",line); |
318 |
else |
319 |
entries[num-1].title = strdup(v); |
320 |
} else if(strncasecmp(line,"Length",6) == 0) { |
321 |
num = pls_read_entry(line+6,&entries,&max_entry,&v); |
322 |
if(num < 0) |
323 |
mp_msg(MSGT_PLAYTREE,MSGL_ERR,"No value in entry %s\n",line); |
324 |
else |
325 |
entries[num-1].length = strdup(v); |
326 |
} else |
327 |
mp_msg(MSGT_PLAYTREE,MSGL_WARN,"Unknown entry type %s\n",line); |
336 |
mp_msg(MSGT_PLAYTREE,MSGL_WARN,"Unknown entry type %s\n",line); |
328 |
line = play_tree_parser_get_line(p); |
337 |
line = play_tree_parser_get_stripped_line(p); |
329 |
} |
338 |
} |
330 |
|
339 |
|
|
|
340 |
qsort(entries,max_entry,sizeof(*entries),cmp_entry_number); |
341 |
|
331 |
for(num = 0; num < max_entry ; num++) { |
342 |
for(num = 0; num < max_entry ; num++) { |
332 |
if(entries[num].file == NULL) |
343 |
if(entries[num].file == NULL) |
333 |
mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Entry %d don't have a file !!!!\n",num+1); |
344 |
mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Entry %d don't have a file !!!!\n",entries[num].number); |
334 |
else { |
345 |
else { |
335 |
mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding entry %s\n",entries[num].file); |
346 |
mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding entry %s\n",entries[num].file); |
336 |
entry = play_tree_new(); |
347 |
entry = play_tree_new(); |
Lines 368-385
Link Here
|
368 |
play_tree_t *list = NULL, *entry = NULL, *last_entry = NULL; |
379 |
play_tree_t *list = NULL, *entry = NULL, *last_entry = NULL; |
369 |
|
380 |
|
370 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying reference-ini playlist...\n"); |
381 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying reference-ini playlist...\n"); |
371 |
if (!(line = play_tree_parser_get_line(p))) |
382 |
if (!(line = play_tree_parser_get_stripped_line(p))) |
372 |
return NULL; |
383 |
return NULL; |
373 |
strstrip(line); |
|
|
374 |
if(strcasecmp(line,"[Reference]")) |
384 |
if(strcasecmp(line,"[Reference]")) |
375 |
return NULL; |
385 |
return NULL; |
376 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected reference-ini playlist format\n"); |
386 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected reference-ini playlist format\n"); |
377 |
play_tree_parser_stop_keeping(p); |
387 |
play_tree_parser_stop_keeping(p); |
378 |
line = play_tree_parser_get_line(p); |
388 |
line = play_tree_parser_get_stripped_line(p); |
379 |
if(!line) |
389 |
if(!line) |
380 |
return NULL; |
390 |
return NULL; |
381 |
while(line) { |
391 |
while(line) { |
382 |
strstrip(line); |
|
|
383 |
if(strncasecmp(line,"Ref",3) == 0) { |
392 |
if(strncasecmp(line,"Ref",3) == 0) { |
384 |
v = pls_entry_get_value(line+3); |
393 |
v = pls_entry_get_value(line+3); |
385 |
if(!v) |
394 |
if(!v) |
Lines 396-402
Link Here
|
396 |
last_entry = entry; |
405 |
last_entry = entry; |
397 |
} |
406 |
} |
398 |
} |
407 |
} |
399 |
line = play_tree_parser_get_line(p); |
408 |
line = play_tree_parser_get_stripped_line(p); |
400 |
} |
409 |
} |
401 |
|
410 |
|
402 |
if(!list) return NULL; |
411 |
if(!list) return NULL; |
Lines 411-426
Link Here
|
411 |
play_tree_t *list = NULL, *entry = NULL, *last_entry = NULL; |
420 |
play_tree_t *list = NULL, *entry = NULL, *last_entry = NULL; |
412 |
|
421 |
|
413 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying extended m3u playlist...\n"); |
422 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying extended m3u playlist...\n"); |
414 |
if (!(line = play_tree_parser_get_line(p))) |
423 |
if (!(line = play_tree_parser_get_stripped_line(p))) |
415 |
return NULL; |
424 |
return NULL; |
416 |
strstrip(line); |
|
|
417 |
if(strcasecmp(line,"#EXTM3U")) |
425 |
if(strcasecmp(line,"#EXTM3U")) |
418 |
return NULL; |
426 |
return NULL; |
419 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected extended m3u playlist format\n"); |
427 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected extended m3u playlist format\n"); |
420 |
play_tree_parser_stop_keeping(p); |
428 |
play_tree_parser_stop_keeping(p); |
421 |
|
429 |
|
422 |
while((line = play_tree_parser_get_line(p)) != NULL) { |
430 |
while((line = play_tree_parser_get_stripped_line(p)) != NULL) { |
423 |
strstrip(line); |
|
|
424 |
if(line[0] == '\0') |
431 |
if(line[0] == '\0') |
425 |
continue; |
432 |
continue; |
426 |
/* EXTM3U files contain such lines: |
433 |
/* EXTM3U files contain such lines: |
Lines 464-471
Link Here
|
464 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying smil playlist...\n"); |
471 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying smil playlist...\n"); |
465 |
|
472 |
|
466 |
// Check if smil |
473 |
// Check if smil |
467 |
while((line = play_tree_parser_get_line(p)) != NULL) { |
474 |
while((line = play_tree_parser_get_stripped_line(p)) != NULL) { |
468 |
strstrip(line); |
|
|
469 |
if(line[0] == '\0') // Ignore empties |
475 |
if(line[0] == '\0') // Ignore empties |
470 |
continue; |
476 |
continue; |
471 |
if (strncasecmp(line,"<?xml",5)==0) // smil in xml |
477 |
if (strncasecmp(line,"<?xml",5)==0) // smil in xml |
Lines 501-507
Link Here
|
501 |
src_line = line; |
507 |
src_line = line; |
502 |
line = NULL; |
508 |
line = NULL; |
503 |
do { |
509 |
do { |
504 |
strstrip(src_line); |
|
|
505 |
if (line) { |
510 |
if (line) { |
506 |
free(line); |
511 |
free(line); |
507 |
line = NULL; |
512 |
line = NULL; |
Lines 514-524
Link Here
|
514 |
char *payload; |
519 |
char *payload; |
515 |
|
520 |
|
516 |
line = strdup(src_line); |
521 |
line = strdup(src_line); |
517 |
if(!(src_line = play_tree_parser_get_line(p))) { |
522 |
if(!(src_line = play_tree_parser_get_stripped_line(p))) { |
518 |
mp_msg(MSGT_PLAYTREE,MSGL_WARN,"smil-over-realrtsp: can't get line from packet %u/%u.\n", npkt, ttlpkt); |
523 |
mp_msg(MSGT_PLAYTREE,MSGL_WARN,"smil-over-realrtsp: can't get line from packet %u/%u.\n", npkt, ttlpkt); |
519 |
break; |
524 |
break; |
520 |
} |
525 |
} |
521 |
strstrip(src_line); |
|
|
522 |
// Skip header, packet starts after " |
526 |
// Skip header, packet starts after " |
523 |
if(!(payload = strchr(src_line,'\"'))) { |
527 |
if(!(payload = strchr(src_line,'\"'))) { |
524 |
mp_msg(MSGT_PLAYTREE,MSGL_WARN,"smil-over-realrtsp: can't find start of packet, using complete line.\n"); |
528 |
mp_msg(MSGT_PLAYTREE,MSGL_WARN,"smil-over-realrtsp: can't find start of packet, using complete line.\n"); |
Lines 583-589
Link Here
|
583 |
} |
587 |
} |
584 |
} |
588 |
} |
585 |
} |
589 |
} |
586 |
} while((src_line = play_tree_parser_get_line(p)) != NULL); |
590 |
} while((src_line = play_tree_parser_get_stripped_line(p)) != NULL); |
587 |
|
591 |
|
588 |
if (line) |
592 |
if (line) |
589 |
free(line); |
593 |
free(line); |
Lines 630-637
Link Here
|
630 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying plaintext playlist...\n"); |
634 |
mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying plaintext playlist...\n"); |
631 |
play_tree_parser_stop_keeping(p); |
635 |
play_tree_parser_stop_keeping(p); |
632 |
|
636 |
|
633 |
while((line = play_tree_parser_get_line(p)) != NULL) { |
637 |
while((line = play_tree_parser_get_stripped_line(p)) != NULL) { |
634 |
strstrip(line); |
|
|
635 |
if(line[0] == '\0' || line[0] == '#' || (line[0] == '/' && line[1] == '/')) |
638 |
if(line[0] == '\0' || line[0] == '#' || (line[0] == '/' && line[1] == '/')) |
636 |
continue; |
639 |
continue; |
637 |
|
640 |
|