Mercurial > mplayer.hg
view playtreeparser.c @ 4479:423ce4451ca8
tested and fixed on 2.2.x, more comments
author | alex |
---|---|
date | Sat, 02 Feb 2002 17:35:53 +0000 |
parents | d752f99fd535 |
children | 7d24c9bd2ae5 |
line wrap: on
line source
#include "config.h" #include <stdlib.h> #include <stdio.h> #include <string.h> #ifdef MP_DEBUG #include <assert.h> #endif #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include "playtree.h" #include "playtreeparser.h" #include "libmpdemux/stream.h" #include "mp_msg.h" extern play_tree_t* asx_parser_build_tree(char* buffer, int ref); play_tree_t* parse_asx(play_tree_parser_t* p) { int r; int comments = 0,read = 1,eof = 0; mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying asx...\n"); while(1) { if(read && eof) // Eof reached before anything useful return NULL; if(read) { if(p->buffer_size - p->buffer_end < 50) p->buffer_size += 255; p->buffer = (char*)realloc(p->buffer,p->buffer_size*sizeof(char)); if(p->buffer == NULL) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory\n",p->buffer_size*sizeof(char)); p->buffer_size = p->buffer_end = 0; return NULL; } r = stream_read(p->stream,p->buffer+p->buffer_end,p->buffer_size-p->buffer_end-1); if(r < 0) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't read from stream r=%d\n",r); return NULL; } else if(r == 0) eof = 1; p->buffer_end += r; p->buffer[p->buffer_end] = '\0'; } if(comments) { // Jump comments int e; char* end = strstr(p->buffer,"-->"); if(!end) { if(p->buffer[p->buffer_end-1] != '-') p->buffer_end = 0; // Drop buffer content if last char isn't '-' continue; } comments = 0; e = end - p->buffer + 3; if(e >= p->buffer_end) { // > seems impossible p->buffer_end = 0; // Drop buffer content read = 1; continue; } p->buffer_end -= e; memmove(p->buffer,end+3,p->buffer_end); // Drop comments continue; } for(r= 0 ; r < p->buffer_end ; r++) { if(strchr(" \n\r\t",p->buffer[r]) != NULL) // Jump space continue; if(p->buffer[r] != '<') { mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"First char isn't '<' but '%c'\n",p->buffer[r]); mp_msg(MSGT_PLAYTREE,MSGL_DBG3,"Buffer = [%s]\n",p->buffer); return NULL; } break; // Stop on first '<' } if(r > p->buffer_end-4) { // We need more if(r > 0) { // Drop unuseful beggining p->buffer_end -= r; memmove(p->buffer,&p->buffer[r],p->buffer_end); } read = 1; continue; } if(strncmp(&p->buffer[r],"<!--",4) == 0) { // Comments read = 0; comments = 1; continue; } if(strncasecmp(&p->buffer[r],"<ASX",4) != 0) // First element is not a comment nor an asx : end return NULL; mp_msg(MSGT_PLAYTREE,MSGL_V,"Detected asx format\n"); break; } // We have an asx : load it in memory and parse while(!eof) { if(p->buffer_size - p->buffer_end < 50) p->buffer_size += 255; p->buffer = (char*)realloc(p->buffer,p->buffer_size*sizeof(char)); if(p->buffer == NULL) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory\n",p->buffer_size*sizeof(char)); p->buffer_size = p->buffer_end = 0; return NULL; } r = stream_read(p->stream,p->buffer+p->buffer_end,p->buffer_size-p->buffer_end-1); if(r > 0) p->buffer_end += r; if(r <= 0) break; p->buffer[p->buffer_end] = '\0'; } mp_msg(MSGT_PLAYTREE,MSGL_DBG3,"Parsing asx file : [%s]\n",p->buffer); return asx_parser_build_tree(p->buffer,p->deep); } play_tree_t* parse_textplain(play_tree_parser_t* p) { char* end; char* file; int eof = 0,r,p_end=-1,resize = 0; play_tree_t *list = NULL, *entry = NULL; mp_msg(MSGT_PLAYTREE,MSGL_V,"Trying plaintext...\n"); if(p->buffer_size < 255 && ! p->stream->eof) { p->buffer_size = 255; p->buffer = (char*)realloc(p->buffer,p->buffer_size*sizeof(char)); if(p->buffer == NULL) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory\n",p->buffer_size*sizeof(char)); p->buffer_size = p->buffer_end = 0; return NULL; } } while(!eof) { if(resize) { p->buffer_size += 255; p->buffer = (char*)realloc(p->buffer,p->buffer_size*sizeof(char)); resize = 0; if(p->buffer == NULL) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory\n",p->buffer_size*sizeof(char)); p->buffer_size = p->buffer_end = 0; if(list) play_tree_free_list(list,1); return NULL; } } if(!p->stream->eof) { r = stream_read(p->stream,p->buffer+p->buffer_end,p->buffer_size-p->buffer_end-1); if(r < 0) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't read from stream r=%d\n",r); return NULL; } else if(r == 0) eof = 1; p->buffer_end += r; p->buffer[p->buffer_end] = '\0'; } else eof = 1; r = 0; while(1) { p_end = r; for( ; p->buffer[r] != '\0' ; r++) { if(strchr(" \n\r\t",p->buffer[r]) != NULL) continue; break; } if(p->buffer[r] == '\0') { p_end = r; if(!eof) resize = 1; break; } end = strchr(&p->buffer[r],'\n'); if(!end) { if(!eof) { p_end = r; if(p_end == 0) { resize = 1; } break; } entry = play_tree_new(); play_tree_add_file(entry,&p->buffer[r]); r = p->buffer_end; } else { if(r > 0 && p->buffer[r-1] == '\r') r--; file = (char*)malloc((end-(&p->buffer[r])+1)*sizeof(char)); if(file == NULL) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory\n",p->buffer_size*sizeof(char)); p->buffer_size = p->buffer_end = 0; if(list) play_tree_free_list(list,1); return NULL; } // TODO : Check if the given file exist and is readable (or it'a an url) strncpy(file,&p->buffer[r],end-(&p->buffer[r])); file[end-(&p->buffer[r])] = '\0'; entry = play_tree_new(); play_tree_add_file(entry,file); free(file); r += end-(&p->buffer[r]); p_end = r; } if(entry) { mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding file %s to playlist\n",entry->files[0]); if(list) play_tree_append_entry(list,entry); else list = entry; entry = NULL; } } if(!eof && p_end > 0 && p_end < p->buffer_end) { memmove(p->buffer,&p->buffer[p_end],p->buffer_end-p_end); p->buffer_end -= p_end; } else if(!eof && !resize && p_end == p->buffer_end) { p->buffer_end = 0; p->buffer[0] = '\0'; } } if(!list) return NULL; entry = play_tree_new(); play_tree_set_child(entry,list); return entry; } play_tree_t* parse_playtree(stream_t *stream) { play_tree_parser_t* p; play_tree_t* ret; #ifdef MP_DEBUG assert(stream != NULL); assert(stream->type == STREAMTYPE_PLAYLIST); #endif p = play_tree_parser_new(stream,0); if(!p) return NULL; ret = play_tree_parser_get_play_tree(p); play_tree_parser_free(p); return ret; } play_tree_t* parse_playlist_file(char* file) { stream_t *stream; play_tree_t* ret; int fd; if(!strcmp(file,"-")) fd = 0; else fd = open(file,O_RDONLY); if(fd < 0) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Error while opening playlist file %s : %s\n",file,strerror(errno)); return NULL; } mp_msg(MSGT_PLAYTREE,MSGL_V,"Parsing playlist file %s...\n",file); stream = new_stream(fd,STREAMTYPE_PLAYLIST); ret = parse_playtree(stream); if(close(fd) < 0) mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Warning error while closing playlist file %s : %s\n",file,strerror(errno)); free_stream(stream); return ret; } play_tree_parser_t* play_tree_parser_new(stream_t* stream,int deep) { play_tree_parser_t* p; p = (play_tree_parser_t*)calloc(1,sizeof(play_tree_parser_t)); if(!p) return NULL; p->stream = stream; p->deep = deep; return p; } void play_tree_parser_free(play_tree_parser_t* p) { #ifdef MP_DEBUG assert(p != NULL); #endif if(p->buffer) free(p->buffer); free(p->buffer); } play_tree_t* play_tree_parser_get_play_tree(play_tree_parser_t* p) { play_tree_t* tree = NULL; #ifdef MP_DEBUG assert(p != NULL); #endif while(1) { tree = parse_asx(p); if(tree) break; // Here come the others formats ( textplain must stay the last one ) tree = parse_textplain(p); if(tree) break; break; } if(tree) mp_msg(MSGT_PLAYTREE,MSGL_V,"Playlist succefully parsed\n"); else mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Error while parsing playlist\n"); if(tree) tree = play_tree_cleanup(tree); if(!tree) mp_msg(MSGT_PLAYTREE,MSGL_WARN,"Warning empty playlist\n"); if(p->buffer) free(p->buffer); p->buffer = NULL; p->buffer_end = p->buffer_size = 0; return tree; }