Remove iTunes XML playlist parsing code

This commit is contained in:
Julien BLACHE 2009-04-20 16:48:37 +02:00
parent 69d6acad37
commit 1a0e1731e4
6 changed files with 1 additions and 2744 deletions

View File

@ -22,8 +22,7 @@ mt_daapd_SOURCES = main.c daapd.h webserver.c \
filescanner_ffmpeg.c filescanner_urlfile.c filescanner_m3u.c \
mdns_avahi.c mdns_avahi.h \
db-generic.c db-generic.h ff-plugins.c ff-plugins.h \
rxml.c rxml.h redblack.c redblack.h \
scan-xml.c scan-wma.c \
scan-wma.c \
smart-parser.c smart-parser.h xml-rpc.c xml-rpc.h \
util.c util.h \
plugin.c plugin.h db-sql-updates.c \

File diff suppressed because it is too large Load Diff

View File

@ -1,195 +0,0 @@
/*
Redblack balanced tree algorithm
Copyright (C) Damian Ivereigh 2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. See the file COPYING for details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Header file for redblack.c, should be included by any code that
** uses redblack.c since it defines the functions
*/
/* Stop multiple includes */
#ifndef _REDBLACK_H
#ifndef RB_CUSTOMIZE
/*
* Without customization, the data member in the tree nodes is a void
* pointer, and you need to pass in a comparison function to be
* applied at runtime. With customization, you specify the data type
* as the macro RB_ENTRY(data_t) (has to be a macro because compilers
* gag on typdef void) and the name of the compare function as the
* value of the macro RB_CMP. Because the comparison function is
* compiled in, RB_CMP only needs to take two arguments. If your
* content type is not a pointer, define INLINE to get direct access.
*/
#define rbdata_t void
#define RB_CMP(s, t, e) (*rbinfo->rb_cmp)(s, t, e)
#undef RB_INLINE
#define RB_ENTRY(name) rb##name
#endif /* RB_CUSTOMIZE */
#ifndef RB_STATIC
#define RB_STATIC
#endif
/* Modes for rblookup */
#define RB_NONE -1 /* None of those below */
#define RB_LUEQUAL 0 /* Only exact match */
#define RB_LUGTEQ 1 /* Exact match or greater */
#define RB_LULTEQ 2 /* Exact match or less */
#define RB_LULESS 3 /* Less than key (not equal to) */
#define RB_LUGREAT 4 /* Greater than key (not equal to) */
#define RB_LUNEXT 5 /* Next key after current */
#define RB_LUPREV 6 /* Prev key before current */
#define RB_LUFIRST 7 /* First key in index */
#define RB_LULAST 8 /* Last key in index */
/* For rbwalk - pinched from search.h */
typedef enum
{
preorder,
postorder,
endorder,
leaf
}
VISIT;
struct RB_ENTRY(lists) {
const struct RB_ENTRY(node) *rootp;
const struct RB_ENTRY(node) *nextp;
};
#define RBLIST struct RB_ENTRY(lists)
struct RB_ENTRY(tree) {
#ifndef RB_CUSTOMIZE
/* comparison routine */
int (*rb_cmp)(const void *, const void *, const void *);
/* config data to be passed to rb_cmp */
const void *rb_config;
/* root of tree */
#endif /* RB_CUSTOMIZE */
struct RB_ENTRY(node) *rb_root;
};
#ifndef RB_CUSTOMIZE
RB_STATIC struct RB_ENTRY(tree) *rbinit(int (*)(const void *, const void *, const void *),
const void *);
#else
RB_STATIC struct RB_ENTRY(tree) *RB_ENTRY(init)(void);
#endif /* RB_CUSTOMIZE */
#ifndef no_delete
RB_STATIC const RB_ENTRY(data_t) *RB_ENTRY(delete)(const RB_ENTRY(data_t) *, struct RB_ENTRY(tree) *);
#endif
#ifndef no_find
RB_STATIC const RB_ENTRY(data_t) *RB_ENTRY(find)(const RB_ENTRY(data_t) *, struct RB_ENTRY(tree) *);
#endif
#ifndef no_lookup
RB_STATIC const RB_ENTRY(data_t) *RB_ENTRY(lookup)(int, const RB_ENTRY(data_t) *, struct RB_ENTRY(tree) *);
#endif
#ifndef no_search
RB_STATIC const RB_ENTRY(data_t) *RB_ENTRY(search)(const RB_ENTRY(data_t) *, struct RB_ENTRY(tree) *);
#endif
#ifndef no_destroy
RB_STATIC void RB_ENTRY(destroy)(struct RB_ENTRY(tree) *);
#endif
#ifndef no_walk
RB_STATIC void RB_ENTRY(walk)(const struct RB_ENTRY(tree) *,
void (*)(const RB_ENTRY(data_t) *, const VISIT, const int, void *),
void *);
#endif
#ifndef no_readlist
RB_STATIC RBLIST *RB_ENTRY(openlist)(const struct RB_ENTRY(tree) *);
RB_STATIC const RB_ENTRY(data_t) *RB_ENTRY(readlist)(RBLIST *);
RB_STATIC void RB_ENTRY(closelist)(RBLIST *);
#endif
/* Some useful macros */
#define rbmin(rbinfo) RB_ENTRY(lookup)(RB_LUFIRST, NULL, (rbinfo))
#define rbmax(rbinfo) RB_ENTRY(lookup)(RB_LULAST, NULL, (rbinfo))
#define _REDBLACK_H
#endif /* _REDBLACK_H */
/*
*
* Revision 1.4 2006/02/26 08:46:24 rpedde
* Merged win32-branch
*
* Revision 1.3.2.1 2006/02/26 08:28:35 rpedde
* unix fixes from win32 port
*
* Revision 1.3 2005/05/21 05:56:09 rpedde
* for quick translation from itunes song id to mt-daapd song id
*
* Revision 1.1 2004/03/13 23:43:02 rpedde
* Add Damian Ivereigh's redblack tree implementation to speed lookups
*
* Revision 1.9 2003/10/24 01:31:21 damo
* Patches from Eric Raymond: %prefix is implemented.  Various other small
* changes avoid stepping on global namespaces and improve the documentation.
*
* Revision 1.8 2003/10/23 04:18:47 damo
* Fixed up the rbgen stuff ready for the 1.3 release
*
* Revision 1.7 2002/08/26 03:11:40 damo
* Fixed up a bunch of compiler warnings when compiling example4
*
* Tidies up the Makefile.am & Specfile.
*
* Renamed redblack to rbgen
*
* Revision 1.6 2002/08/26 01:03:35 damo
* Patch from Eric Raymond to change the way the library is used:-
*
* Eric's idea is to convert libredblack into a piece of in-line code
* generated by another program. This should be faster, smaller and easier
* to use.
*
* This is the first check-in of his code before I start futzing with it!
*
* Revision 1.5 2002/01/30 07:54:53 damo
* Fixed up the libtool versioning stuff (finally)
* Fixed bug 500600 (not detecting a NULL return from malloc)
* Fixed bug 509485 (no longer needs search.h)
* Cleaned up debugging section
* Allow multiple inclusions of redblack.h
* Thanks to Matthias Andree for reporting (and fixing) these
*
* Revision 1.4 2000/06/06 14:43:43 damo
* Added all the rbwalk & rbopenlist stuff. Fixed up malloc instead of sbrk.
* Added two new examples
*
* Revision 1.3 2000/05/24 06:45:27 damo
* Converted everything over to using const
* Added a new example1.c file to demonstrate the worst case scenario
* Minor fixups of the spec file
*
* Revision 1.2 2000/05/24 06:17:10 damo
* Fixed up the License (now the LGPL)
*
* Revision 1.1 2000/05/24 04:15:53 damo
* Initial import of files. Versions are now all over the place. Oh well
*
*/

View File

@ -1,351 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "daapd.h"
#include "io.h"
#include "rxml.h"
/* Typedefs/Defines */
#define RXML_ERROR(a,b) { (a)->ecode=(b); return 0; };
#define RXML_MAX_LINE 1024
#define RXML_MAX_TEXT 1024
#define RXML_MAX_TAG 256
typedef struct _RXML {
RXML_EVTHANDLER handler;
char *fname;
IOHANDLE hfile;
void *udata;
int ecode;
int line;
char *estring;
} RXML;
#ifndef FALSE
# define FALSE 0
# define TRUE 1
#endif /* FALSE */
#define E_RXML_SUCCESS 0x00
#define E_RXML_OPEN 0x01 | 0x80
#define E_RXML_READ 0x02 | 0x80
#define E_RXML_NEST 0x03
#define E_RXML_SPLIT 0x04
#define E_RXML_CLOSE 0x05
#define E_RXML_TAGSIZE 0x06
#define E_RXML_ENTITY 0x07
#define E_RXML_MALLOC 0x08
char *rxml_estrings[] = {
"Success",
"Could not open xml file: ",
"Error reading file: ",
"Parse error: Nested tags",
"Parse error: Tag split over multiple lines",
"Parse error: Unexpected '>'",
"Parse error: tag too big",
"Parse error: bad entity encoding",
"Internal malloc error",
NULL
};
/* Forwards */
static int rxml_decode_string(char *string);
/**
* decode an xml entity-encoded string in-place
*
* @param string string to encode
* @returns 1 on success, 0 on error
*/
int rxml_decode_string(char *string) {
char *src, *dst;
int len;
int cval;
src=dst=string;
while(*src) {
if((*src) == '&') {
len = (int)strlen(src);
if((len > 3) && (strncmp(src,"&gt;",4) == 0)) {
*dst++ = '>';
src += 4;
} else if((len > 3) && (strncmp(src,"&lt;",4) == 0)) {
*dst++ = '<';
src += 4;
} else if((len > 4) && (strncmp(src,"&amp;",5) == 0)) {
*dst++ = '&';
src += 5;
} else if((len > 5) && (strncmp(src,"&quot;",6) == 0)) {
*dst++ = '"';
src += 6;
} else if((len > 5) && (strncmp(src,"&apos;",6) == 0)) {
*dst ++ = '\'';
src += 6;
} else {
/* &#xx; */
if(!sscanf((char*)&src[2],"%d;",&cval))
return FALSE;
*dst++ = cval;
if(src[3] == ';') {
src += 4;
} else if(src[4] == ';') {
src += 5;
} else if(src[5] == ';') {
src += 6;
} else {
return FALSE;
}
}
} else {
*dst++=*src++;
}
}
*dst = '\0';
return TRUE;
}
/**
* open a file
*
* @param vp pointer to the opaque xml struct
* @param file filename of file to open
* @param handler handler function for events
* @param udata opaque data structure to pass to the callback
*/
int rxml_open(RXMLHANDLE *vp, char *file,
RXML_EVTHANDLER handler, void *udata) {
RXML *pnew;
char *urltemp;
int ret;
pnew=(RXML*)malloc(sizeof(RXML));
if(!pnew) {
*vp = NULL;
return FALSE;
}
memset(pnew,0x0,sizeof(RXML));
*vp = pnew;
pnew->handler = handler;
pnew->fname = file;
pnew->hfile = io_new();
if(!pnew->hfile)
RXML_ERROR(pnew,E_RXML_MALLOC);
urltemp = io_urlencode(file);
if (!urltemp)
RXML_ERROR(pnew,E_RXML_MALLOC);
ret = io_open(pnew->hfile, "file://%s?ascii=1", urltemp);
free(urltemp);
if (!ret) {
io_dispose(pnew->hfile);
pnew->hfile = NULL;
RXML_ERROR(pnew,E_RXML_OPEN);
}
io_buffer(pnew->hfile);
pnew->udata = udata;
pnew->line = 0;
if(pnew->handler)
pnew->handler(RXML_EVT_OPEN, pnew->udata, pnew->fname);
return TRUE;
}
/**
* close the currently open file
*
* @param vp xml struct containing info about the file to close
*/
int rxml_close(RXMLHANDLE vp) {
RXML *ph = (RXML*)vp;
if(ph->handler) ph->handler(RXML_EVT_CLOSE,ph->udata,ph->fname);
if(ph->hfile) {
io_close(ph->hfile);
io_dispose(ph->hfile);
}
if(ph->estring) free(ph->estring);
free(ph);
return TRUE;
}
/**
* return a string describing the last error
*
* @param vp handle of the document with the error
*/
char *rxml_errorstring(RXMLHANDLE vp) {
RXML *ph = (RXML*)vp;
int len;
char *estring=NULL;
if(!ph) {
return "Malloc error";
}
if(ph->estring) free(ph->estring);
len = (int)strlen(rxml_estrings[ph->ecode]) + 16;
if((ph->ecode & 0x80)) {
estring=io_errstr(ph->hfile);
len += (int)strlen(estring);
}
ph->estring=(char*)malloc(len);
if(!ph->estring)
return "Double-fault malloc error";
if(((ph->ecode & 0x80) && (ph->hfile))) {
snprintf(ph->estring,len,"%s%s",rxml_estrings[ph->ecode],io_errstr(ph->hfile));
} else {
if(strncmp(rxml_estrings[ph->ecode],"Parse",5)==0) {
snprintf(ph->estring, len, "%s (Line:%d)",
rxml_estrings[ph->ecode], ph->line);
} else {
snprintf(ph->estring,len, "%s", rxml_estrings[ph->ecode]);
}
}
return ph->estring;
}
/**
* walk through the xml file, sending events to the
* callback handler.
*
* @param vp opaque doc struct of the doc to parse
*/
int rxml_parse(RXMLHANDLE vp) {
char linebuffer[RXML_MAX_LINE];
char tagbuffer[RXML_MAX_TAG];
char textbuffer[RXML_MAX_TEXT];
int in_text=0;
int text_offset=0;
int size;
int offset;
int in_tag=0;
int tag_end=0;
int tag_start=0;
int single_tag;
RXML *ph = (RXML*)vp;
uint32_t len;
ph->line = 0;
textbuffer[0] = '\0';
len = sizeof(linebuffer);
/* walk through and read row by row */
while(io_readline(ph->hfile,(unsigned char *)linebuffer,&len) && len) {
ph->line++;
offset=0;
size=(int)strlen(linebuffer);
in_text=0;
text_offset=0;
while(offset < size) {
switch(linebuffer[offset]) {
case '<':
if(in_tag)
RXML_ERROR(ph, E_RXML_NEST);
in_tag=TRUE;
tag_start=offset+1;
tag_end=FALSE;
if(linebuffer[tag_start] == '/') {
tag_end = TRUE;
offset++;
tag_start++;
}
offset++;
in_text=0;
break;
case '>':
if(!in_tag)
RXML_ERROR(ph, E_RXML_CLOSE);
in_tag=FALSE;
if((offset - tag_start) > RXML_MAX_TAG)
RXML_ERROR(ph, E_RXML_TAGSIZE);
strncpy(tagbuffer,&linebuffer[tag_start],offset-tag_start);
tagbuffer[offset-tag_start] = '\0';
if(tag_end) {
/* send the text before the tag end */
if((ph->handler) && (strlen(textbuffer))) {
if(!rxml_decode_string(textbuffer))
RXML_ERROR(ph,E_RXML_ENTITY);
ph->handler(RXML_EVT_TEXT,ph->udata,textbuffer);
}
}
in_text=1;
text_offset=0;
textbuffer[0] = '\0';
single_tag=0;
if(tagbuffer[strlen(tagbuffer)-1] == '/') {
tagbuffer[strlen(tagbuffer)-1] = '\0';
single_tag=1;
}
if(ph->handler)
ph->handler(tag_end ? RXML_EVT_END : RXML_EVT_BEGIN,
ph->udata,tagbuffer);
/* send a follow-up end on a <tag/> - style tag */
if((single_tag) && (ph->handler))
ph->handler(RXML_EVT_END,ph->udata,tagbuffer);
offset++;
break;
default:
if((in_text) && (text_offset < (sizeof(textbuffer)-1))) {
/* get rid of EOL */
if((linebuffer[offset] != '\r') &&
(linebuffer[offset] != '\n')) {
textbuffer[text_offset] = linebuffer[offset];
text_offset++;
textbuffer[text_offset] = '\x0';
}
} else if (in_text) {
/* should warn of an overflow */
}
offset++;
break;
}
}
len = sizeof(linebuffer);
}
if(len)
RXML_ERROR(ph,E_RXML_READ);
return TRUE;
}

View File

@ -1,20 +0,0 @@
#ifndef _RXML_H_
#define _RXML_H_
#define RXML_EVT_OPEN 0x0
#define RXML_EVT_CLOSE 0x1
#define RXML_EVT_BEGIN 0x2
#define RXML_EVT_END 0x3
#define RXML_EVT_TEXT 0x4
typedef void* RXMLHANDLE;
typedef void(*RXML_EVTHANDLER)(int,void*,char*);
extern int rxml_open(RXMLHANDLE *handle, char *file,
RXML_EVTHANDLER handler, void* udata);
extern int rxml_close(RXMLHANDLE handle);
extern char *rxml_errorstring(RXMLHANDLE handle);
extern int rxml_parse(RXMLHANDLE handle);
#endif /* _ RXML_H_ */

File diff suppressed because it is too large Load Diff