1
0
mirror of http://mpg123.de/trunk/.git synced 2025-08-06 10:02:38 +03:00

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
This commit is contained in:
thor
2006-12-22 02:28:31 +00:00
parent 8e4b98616b
commit fbf28eee49
11 changed files with 242 additions and 54 deletions

View File

@@ -57,7 +57,7 @@ sub printdefs
unshift(@args, '') if(@args); unshift(@args, '') if(@args);
print ' #define '.$type.($i > 1 ? ($i-1) : '').'(s'; print ' #define '.$type.($i > 1 ? ($i-1) : '').'(s';
print join(', ', @args).') '; 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"; } else{ print "{}\n"; }
} }
} }

View File

@@ -32,6 +32,8 @@ mpg123_SOURCES = \
getlopt.h \ getlopt.h \
httpget.c \ httpget.c \
huffman.h \ huffman.h \
icy.c \
icy.h \
id3.c \ id3.c \
id3.h \ id3.h \
genre.h \ genre.h \

View File

@@ -610,12 +610,12 @@ generic:
mpg123-make: mpg123-make:
@ $(MAKE) BINNAME=mpg123 mpg123 @ $(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 \ tabinit.o audio.o layer1.o layer2.o layer3.o buffer.o \
getlopt.o httpget.o xfermem.o equalizer.o \ getlopt.o httpget.o xfermem.o equalizer.o \
decode_ntom.o $(MAKEFILE) wav.o readers.o getbits.o \ decode_ntom.o $(MAKEFILE) wav.o readers.o getbits.o \
control_generic.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 \ 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 \ decode_4to1.o getlopt.o httpget.o xfermem.o decode_ntom.o \
wav.o readers.o getbits.o control_generic.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 getbits.o: common.h mpg123.h debug.h config.h
tabinit.o: mpg123.h audio.h debug.h config.h tabinit.o: mpg123.h audio.h debug.h config.h
getlopt.o: getlopt.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.o: mpg123.h debug.h config.h
dct64_i386.o: mpg123.h debug.h config.h dct64_i386.o: mpg123.h debug.h config.h
xfermem.o: xfermem.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 playlist.o: mpg123.h term.h getlopt.h debug.h config.h stringbuf.h
stringbuf.o: stringbuf.h config.h debug.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 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 control_generic.o: config.h mpg123.h common.h debug.h layer3.h

View File

@@ -26,17 +26,17 @@
#ifdef DEBUG #ifdef DEBUG
#include <stdio.h> #include <stdio.h>
#define debug(s) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__) #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 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 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 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 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 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 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 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 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 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 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 #else
#define debug(s) {} #define debug(s) {}
#define debug1(s, a) {} #define debug1(s, a) {}
@@ -52,27 +52,27 @@
#endif #endif
/* warning macros also here... */ /* warning macros also here... */
#define warning(s) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__) #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 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 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 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 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 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 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 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 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 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 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... */ /* error macros also here... */
#define error(s) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__) #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 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 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 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 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 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 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 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 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 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 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);

View File

@@ -58,6 +58,8 @@
#include "config.h" #include "config.h"
#include "mpg123.h" #include "mpg123.h"
#include "debug.h" #include "debug.h"
#include "stringbuf.h"
#include "icy.h"
#ifndef INADDR_NONE #ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff #define INADDR_NONE 0xffffffff
@@ -207,6 +209,29 @@ char *url2hostport (char *url, char **hname, unsigned long *hip, unsigned int *p
return (cptr); 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; char *proxyurl = NULL;
unsigned long proxyip = 0; unsigned long proxyip = 0;
unsigned int proxyport; unsigned int proxyport;
@@ -215,6 +240,9 @@ unsigned int proxyport;
/* #define CONN_HEAD "Connection: close\r\n" */ /* #define CONN_HEAD "Connection: close\r\n" */
#define CONN_HEAD "" #define CONN_HEAD ""
/* shoutcsast meta data: 1=on, 0=off */
#define ACCEPT_ICY_META "Icy-MetaData: 0\r\n"
char *httpauth = NULL; char *httpauth = NULL;
char *httpauth1 = NULL; char *httpauth1 = NULL;
@@ -320,9 +348,10 @@ int http_open (char* url, char** content_type)
* ACCEPT_HEAD strlen(ACCEPT_HEAD) * ACCEPT_HEAD strlen(ACCEPT_HEAD)
* "Authorization: Basic \r\n" 23 * "Authorization: Basic \r\n" 23
* "\r\n" 2 * "\r\n" 2
* ... plus the other predefined header lines
*/ */
linelengthbase = 62 + strlen(PACKAGE_NAME) + strlen(PACKAGE_VERSION) 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) { if(httpauth) {
tmp = (strlen(httpauth) + 1) * 4; tmp = (strlen(httpauth) + 1) * 4;
@@ -482,6 +511,7 @@ int http_open (char* url, char** content_type)
} */ } */
strcat (request, ACCEPT_HEAD); strcat (request, ACCEPT_HEAD);
strcat (request, CONN_HEAD); strcat (request, CONN_HEAD);
strcat (request, ACCEPT_ICY_META);
server.sin_family = AF_INET; server.sin_family = AF_INET;
server.sin_port = htons(myport); server.sin_port = htons(myport);
server.sin_addr.s_addr = myip; server.sin_addr.s_addr = myip;
@@ -622,24 +652,14 @@ int http_open (char* url, char** content_type)
} }
else else
{ {
char *tmp;
size_t len;
/* watch out for content type */ /* watch out for content type */
debug1("searching for content-type... %s", response); debug1("searching for header values... %s", response);
if(!strncasecmp("content-type:", response, 13)) if((tmp = get_header_val("content-type", response, &len)))
{ {
if(content_type != NULL) 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(len)
{ {
if(*content_type != NULL) free(*content_type); if(*content_type != NULL) free(*content_type);
@@ -650,10 +670,28 @@ int http_open (char* url, char** content_type)
(*content_type)[len] = 0; (*content_type)[len] = 0;
debug1("got type %s", *content_type); 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 (response[0] != '\r' && response[0] != '\n');
} while (relocate && purl[0] && numrelocs++ < HTTP_MAX_RELOCATIONS); } while (relocate && purl[0] && numrelocs++ < HTTP_MAX_RELOCATIONS);

30
src/icy.c Normal file
View File

@@ -0,0 +1,30 @@
#include "icy.h"
#include <stdlib.h>
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;
}

26
src/icy.h Normal file
View File

@@ -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 <sys/types.h>
#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();

View File

@@ -36,6 +36,7 @@
#endif #endif
#include "playlist.h" #include "playlist.h"
#include "id3.h" #include "id3.h"
#include "icy.h"
static void usage(int err); static void usage(int err);
static void want_usage(char* arg); static void want_usage(char* arg);
@@ -814,12 +815,15 @@ int main(int argc, char *argv[])
if(param.remote) { if(param.remote) {
int ret; int ret;
init_id3(); init_id3();
init_icy();
ret = control_generic(&fr); ret = control_generic(&fr);
clear_icy();
exit_id3(); exit_id3();
safe_exit(ret); safe_exit(ret);
} }
#endif #endif
init_icy();
init_id3(); /* prepare id3 memory */ init_id3(); /* prepare id3 memory */
while ((fname = get_next_file())) { while ((fname = get_next_file())) {
char *dirname, *filename; char *dirname, *filename;
@@ -1025,6 +1029,7 @@ tc_hack:
#endif #endif
} }
} /* end of loop over input files */ } /* end of loop over input files */
clear_icy();
exit_id3(); /* free id3 memory */ exit_id3(); /* free id3 memory */
#ifndef NOXFERMEM #ifndef NOXFERMEM
if (param.usebuffer) { if (param.usebuffer) {

View File

@@ -17,11 +17,87 @@
#include "debug.h" #include "debug.h"
#include "buffer.h" #include "buffer.h"
#include "common.h" #include "common.h"
#include "icy.h"
static off_t get_fileinfo(struct reader *,char *buf); 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 */ /* 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; ssize_t ret,cnt=0;
@@ -275,6 +351,7 @@ int open_stream(char *bs_filenam,int fd)
int filept_opened = 1; int filept_opened = 1;
int filept; /* descriptor of opened file/stream */ int filept; /* descriptor of opened file/stream */
clear_icy();
if(!bs_filenam) /* no file to open, got a descriptor (stdin) */ if(!bs_filenam) /* no file to open, got a descriptor (stdin) */
{ {
if(fd < 0) /* special: read from 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 */ /* id3tag printing moved to read_frame */
return filept; return filept;
} }

View File

@@ -82,3 +82,9 @@ int add_to_stringbuf(struct stringbuf* sb, char* stuff)
} }
return 1; return 1;
} }
int set_stringbuf(struct stringbuf* sb, char* stuff)
{
sb->fill = 0;
return add_to_stringbuf(sb, stuff);
}

View File

@@ -23,5 +23,6 @@ void free_stringbuf(struct stringbuf* sb);
int resize_stringbuf(struct stringbuf* sb, size_t new); int resize_stringbuf(struct stringbuf* sb, size_t new);
int copy_stringbuf(struct stringbuf* from, struct stringbuf* to); int copy_stringbuf(struct stringbuf* from, struct stringbuf* to);
int add_to_stringbuf(struct stringbuf* sb, char* stuff); int add_to_stringbuf(struct stringbuf* sb, char* stuff);
int set_stringbuf(struct stringbuf* sb, char* stuff);
#endif #endif