~ubuntu-branches/ubuntu/vivid/mpv/vivid

« back to all changes in this revision

Viewing changes to mpvcore/asxparser.c

  • Committer: Package Import Robot
  • Author(s): Alessandro Ghedini
  • Date: 2013-12-29 20:04:26 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20131229200426-w0qsj8clnui1pxaw
Tags: 0.3.0-1
* New upstream release
  - Fix --vf=expand example in manpage (Closes: #732271)
* Add 03_waf.patch to provide uncompressed waf scripts and modules
* Switch to waf build script
* Drop libmng-dev Build-Depends (not used anymore)
* Bump Standards-Version to 3.9.5 (no changes needed)
* Enable support for dvdnav
* Install more docs

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * This file is part of MPlayer.
3
 
 *
4
 
 * MPlayer is free software; you can redistribute it and/or modify
5
 
 * it under the terms of the GNU General Public License as published by
6
 
 * the Free Software Foundation; either version 2 of the License, or
7
 
 * (at your option) any later version.
8
 
 *
9
 
 * MPlayer is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
 * GNU General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU General Public License along
15
 
 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16
 
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
 
 */
18
 
 
19
 
#include "config.h"
20
 
 
21
 
#include <stdlib.h>
22
 
#include <stdio.h>
23
 
#include <stdarg.h>
24
 
#include <string.h>
25
 
#include <unistd.h>
26
 
 
27
 
#include "playlist.h"
28
 
#include "playlist_parser.h"
29
 
#include "stream/stream.h"
30
 
#include "asxparser.h"
31
 
#include "mpvcore/mp_msg.h"
32
 
 
33
 
 
34
 
typedef struct ASX_Parser_t ASX_Parser_t;
35
 
 
36
 
typedef struct {
37
 
  char* buffer;
38
 
  int line;
39
 
} ASX_LineSave_t;
40
 
 
41
 
struct ASX_Parser_t {
42
 
  int line; // Curent line
43
 
  ASX_LineSave_t *ret_stack;
44
 
  int ret_stack_size;
45
 
  char* last_body;
46
 
  int deep;
47
 
  struct playlist *pl;
48
 
};
49
 
 
50
 
ASX_Parser_t *asx_parser_new(struct playlist *pl);
51
 
 
52
 
void
53
 
asx_parser_free(ASX_Parser_t* parser);
54
 
 
55
 
/*
56
 
 * Return -1 on error, 0 when nothing is found, 1 on sucess
57
 
 */
58
 
int
59
 
asx_get_element(ASX_Parser_t* parser,char** _buffer,
60
 
                char** _element,char** _body,char*** _attribs);
61
 
 
62
 
int
63
 
asx_parse_attribs(ASX_Parser_t* parser,char* buffer,char*** _attribs);
64
 
 
65
 
/////// Attribs utils
66
 
 
67
 
char*
68
 
asx_get_attrib(const char* attrib,char** attribs);
69
 
 
70
 
#define asx_free_attribs(a) asx_list_free(&a,free)
71
 
 
72
 
////// List utils
73
 
 
74
 
typedef void (*ASX_FreeFunc)(void* arg);
75
 
 
76
 
void
77
 
asx_list_free(void* list_ptr,ASX_FreeFunc free_func);
78
 
 
79
 
 
80
 
////// List utils
81
 
 
82
 
void
83
 
asx_list_free(void* list_ptr,ASX_FreeFunc free_func) {
84
 
  void** ptr = *(void***)list_ptr;
85
 
  if(ptr == NULL) return;
86
 
  if(free_func != NULL) {
87
 
    for( ; *ptr != NULL ; ptr++)
88
 
      free_func(*ptr);
89
 
  }
90
 
  free(*(void**)list_ptr);
91
 
  *(void**)list_ptr = NULL;
92
 
}
93
 
 
94
 
/////// Attribs utils
95
 
 
96
 
char*
97
 
asx_get_attrib(const char* attrib,char** attribs) {
98
 
  char** ptr;
99
 
 
100
 
  if(attrib == NULL || attribs == NULL) return NULL;
101
 
  for(ptr = attribs; ptr[0] != NULL; ptr += 2){
102
 
    if(strcasecmp(ptr[0],attrib) == 0)
103
 
      return strdup(ptr[1]);
104
 
  }
105
 
  return NULL;
106
 
}
107
 
 
108
 
#define asx_warning_attrib_required(p,e,a) mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : element %s don't have the required attribute %s",p->line,e,a)
109
 
#define asx_warning_body_parse_error(p,e) mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : error while parsing %s body",p->line,e)
110
 
 
111
 
ASX_Parser_t *asx_parser_new(struct playlist *pl)
112
 
{
113
 
  ASX_Parser_t* parser = calloc(1,sizeof(ASX_Parser_t));
114
 
  parser->pl = pl;
115
 
  return parser;
116
 
}
117
 
 
118
 
void
119
 
asx_parser_free(ASX_Parser_t* parser) {
120
 
  if(!parser) return;
121
 
  free(parser->ret_stack);
122
 
  free(parser);
123
 
 
124
 
}
125
 
 
126
 
#define LETTER "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
127
 
#define SPACE " \n\t\r"
128
 
 
129
 
int
130
 
asx_parse_attribs(ASX_Parser_t* parser,char* buffer,char*** _attribs) {
131
 
  char *ptr1, *ptr2, *ptr3;
132
 
  int n_attrib = 0;
133
 
  char **attribs = NULL;
134
 
  char *attrib, *val;
135
 
 
136
 
  ptr1 = buffer;
137
 
  while(1) {
138
 
    for( ; strchr(SPACE,*ptr1) != NULL; ptr1++) { // Skip space
139
 
      if(*ptr1 == '\0') break;
140
 
    }
141
 
    ptr3 = strchr(ptr1,'=');
142
 
    if(ptr3 == NULL) break;
143
 
    for(ptr2 = ptr3-1; strchr(SPACE,*ptr2) != NULL; ptr2--) {
144
 
      if (ptr2 == ptr1) {
145
 
        mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : this should never append, back to attribute begin while skipping end space",parser->line);
146
 
        break;
147
 
      }
148
 
    }
149
 
    attrib = malloc(ptr2-ptr1+2);
150
 
    strncpy(attrib,ptr1,ptr2-ptr1+1);
151
 
    attrib[ptr2-ptr1+1] = '\0';
152
 
 
153
 
    ptr1 = strchr(ptr3,'"');
154
 
    if(ptr1 == NULL || ptr1[1] == '\0') ptr1 = strchr(ptr3,'\'');
155
 
    if(ptr1 == NULL || ptr1[1] == '\0') {
156
 
      mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : can't find attribute %s value",parser->line,attrib);
157
 
      free(attrib);
158
 
      break;
159
 
    }
160
 
    ptr2 = strchr(ptr1+1,ptr1[0]);
161
 
    if (ptr2 == NULL) {
162
 
      mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : value of attribute %s isn't finished",parser->line,attrib);
163
 
      free(attrib);
164
 
      break;
165
 
    }
166
 
    ptr1++;
167
 
    val = malloc(ptr2-ptr1+1);
168
 
    strncpy(val,ptr1,ptr2-ptr1);
169
 
    val[ptr2-ptr1] = '\0';
170
 
    n_attrib++;
171
 
 
172
 
    attribs = realloc(attribs, (2 * n_attrib + 1) * sizeof(char*));
173
 
    attribs[n_attrib*2-2] = attrib;
174
 
    attribs[n_attrib*2-1] = val;
175
 
 
176
 
    ptr1 = ptr2+1;
177
 
  }
178
 
 
179
 
  if(n_attrib > 0)
180
 
    attribs[n_attrib*2] = NULL;
181
 
 
182
 
  *_attribs = attribs;
183
 
 
184
 
  return n_attrib;
185
 
}
186
 
 
187
 
/*
188
 
 * Return -1 on error, 0 when nothing is found, 1 on sucess
189
 
 */
190
 
int
191
 
asx_get_element(ASX_Parser_t* parser,char** _buffer,
192
 
                char** _element,char** _body,char*** _attribs) {
193
 
  char *ptr1,*ptr2, *ptr3, *ptr4;
194
 
  char *attribs = NULL;
195
 
  char *element = NULL, *body = NULL, *ret = NULL, *buffer;
196
 
  int n_attrib = 0;
197
 
  int body_line = 0,attrib_line,ret_line,in = 0;
198
 
  int quotes = 0;
199
 
 
200
 
  if(_buffer == NULL || _element == NULL || _body == NULL || _attribs == NULL) {
201
 
    mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : asx_get_element called with invalid value",parser->line);
202
 
    return -1;
203
 
  }
204
 
 
205
 
  *_body = *_element = NULL;
206
 
  *_attribs =  NULL;
207
 
  buffer = *_buffer;
208
 
 
209
 
  if(buffer == NULL) return 0;
210
 
 
211
 
  if(parser->ret_stack && /*parser->last_body && */buffer != parser->last_body) {
212
 
    ASX_LineSave_t* ls = parser->ret_stack;
213
 
    int i;
214
 
    for(i = 0 ; i < parser->ret_stack_size ; i++) {
215
 
      if(buffer == ls[i].buffer) {
216
 
        parser->line = ls[i].line;
217
 
        break;
218
 
      }
219
 
 
220
 
    }
221
 
    if( i < parser->ret_stack_size) {
222
 
      i++;
223
 
      if( i < parser->ret_stack_size)
224
 
        memmove(parser->ret_stack,parser->ret_stack+i, (parser->ret_stack_size - i)*sizeof(ASX_LineSave_t));
225
 
      parser->ret_stack_size -= i;
226
 
      if(parser->ret_stack_size > 0)
227
 
        parser->ret_stack = realloc(parser->ret_stack,parser->ret_stack_size*sizeof(ASX_LineSave_t));
228
 
      else {
229
 
        free(parser->ret_stack);
230
 
        parser->ret_stack = NULL;
231
 
      }
232
 
    }
233
 
  }
234
 
 
235
 
  ptr1 = buffer;
236
 
  while(1) {
237
 
    for( ; ptr1[0] != '<' ; ptr1++) {
238
 
      if(ptr1[0] == '\0') {
239
 
        ptr1 = NULL;
240
 
        break;
241
 
      }
242
 
      if(ptr1[0] == '\n') parser->line++;
243
 
    }
244
 
    //ptr1 = strchr(ptr1,'<');
245
 
    if(!ptr1 || ptr1[1] == '\0') return 0; // Nothing found
246
 
 
247
 
    if(strncmp(ptr1,"<!--",4) == 0) { // Comments
248
 
      for( ; strncmp(ptr1,"-->",3) != 0 ; ptr1++) {
249
 
        if(ptr1[0] == '\0') {
250
 
          ptr1 = NULL;
251
 
          break;
252
 
        }
253
 
        if(ptr1[0] == '\n') parser->line++;
254
 
      }
255
 
      //ptr1 = strstr(ptr1,"-->");
256
 
      if(!ptr1) {
257
 
        mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : unfinished comment",parser->line);
258
 
        return -1;
259
 
      }
260
 
    } else {
261
 
      break;
262
 
    }
263
 
  }
264
 
 
265
 
  // Is this space skip very useful ??
266
 
  for(ptr1++; strchr(SPACE,ptr1[0]) != NULL; ptr1++) { // Skip space
267
 
    if(ptr1[0] == '\0') {
268
 
      mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line);
269
 
      return -1;
270
 
    }
271
 
    if(ptr1[0] == '\n') parser->line++;
272
 
  }
273
 
 
274
 
  for(ptr2 = ptr1; strchr(LETTER,*ptr2) != NULL;ptr2++) { // Go to end of name
275
 
    if(*ptr2 == '\0'){
276
 
      mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line);
277
 
      return -1;
278
 
    }
279
 
    if(ptr2[0] == '\n') parser->line++;
280
 
  }
281
 
 
282
 
  element = malloc(ptr2-ptr1+1);
283
 
  strncpy(element,ptr1,ptr2-ptr1);
284
 
  element[ptr2-ptr1] = '\0';
285
 
 
286
 
  for( ; strchr(SPACE,*ptr2) != NULL; ptr2++) { // Skip space
287
 
    if(ptr2[0] == '\0') {
288
 
      mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line);
289
 
      free(element);
290
 
      return -1;
291
 
    }
292
 
    if(ptr2[0] == '\n') parser->line++;
293
 
  }
294
 
  attrib_line = parser->line;
295
 
 
296
 
 
297
 
 
298
 
  for(ptr3 = ptr2; ptr3[0] != '\0'; ptr3++) { // Go to element end
299
 
    if(ptr3[0] == '"') quotes ^= 1;
300
 
    if(!quotes && (ptr3[0] == '>' || strncmp(ptr3,"/>",2) == 0))
301
 
      break;
302
 
    if(ptr3[0] == '\n') parser->line++;
303
 
  }
304
 
  if(ptr3[0] == '\0' || ptr3[1] == '\0') { // End of file
305
 
    mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line);
306
 
    free(element);
307
 
    return -1;
308
 
  }
309
 
 
310
 
  // Save attribs string
311
 
  if(ptr3-ptr2 > 0) {
312
 
    attribs = malloc(ptr3-ptr2+1);
313
 
    strncpy(attribs,ptr2,ptr3-ptr2);
314
 
    attribs[ptr3-ptr2] = '\0';
315
 
  }
316
 
  //bs_line = parser->line;
317
 
  if(ptr3[0] != '/') { // Not Self closed element
318
 
    ptr3++;
319
 
    for( ; strchr(SPACE,*ptr3) != NULL; ptr3++) { // Skip space on body begin
320
 
      if(*ptr3 == '\0') {
321
 
        mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing %s element body",parser->line,element);
322
 
        free(element);
323
 
        free(attribs);
324
 
        return -1;
325
 
      }
326
 
      if(ptr3[0] == '\n') parser->line++;
327
 
    }
328
 
    ptr4 = ptr3;
329
 
    body_line = parser->line;
330
 
    while(1) { // Find closing element
331
 
      for( ; ptr4[0] != '<' ; ptr4++) {
332
 
        if(ptr4[0] == '\0') {
333
 
          ptr4 = NULL;
334
 
          break;
335
 
        }
336
 
        if(ptr4[0] == '\n') parser->line++;
337
 
      }
338
 
      if(ptr4 && strncmp(ptr4,"<!--",4) == 0) { // Comments
339
 
        for( ; strncmp(ptr4,"-->",3) != 0 ; ptr4++) {
340
 
        if(ptr4[0] == '\0') {
341
 
          ptr4 = NULL;
342
 
          break;
343
 
        }
344
 
        if(ptr1[0] == '\n') parser->line++;
345
 
        }
346
 
        continue;
347
 
      }
348
 
      if(ptr4 == NULL || ptr4[1] == '\0') {
349
 
        mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing %s element body",parser->line,element);
350
 
        free(element);
351
 
        free(attribs);
352
 
        return -1;
353
 
      }
354
 
      if(ptr4[1] != '/' && strncasecmp(element,ptr4+1,strlen(element)) == 0) {
355
 
        in++;
356
 
        ptr4+=2;
357
 
        continue;
358
 
      } else if(strncasecmp(element,ptr4+2,strlen(element)) == 0) { // Extract body
359
 
        if(in > 0) {
360
 
          in--;
361
 
          ptr4 += 2+strlen(element);
362
 
          continue;
363
 
        }
364
 
        ret = ptr4+strlen(element)+3;
365
 
        if(ptr4 != ptr3) {
366
 
          ptr4--;
367
 
          for( ; ptr4 != ptr3 && strchr(SPACE,*ptr4) != NULL; ptr4--) ;// Skip space on body end
368
 
          //        if(ptr4[0] == '\0') parser->line--;
369
 
          //}
370
 
          ptr4++;
371
 
          body = malloc(ptr4-ptr3+1);
372
 
          strncpy(body,ptr3,ptr4-ptr3);
373
 
          body[ptr4-ptr3] = '\0';
374
 
        }
375
 
        break;
376
 
      } else {
377
 
        ptr4 += 2;
378
 
      }
379
 
    }
380
 
  } else {
381
 
    ret = ptr3 + 2; // 2 is for />
382
 
  }
383
 
 
384
 
  for( ; ret[0] != '\0' && strchr(SPACE,ret[0]) != NULL; ret++) { // Skip space
385
 
    if(ret[0] == '\n') parser->line++;
386
 
  }
387
 
 
388
 
  ret_line = parser->line;
389
 
 
390
 
  if(attribs) {
391
 
    parser->line = attrib_line;
392
 
    n_attrib = asx_parse_attribs(parser,attribs,_attribs);
393
 
    free(attribs);
394
 
    if(n_attrib < 0) {
395
 
      mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : error while parsing element %s attributes",parser->line,element);
396
 
      free(element);
397
 
      free(body);
398
 
      return -1;
399
 
    }
400
 
  } else
401
 
    *_attribs = NULL;
402
 
 
403
 
  *_element = element;
404
 
  *_body = body;
405
 
 
406
 
  parser->last_body = body;
407
 
  parser->ret_stack_size++;
408
 
  parser->ret_stack = realloc(parser->ret_stack,parser->ret_stack_size*sizeof(ASX_LineSave_t));
409
 
  if(parser->ret_stack_size > 1)
410
 
    memmove(parser->ret_stack+1,parser->ret_stack,(parser->ret_stack_size-1)*sizeof(ASX_LineSave_t));
411
 
  parser->ret_stack[0].buffer = ret;
412
 
  parser->ret_stack[0].line = ret_line;
413
 
  parser->line = body ? body_line : ret_line;
414
 
 
415
 
  *_buffer = ret;
416
 
  return 1;
417
 
 
418
 
}
419
 
 
420
 
static void
421
 
asx_parse_ref(ASX_Parser_t* parser, char** attribs) {
422
 
  char *href;
423
 
 
424
 
  href = asx_get_attrib("HREF",attribs);
425
 
  if(href == NULL) {
426
 
    asx_warning_attrib_required(parser,"REF" ,"HREF" );
427
 
    return;
428
 
  }
429
 
#if 0
430
 
  // replace http my mmshttp to avoid infinite loops
431
 
  // disabled since some playlists for e.g. WinAMP use asx as well
432
 
  // "-user-agent NSPlayer/4.1.0.3856" is a possible workaround
433
 
  if (strncmp(href, "http://", 7) == 0) {
434
 
    char *newref = malloc(3 + strlen(href) + 1);
435
 
    strcpy(newref, "mms");
436
 
    strcpy(newref + 3, href);
437
 
    free(href);
438
 
    href = newref;
439
 
  }
440
 
#endif
441
 
 
442
 
  playlist_add_file(parser->pl, href);
443
 
 
444
 
  mp_msg(MSGT_PLAYTREE,MSGL_V,"Adding file %s to element entry\n",href);
445
 
 
446
 
  free(href);
447
 
 
448
 
}
449
 
 
450
 
static void asx_parse_entryref(ASX_Parser_t* parser,char* buffer,char** _attribs) {
451
 
  char *href;
452
 
 
453
 
  if(parser->deep > 0)
454
 
    return;
455
 
 
456
 
  href = asx_get_attrib("HREF",_attribs);
457
 
  if(href == NULL) {
458
 
    asx_warning_attrib_required(parser,"ENTRYREF" ,"HREF" );
459
 
    return;
460
 
  }
461
 
  mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Recursive playlist %s\n", href);
462
 
  playlist_add_file(parser->pl, href);
463
 
  free(href);
464
 
  //mp_msg(MSGT_PLAYTREE,MSGL_INFO,"Need to implement entryref\n");
465
 
}
466
 
 
467
 
static void asx_parse_entry(ASX_Parser_t* parser,char* buffer,char** _attribs) {
468
 
  char *element,*body,**attribs;
469
 
  int r;
470
 
 
471
 
  while(buffer && buffer[0] != '\0') {
472
 
    r = asx_get_element(parser,&buffer,&element,&body,&attribs);
473
 
    if(r < 0) {
474
 
      asx_warning_body_parse_error(parser,"ENTRY");
475
 
      return;
476
 
    } else if (r == 0) { // No more element
477
 
      break;
478
 
    }
479
 
    if(strcasecmp(element,"REF") == 0) {
480
 
      asx_parse_ref(parser,attribs);
481
 
      mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to entry\n",element);
482
 
    } else
483
 
      mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element);
484
 
    free(body);
485
 
    asx_free_attribs(attribs);
486
 
  }
487
 
 
488
 
}
489
 
 
490
 
 
491
 
static void asx_parse_repeat(ASX_Parser_t* parser,char* buffer,char** _attribs) {
492
 
  char *element,*body,**attribs;
493
 
  int r;
494
 
 
495
 
  asx_get_attrib("COUNT",_attribs);
496
 
  mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Ignoring repeated playlist entries\n");
497
 
 
498
 
  while(buffer && buffer[0] != '\0') {
499
 
    r = asx_get_element(parser,&buffer,&element,&body,&attribs);
500
 
    if(r < 0) {
501
 
      asx_warning_body_parse_error(parser,"REPEAT");
502
 
      return;
503
 
    } else if (r == 0) { // No more element
504
 
      break;
505
 
    }
506
 
    if(strcasecmp(element,"ENTRY") == 0) {
507
 
       asx_parse_entry(parser,body,attribs);
508
 
    } else if(strcasecmp(element,"ENTRYREF") == 0) {
509
 
       asx_parse_entryref(parser,body,attribs);
510
 
     } else if(strcasecmp(element,"REPEAT") == 0) {
511
 
       asx_parse_repeat(parser,body,attribs);
512
 
     } else
513
 
       mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element);
514
 
     free(body);
515
 
     asx_free_attribs(attribs);
516
 
  }
517
 
 
518
 
}
519
 
 
520
 
 
521
 
bool asx_parse(char* buffer, struct playlist *pl)
522
 
{
523
 
  char *element,*asx_body,**asx_attribs,*body = NULL, **attribs;
524
 
  int r;
525
 
  ASX_Parser_t* parser = asx_parser_new(pl);
526
 
 
527
 
  parser->line = 1;
528
 
  parser->deep = 0;
529
 
 
530
 
   r = asx_get_element(parser,&buffer,&element,&asx_body,&asx_attribs);
531
 
  if(r < 0) {
532
 
    mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : Syntax error ???",parser->line);
533
 
    asx_parser_free(parser);
534
 
    return false;
535
 
  } else if(r == 0) { // No contents
536
 
    mp_msg(MSGT_PLAYTREE,MSGL_ERR,"empty asx element");
537
 
    asx_parser_free(parser);
538
 
    return false;
539
 
  }
540
 
 
541
 
  if(strcasecmp(element,"ASX") != 0) {
542
 
    mp_msg(MSGT_PLAYTREE,MSGL_ERR,"first element isn't ASX, it's %s\n",element);
543
 
    asx_free_attribs(asx_attribs);
544
 
    asx_parser_free(parser);
545
 
    return false;
546
 
  }
547
 
 
548
 
  if(!asx_body) {
549
 
    mp_msg(MSGT_PLAYTREE,MSGL_ERR,"ASX element is empty");
550
 
    asx_free_attribs(asx_attribs);
551
 
    asx_parser_free(parser);
552
 
    return false;
553
 
  }
554
 
 
555
 
  buffer = asx_body;
556
 
  while(buffer && buffer[0] != '\0') {
557
 
    r = asx_get_element(parser,&buffer,&element,&body,&attribs);
558
 
     if(r < 0) {
559
 
       asx_warning_body_parse_error(parser,"ASX");
560
 
       asx_parser_free(parser);
561
 
       return false;
562
 
     } else if (r == 0) { // No more element
563
 
       break;
564
 
     }
565
 
     if(strcasecmp(element,"ENTRY") == 0) {
566
 
       asx_parse_entry(parser,body,attribs);
567
 
     } else if(strcasecmp(element,"ENTRYREF") == 0) {
568
 
       asx_parse_entryref(parser,body,attribs);
569
 
     } else if(strcasecmp(element,"REPEAT") == 0) {
570
 
       asx_parse_repeat(parser,body,attribs);
571
 
     } else
572
 
       mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element);
573
 
     free(body);
574
 
     asx_free_attribs(attribs);
575
 
  }
576
 
 
577
 
  free(asx_body);
578
 
  asx_free_attribs(asx_attribs);
579
 
  asx_parser_free(parser);
580
 
  return true;
581
 
}