From fbf28eee494df702170bedd7e44609a6c018ffbd Mon Sep 17 00:00:00 2001 From: thor Date: Fri, 22 Dec 2006 02:28:31 +0000 Subject: [PATCH] Essential part of ICY support. It's in reader and http_open. Missing is only proper output - and, that it actually works:-/ There is something fishy in the reader... git-svn-id: svn://scm.orgis.org/mpg123/trunk@536 35dc7657-300d-0410-a2e5-dc2837fedb53 --- scripts/debugdef.pl | 2 +- src/Makefile.am | 2 ++ src/Makefile.legacy | 7 ++-- src/debug.h | 66 ++++++++++++++++++------------------ src/httpget.c | 70 ++++++++++++++++++++++++++++++--------- src/icy.c | 30 +++++++++++++++++ src/icy.h | 26 +++++++++++++++ src/mpg123.c | 5 +++ src/readers.c | 81 ++++++++++++++++++++++++++++++++++++++++++++- src/stringbuf.c | 6 ++++ src/stringbuf.h | 1 + 11 files changed, 242 insertions(+), 54 deletions(-) create mode 100644 src/icy.c create mode 100644 src/icy.h diff --git a/scripts/debugdef.pl b/scripts/debugdef.pl index 199c212d..97d8779d 100755 --- a/scripts/debugdef.pl +++ b/scripts/debugdef.pl @@ -57,7 +57,7 @@ sub printdefs unshift(@args, '') if(@args); print ' #define '.$type.($i > 1 ? ($i-1) : '').'(s'; print join(', ', @args).') '; - if($forreal){ print 'fprintf(stderr, "[" __FILE__ ":%i] '.$type.': " s "\n", __LINE__'.join(', ', @args).")\n"; } + if($forreal){ print 'fprintf(stderr, "[" __FILE__ ":%i] '.$type.': " s "\n", __LINE__'.join(', ', @args).");\n"; } else{ print "{}\n"; } } } diff --git a/src/Makefile.am b/src/Makefile.am index 63d81eaf..b2ec1f81 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -32,6 +32,8 @@ mpg123_SOURCES = \ getlopt.h \ httpget.c \ huffman.h \ + icy.c \ + icy.h \ id3.c \ id3.h \ genre.h \ diff --git a/src/Makefile.legacy b/src/Makefile.legacy index 72e11890..b76340ce 100644 --- a/src/Makefile.legacy +++ b/src/Makefile.legacy @@ -610,12 +610,12 @@ generic: mpg123-make: @ $(MAKE) BINNAME=mpg123 mpg123 -mpg123: mpg123.o playlist.o stringbuf.o common.o id3.o $(OBJECTS) decode_2to1.o decode_4to1.o \ +mpg123: mpg123.o playlist.o stringbuf.o common.o id3.o icy.o $(OBJECTS) decode_2to1.o decode_4to1.o \ tabinit.o audio.o layer1.o layer2.o layer3.o buffer.o \ getlopt.o httpget.o xfermem.o equalizer.o \ decode_ntom.o $(MAKEFILE) wav.o readers.o getbits.o \ control_generic.o - $(CC) $(CFLAGS) $(LDFLAGS) mpg123.o playlist.o stringbuf.o tabinit.o common.o id3.o layer1.o \ + $(CC) $(CFLAGS) $(LDFLAGS) mpg123.o playlist.o stringbuf.o tabinit.o common.o id3.o icy.o layer1.o \ layer2.o layer3.o audio.o buffer.o decode_2to1.o equalizer.o \ decode_4to1.o getlopt.o httpget.o xfermem.o decode_ntom.o \ wav.o readers.o getbits.o control_generic.o \ @@ -653,7 +653,7 @@ buffer.o: mpg123.h xfermem.h buffer.h debug.h config.h getbits.o: common.h mpg123.h debug.h config.h tabinit.o: mpg123.h audio.h debug.h config.h getlopt.o: getlopt.h debug.h config.h -httpget.o: mpg123.h debug.h config.h +httpget.o: mpg123.h debug.h config.h icy.h stringbuf.h dct64.o: mpg123.h debug.h config.h dct64_i386.o: mpg123.h debug.h config.h xfermem.o: xfermem.h debug.h config.h @@ -664,6 +664,7 @@ term.o: mpg123.h buffer.h term.h common.h debug.h config.h playlist.o: mpg123.h term.h getlopt.h debug.h config.h stringbuf.h stringbuf.o: stringbuf.h config.h debug.h id3.o: config.h mpg123.h stringbuf.h genre.h id3.h debug.h common.h +icy.o: icy.h stringbuf.h control_generic.o: config.h mpg123.h common.h debug.h layer3.h diff --git a/src/debug.h b/src/debug.h index 9b8ab116..943880b9 100644 --- a/src/debug.h +++ b/src/debug.h @@ -26,17 +26,17 @@ #ifdef DEBUG #include - #define debug(s) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__) - #define debug1(s, a) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a) - #define debug2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b) - #define debug3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c) - #define debug4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d) - #define debug5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e) - #define debug6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f) - #define debug7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g) - #define debug8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h) - #define debug9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i) - #define debug10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j) + #define debug(s) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__); + #define debug1(s, a) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a); + #define debug2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b); + #define debug3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c); + #define debug4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d); + #define debug5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e); + #define debug6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f); + #define debug7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g); + #define debug8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h); + #define debug9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i); + #define debug10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j); #else #define debug(s) {} #define debug1(s, a) {} @@ -52,27 +52,27 @@ #endif /* warning macros also here... */ - #define warning(s) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__) - #define warning1(s, a) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a) - #define warning2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b) - #define warning3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c) - #define warning4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d) - #define warning5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e) - #define warning6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f) - #define warning7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g) - #define warning8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h) - #define warning9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i) - #define warning10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j) + #define warning(s) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__); + #define warning1(s, a) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a); + #define warning2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b); + #define warning3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c); + #define warning4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d); + #define warning5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e); + #define warning6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f); + #define warning7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g); + #define warning8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h); + #define warning9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i); + #define warning10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j); /* error macros also here... */ - #define error(s) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__) - #define error1(s, a) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a) - #define error2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b) - #define error3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c) - #define error4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d) - #define error5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e) - #define error6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f) - #define error7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g) - #define error8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h) - #define error9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i) - #define error10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j) + #define error(s) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__); + #define error1(s, a) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a); + #define error2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b); + #define error3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c); + #define error4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d); + #define error5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e); + #define error6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f); + #define error7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g); + #define error8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h); + #define error9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i); + #define error10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j); diff --git a/src/httpget.c b/src/httpget.c index 321a6384..244fd98a 100644 --- a/src/httpget.c +++ b/src/httpget.c @@ -58,6 +58,8 @@ #include "config.h" #include "mpg123.h" #include "debug.h" +#include "stringbuf.h" +#include "icy.h" #ifndef INADDR_NONE #define INADDR_NONE 0xffffffff @@ -207,6 +209,29 @@ char *url2hostport (char *url, char **hname, unsigned long *hip, unsigned int *p return (cptr); } +char* get_header_val(const char *hname, char* response, size_t *length) +{ + char *tmp = NULL; + size_t len = 0; + size_t prelen = strlen(hname); + /* if header name found, next char is at least something, so just check for : */ + if(!strncasecmp(hname, response, prelen) && (response[prelen] == ':')) + { + ++prelen; + if((tmp = strchr(response, '\r')) != NULL ) tmp[0] = 0; + if((tmp = strchr(response, '\n')) != NULL ) tmp[0] = 0; + len = strlen(response)-prelen; + tmp = response+prelen; + while(len && ((tmp[0] == ' ') || (tmp[0] == '\t'))) + { + ++tmp; + --len; + } + } + *length = len; + return tmp; +} + char *proxyurl = NULL; unsigned long proxyip = 0; unsigned int proxyport; @@ -215,6 +240,9 @@ unsigned int proxyport; /* #define CONN_HEAD "Connection: close\r\n" */ #define CONN_HEAD "" +/* shoutcsast meta data: 1=on, 0=off */ +#define ACCEPT_ICY_META "Icy-MetaData: 0\r\n" + char *httpauth = NULL; char *httpauth1 = NULL; @@ -320,9 +348,10 @@ int http_open (char* url, char** content_type) * ACCEPT_HEAD strlen(ACCEPT_HEAD) * "Authorization: Basic \r\n" 23 * "\r\n" 2 + * ... plus the other predefined header lines */ linelengthbase = 62 + strlen(PACKAGE_NAME) + strlen(PACKAGE_VERSION) - + strlen(ACCEPT_HEAD) + strlen(CONN_HEAD); + + strlen(ACCEPT_HEAD) + strlen(CONN_HEAD) + strlen(ACCEPT_ICY_META); if(httpauth) { tmp = (strlen(httpauth) + 1) * 4; @@ -482,6 +511,7 @@ int http_open (char* url, char** content_type) } */ strcat (request, ACCEPT_HEAD); strcat (request, CONN_HEAD); + strcat (request, ACCEPT_ICY_META); server.sin_family = AF_INET; server.sin_port = htons(myport); server.sin_addr.s_addr = myip; @@ -622,24 +652,14 @@ int http_open (char* url, char** content_type) } else { + char *tmp; + size_t len; /* watch out for content type */ - debug1("searching for content-type... %s", response); - if(!strncasecmp("content-type:", response, 13)) + debug1("searching for header values... %s", response); + if((tmp = get_header_val("content-type", response, &len))) { if(content_type != NULL) { - char *tmp = NULL; - size_t len = 0; - - if((tmp = strchr(response, '\r')) != NULL ) tmp[0] = 0; - if((tmp = strchr(response, '\n')) != NULL ) tmp[0] = 0; - len = strlen(response)-13; - tmp = response+13; - while(len && ((tmp[0] == ' ') || (tmp[0] == '\t'))) - { - ++tmp; - --len; - } if(len) { if(*content_type != NULL) free(*content_type); @@ -650,10 +670,28 @@ int http_open (char* url, char** content_type) (*content_type)[len] = 0; debug1("got type %s", *content_type); } - else fprintf(stderr, "Error: canno allocate memory for content type!\n"); + else error("cannot allocate memory for content type!"); } } } + /* watch out for icy-name */ + else if((tmp = get_header_val("icy-name", response, &len))) + { + if(set_stringbuf(&icy.name, tmp)) debug1("got icy-name %s", icy.name.p) + else error1("unable to set icy name to %s!", tmp) + } + /* watch out for icy-url */ + else if((tmp = get_header_val("icy-url", response, &len))) + { + if(set_stringbuf(&icy.url, tmp)) debug1("got icy-url %s", icy.name.p) + else error1("unable to set icy url to %s!", tmp) + } + /* watch out for icy-metaint */ + else if((tmp = get_header_val("icy-metaint", response, &len))) + { + icy.interval = atoi(tmp); + debug1("got icy-metaint %li", (long int)icy.interval); + } } } while (response[0] != '\r' && response[0] != '\n'); } while (relocate && purl[0] && numrelocs++ < HTTP_MAX_RELOCATIONS); diff --git a/src/icy.c b/src/icy.c new file mode 100644 index 00000000..3be9c861 --- /dev/null +++ b/src/icy.c @@ -0,0 +1,30 @@ +#include "icy.h" +#include + +struct icy_meta icy; + +void init_icy() +{ + init_stringbuf(&icy.name); + init_stringbuf(&icy.url); + icy.data = NULL; + icy.interval = 0; + icy.next = 0; + icy.changed = 0; +} + +void clear_icy() +{ + /* if pointers are non-null, they have some memory */ + free_stringbuf(&icy.name); + free_stringbuf(&icy.url); + free(icy.data); + init_icy(); +} + +void set_data(char* new_data) +{ + if(icy.data) free(icy.data); + icy.data = new_data; + icy.changed = 1; +} diff --git a/src/icy.h b/src/icy.h new file mode 100644 index 00000000..b27fe4bb --- /dev/null +++ b/src/icy.h @@ -0,0 +1,26 @@ +/* + icy: support for SHOUTcast ICY meta info, an attempt to keep it organized + + copyright 2006 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.de + initially written by Thomas Orgis and modelled after patch by Honza +*/ + +#include +#include "stringbuf.h" + +struct icy_meta +{ + struct stringbuf name; + struct stringbuf url; + char* data; + off_t interval; + off_t next; + int changed; +}; + +/* bah, just make it global... why bother with all that poiner passing to "methods" when there will be only one? */ +extern struct icy_meta icy; + +void init_icy(); +void clear_icy(); diff --git a/src/mpg123.c b/src/mpg123.c index 2f8a076b..e478dc36 100644 --- a/src/mpg123.c +++ b/src/mpg123.c @@ -36,6 +36,7 @@ #endif #include "playlist.h" #include "id3.h" +#include "icy.h" static void usage(int err); static void want_usage(char* arg); @@ -814,12 +815,15 @@ int main(int argc, char *argv[]) if(param.remote) { int ret; init_id3(); + init_icy(); ret = control_generic(&fr); + clear_icy(); exit_id3(); safe_exit(ret); } #endif + init_icy(); init_id3(); /* prepare id3 memory */ while ((fname = get_next_file())) { char *dirname, *filename; @@ -1025,6 +1029,7 @@ tc_hack: #endif } } /* end of loop over input files */ + clear_icy(); exit_id3(); /* free id3 memory */ #ifndef NOXFERMEM if (param.usebuffer) { diff --git a/src/readers.c b/src/readers.c index f44428ec..15314660 100644 --- a/src/readers.c +++ b/src/readers.c @@ -17,11 +17,87 @@ #include "debug.h" #include "buffer.h" #include "common.h" +#include "icy.h" static off_t get_fileinfo(struct reader *,char *buf); +static ssize_t icy_fullread(struct reader *rds,unsigned char *buf, ssize_t count); +static ssize_t plain_fullread(struct reader *rds,unsigned char *buf, ssize_t count); +ssize_t (*fullread)(struct reader *,unsigned char *, ssize_t) = plain_fullread; + +/* stream based operation with icy meta data*/ +static ssize_t icy_fullread(struct reader *rds,unsigned char *buf, ssize_t count) +{ + ssize_t ret,cnt; + cnt = 0; + + /* + We check against READER_ID3TAG instead of rds->filelen >= 0 because if we got the ID3 TAG we know we have the end of the file. + If we don't have an ID3 TAG, then it is possible the file has grown since we started playing, so we want to keep reading from it if possible. + */ + if((rds->flags & READER_ID3TAG) && rds->filepos + count > rds->filelen) count = rds->filelen - rds->filepos; + + while(cnt < count) + { + /* all icy code is inside this if block, everything else is the plain fullread we know */ + if(icy.interval && (rds->filepos+count > icy.next)) + { + char temp_buff; + int meta_size; + ssize_t cut_pos; + + /* we are near icy-metaint boundary, read up to the boundary */ + cut_pos = icy.next-rds->filepos; + ret = read(rds->filept,buf,cut_pos); + if(ret < 0) return ret; + + rds->filepos += ret; + cnt += ret; + + /* now off to read icy data */ + + /* one byte icy-meta size (must be multiplied by 16 to get icy-meta length) */ + ret = read(rds->filept,&temp_buff,1); + if(ret < 0) return ret; + if(ret == 0) break; + + rds->filepos += ret; /* 1... */ + + if((meta_size = (unsigned int) temp_buff * 16)) + { + /* we have got some metadata */ + char *meta_buff; + meta_buff = (char*) malloc(meta_size+1); + meta_buff[meta_size] = 0; /* string paranoia */ + if(meta_buff != NULL) + { + ret = read(rds->filept,meta_buff,meta_size); + if(ret < 0) return ret; + + rds->filepos += ret; + + if(icy.data) free(icy.data); + icy.data = meta_buff; + icy.changed = 1; + debug2("icy-meta: %s size: %d bytes", icy.data, meta_size); + } + else error("cannot allocate memory for meta_buff!"); + } + icy.next = rds->filepos+icy.interval; + } + + ret = read(rds->filept,buf+cnt,count-cnt); + if(ret < 0) return ret; + if(ret == 0) break; + + rds->filepos += ret; + cnt += ret; + } + return cnt; +} + /* stream based operation */ -static ssize_t fullread(struct reader *rds,unsigned char *buf, ssize_t count) +static ssize_t plain_fullread(struct reader *rds,unsigned char *buf, ssize_t count) { ssize_t ret,cnt=0; @@ -275,6 +351,7 @@ int open_stream(char *bs_filenam,int fd) int filept_opened = 1; int filept; /* descriptor of opened file/stream */ + clear_icy(); if(!bs_filenam) /* no file to open, got a descriptor (stdin) */ { if(fd < 0) /* special: read from stdin */ @@ -328,6 +405,8 @@ int open_stream(char *bs_filenam,int fd) } } + if(icy.interval) fullread = icy_fullread; +fullread = icy_fullread; /* id3tag printing moved to read_frame */ return filept; } diff --git a/src/stringbuf.c b/src/stringbuf.c index 704b4aa1..02421439 100644 --- a/src/stringbuf.c +++ b/src/stringbuf.c @@ -82,3 +82,9 @@ int add_to_stringbuf(struct stringbuf* sb, char* stuff) } return 1; } + +int set_stringbuf(struct stringbuf* sb, char* stuff) +{ + sb->fill = 0; + return add_to_stringbuf(sb, stuff); +} diff --git a/src/stringbuf.h b/src/stringbuf.h index 3979891a..e114c8a5 100644 --- a/src/stringbuf.h +++ b/src/stringbuf.h @@ -23,5 +23,6 @@ void free_stringbuf(struct stringbuf* sb); int resize_stringbuf(struct stringbuf* sb, size_t new); int copy_stringbuf(struct stringbuf* from, struct stringbuf* to); int add_to_stringbuf(struct stringbuf* sb, char* stuff); +int set_stringbuf(struct stringbuf* sb, char* stuff); #endif