⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readers.c

📁 mips上编译过的mpg 运行正常 环境:AU12
💻 C
📖 第 1 页 / 共 2 页
字号:
	free(bc->last);	cur->next = NULL;	bc->last  = cur;}#endif/* Append a new buffer and copy content to it. */static int bc_add(struct bufferchain *bc, unsigned char *data, ssize_t size){	int ret = 0;	if((ret = bc_append(bc, size)) == 0)	memcpy(bc->last->data, data, size);	return ret;}/* Give some data, advancing position but not forgetting yet. */static ssize_t bc_give(struct bufferchain *bc, unsigned char *out, size_t size){	struct buffy *b = bc->first;	ssize_t gotcount = 0;	ssize_t offset = 0;	if(bc->size - bc->pos < size)	{		debug3("hit end, back to beginning (%li - %li < %li)", (long)bc->size, (long)bc->pos, (long)size);		/* go back to firstpos, undo the previous reads */		bc->pos = bc->firstpos;		return READER_MORE;	}	/* find the current buffer */	while(b != NULL && (offset + b->size) <= bc->pos)	{		offset += b->size;		b = b->next;	}	/* now start copying from there */	while(gotcount < size && (b != NULL))	{		ssize_t loff = bc->pos - offset;		ssize_t chunk = size - gotcount; /* amount of bytes to get from here... */		if(chunk > b->size - loff) chunk = b->size - loff;		debug3("copying %liB from %p+%li",(long)chunk, b->data, (long)loff);		memcpy(out+gotcount, b->data+loff, chunk);		gotcount += chunk;		bc->pos  += chunk;		offset += b->size;		b = b->next;	}	debug2("got %li bytes, pos advanced to %li", (long)gotcount, (long)bc->pos);	return gotcount;}/* Skip some bytes and return the new position.   The buffers are still there, just the read pointer is moved! */static ssize_t bc_skip(struct bufferchain *bc, ssize_t count){	if(count >= 0)	{		if(bc->size - bc->pos < count) return READER_MORE;		else return bc->pos += count;	}	else return READER_ERROR;}static ssize_t bc_seekback(struct bufferchain *bc, ssize_t count){	if(count >= 0 && count <= bc->pos) return bc->pos -= count;	else return READER_ERROR;}/* Throw away buffies that we passed. */static void bc_forget(struct bufferchain *bc){	struct buffy *b = bc->first;	/* free all buffers that are def'n'tly outdated */	/* we have buffers until filepos... delete all buffers fully below it */	if(b) debug2("bc_forget: block %lu pos %lu", (unsigned long)b->size, (unsigned long)bc->pos);	else debug("forget with nothing there!");	while(b != NULL && bc->pos >= b->size)	{		struct buffy *n = b->next; /* != NULL or this is indeed the end and the last cycle anyway */		if(n == NULL) bc->last = NULL; /* Going to delete the last buffy... */		bc->fileoff += b->size;		bc->pos  -= b->size;		bc->size -= b->size;		debug5("bc_forget: forgot %p with %lu, pos=%li, size=%li, fileoff=%li", (void*)b->data, (long)b->size, (long)bc->pos,  (long)bc->size, (long)bc->fileoff);		free(b->data);		free(b);		b = n;	}	bc->first = b;	bc->firstpos = bc->pos;}/* reader for input via manually provided buffers */static int feed_init(mpg123_handle *fr){	bc_init(&fr->rdat.buffer);	fr->rdat.filelen = 0;	fr->rdat.filepos = 0;	fr->rdat.flags |= READER_BUFFERED;	return 0;}/* externally called function, returns 0 on success, -1 on error */int feed_more(mpg123_handle *fr, unsigned char *in, long count){	int ret = 0;	debug("feed_more");	if((ret = bc_add(&fr->rdat.buffer, in, count)) != 0)	{		ret = READER_ERROR;		if(NOQUIET) error1("Failed to add buffer, return: %i", ret);	}	else /* Not talking about filelen... that stays at 0. */	debug3("feed_more: %p %luB bufsize=%lu", fr->rdat.buffer.last->data,		(unsigned long)fr->rdat.buffer.last->size, (unsigned long)fr->rdat.buffer.size);	return ret;}static ssize_t feed_read(mpg123_handle *fr, unsigned char *out, ssize_t count){	ssize_t gotcount = bc_give(&fr->rdat.buffer, out, count);	if(gotcount >= 0 && gotcount != count) return READER_ERROR;	else return gotcount;}/* returns reached position... negative ones are bad... */static off_t feed_skip_bytes(mpg123_handle *fr,off_t len){	return fr->rdat.buffer.fileoff+bc_skip(&fr->rdat.buffer, (ssize_t)len);}static int feed_back_bytes(mpg123_handle *fr, off_t bytes){	if(bytes >=0)	return bc_seekback(&fr->rdat.buffer, (ssize_t)bytes) >= 0 ? 0 : READER_ERROR;	else	return feed_skip_bytes(fr, -bytes) >= 0 ? 0 : READER_ERROR;}static int buffered_seek_frame(mpg123_handle *fr, off_t num){ return READER_ERROR; }/* Not just for feed reader, also for self-feeding buffered reader. */static void buffered_forget(mpg123_handle *fr){	bc_forget(&fr->rdat.buffer);	fr->rdat.filepos = fr->rdat.buffer.fileoff + fr->rdat.buffer.pos;}off_t feed_set_pos(mpg123_handle *fr, off_t pos){	struct bufferchain *bc = &fr->rdat.buffer;	if(pos >= bc->fileoff && pos-bc->fileoff < bc->size)	{ /* We have the position! */		bc->pos = (ssize_t)(pos - bc->fileoff);		return pos+bc->size; /* Next input after end of buffer... */	}	else	{ /* I expect to get the specific position on next feed. Forget what I have now. */		bc_reset(bc);		bc->fileoff = pos;		return pos; /* Next input from exactly that position. */	}}/* The specific stuff for buffered stream reader. *//* Let's work in nice 4K blocks, that may be nicely reusable (by malloc(), even). */#define BUFFBLOCK 4096static ssize_t buffered_fullread(mpg123_handle *fr, unsigned char *out, ssize_t count){	struct bufferchain *bc = &fr->rdat.buffer;	ssize_t gotcount;	if(bc->size - bc->pos < count)	{ /* Add more stuff to buffer. If hitting end of file, adjust count. */		unsigned char readbuf[BUFFBLOCK];		ssize_t need = count - (bc->size-bc->pos);		while(need>0)		{			int ret;			ssize_t got = fr->rdat.fullread(fr, readbuf, BUFFBLOCK);			if(got < 0)			{				if(NOQUIET) error("buffer reading");				return READER_ERROR;			}			debug1("buffered_fullread: buffering %li bytes from stream (if > 0)", (long)got);			if(got > 0 && (ret=bc_add(bc, readbuf, got)) != 0)			{				if(NOQUIET) error1("unable to add to chain, return: %i", ret);				return READER_ERROR;			}			need -= got; /* May underflow here... */			if(got < BUFFBLOCK) /* That naturally catches got == 0, too. */			{				if(VERBOSE3) fprintf(stderr, "Note: Input data end.\n");				break; /* End. */			}		}		if(bc->size - bc->pos < count)		count = bc->size - bc->pos; /* We want only what we got. */	}	gotcount = bc_give(bc, out, count);	debug2("wanted %li, got %li", (long)count, (long)gotcount);	if(gotcount != count){ if(NOQUIET) error("gotcount != count"); return READER_ERROR; }	else return gotcount;}/***************************************************************** * read frame helper */#define bugger_off { mh->err = MPG123_NO_READER; return MPG123_ERR; }int bad_init(mpg123_handle *mh) bugger_offvoid bad_close(mpg123_handle *mh){}ssize_t bad_fullread(mpg123_handle *mh, unsigned char *data, ssize_t count) bugger_offint bad_head_read(mpg123_handle *mh, unsigned long *newhead) bugger_offint bad_head_shift(mpg123_handle *mh, unsigned long *head) bugger_offoff_t bad_skip_bytes(mpg123_handle *mh, off_t len) bugger_offint bad_read_frame_body(mpg123_handle *mh, unsigned char *data, int size) bugger_offint bad_back_bytes(mpg123_handle *mh, off_t bytes) bugger_offint bad_seek_frame(mpg123_handle *mh, off_t num) bugger_offoff_t bad_tell(mpg123_handle *mh) bugger_offvoid bad_rewind(mpg123_handle *mh){}#undef bugger_off#define READER_STREAM 0#define READER_ICY_STREAM 1#define READER_FEED       2#define READER_BUF_STREAM 3#define READER_BUF_ICY_STREAM 4struct reader readers[] ={	{ /* READER_STREAM */		default_init,		stream_close,		plain_fullread,		generic_head_read,		generic_head_shift,		stream_skip_bytes,		generic_read_frame_body,		stream_back_bytes,		stream_seek_frame,		generic_tell,		stream_rewind,		NULL	} ,	{ /* READER_ICY_STREAM */		default_init,		stream_close,		icy_fullread,		generic_head_read,		generic_head_shift,		stream_skip_bytes,		generic_read_frame_body,		stream_back_bytes,		stream_seek_frame,		generic_tell,		stream_rewind,		NULL	},	{ /* READER_FEED */		feed_init,		stream_close,		feed_read,		generic_head_read,		generic_head_shift,		feed_skip_bytes,		generic_read_frame_body,		feed_back_bytes,		buffered_seek_frame,		generic_tell,		stream_rewind,		buffered_forget	},	{ /* READER_BUF_STREAM */		default_init,		stream_close,		buffered_fullread,		generic_head_read,		generic_head_shift,		stream_skip_bytes,		generic_read_frame_body,		stream_back_bytes,		buffered_seek_frame,		generic_tell,		stream_rewind,		buffered_forget	} ,	{ /* READER_BUF_ICY_STREAM */		default_init,		stream_close,		buffered_fullread,		generic_head_read,		generic_head_shift,		stream_skip_bytes,		generic_read_frame_body,		stream_back_bytes,		buffered_seek_frame,		generic_tell,		stream_rewind,		buffered_forget	},#ifdef READ_SYSTEM	,{		system_init,		NULL,	/* filled in by system_init() */		fullread,		NULL,		NULL,		NULL,		NULL,		NULL,		NULL,		NULL,		NULL,		NULL,	}#endif};struct reader bad_reader ={	bad_init,	bad_close,	bad_fullread,	bad_head_read,	bad_head_shift,	bad_skip_bytes,	bad_read_frame_body,	bad_back_bytes,	bad_seek_frame,	bad_tell,	bad_rewind,	NULL};static int default_init(mpg123_handle *fr){#ifndef WIN32	if(fr->p.timeout > 0)	{		fcntl(fr->rdat.filept, F_SETFL, O_NONBLOCK);		fr->rdat.fdread = timeout_read;		fr->rdat.timeout_sec = fr->p.timeout;		fr->rdat.flags |= READER_NONBLOCK;	}	else#endif	fr->rdat.fdread = plain_read;	fr->rdat.read  = fr->rdat.r_read  != NULL ? fr->rdat.r_read  : posix_read;	fr->rdat.lseek = fr->rdat.r_lseek != NULL ? fr->rdat.r_lseek : posix_lseek;	fr->rdat.filelen = get_fileinfo(fr);	fr->rdat.filepos = 0;	if(fr->rdat.filelen >= 0)	{		fr->rdat.flags |= READER_SEEKABLE;		if(!strncmp((char*)fr->id3buf,"TAG",3))		{			fr->rdat.flags |= READER_ID3TAG;			fr->metaflags  |= MPG123_NEW_ID3;		}	}	/* Switch reader to a buffered one, if allowed. */	else if(fr->p.flags & MPG123_SEEKBUFFER)	{		if     (fr->rd == &readers[READER_STREAM])		{			fr->rd = &readers[READER_BUF_STREAM];			fr->rdat.fullread = plain_fullread;		}		else if(fr->rd == &readers[READER_ICY_STREAM])		{			fr->rd = &readers[READER_BUF_ICY_STREAM];			fr->rdat.fullread = icy_fullread;		}		else		{			if(NOQUIET) error("mpg123 Programmer's fault: invalid reader");			return -1;		}		bc_init(&fr->rdat.buffer);		fr->rdat.filelen = 0; /* We carry the offset, but never know how big the stream is. */		fr->rdat.flags |= READER_BUFFERED;	}	return 0;}void open_bad(mpg123_handle *mh){	clear_icy(&mh->icy);	mh->rd = &bad_reader;	mh->rdat.flags = 0;	bc_init(&mh->rdat.buffer);}int open_feed(mpg123_handle *fr){	debug("feed reader");	clear_icy(&fr->icy);	fr->rd = &readers[READER_FEED];	fr->rdat.flags = 0;	if(fr->rd->init(fr) < 0) return -1;	return 0;}int open_stream(mpg123_handle *fr, char *bs_filenam, int fd){	int filept_opened = 1;	int filept; /* descriptor of opened file/stream */	clear_icy(&fr->icy); /* can be done inside frame_clear ...? */	if(!bs_filenam) /* no file to open, got a descriptor (stdin) */	{		filept = fd;		filept_opened = 0; /* and don't try to close it... */	}	#ifndef O_BINARY	#define O_BINARY (0)	#endif	else if((filept = open(bs_filenam, O_RDONLY|O_BINARY)) < 0) /* a plain old file to open... */	{		if(NOQUIET) error2("Cannot file %s: %s", bs_filenam, strerror(errno));		fr->err = MPG123_BAD_FILE;		return filept; /* error... */	}	/* now we have something behind filept and can init the reader */	fr->rdat.filelen = -1;	fr->rdat.filept  = filept;	fr->rdat.flags = 0;	if(filept_opened)	fr->rdat.flags |= READER_FD_OPENED;	if(fr->p.icy_interval > 0)	{		debug("ICY reader");		fr->icy.interval = fr->p.icy_interval;		fr->icy.next = fr->icy.interval;		fr->rd = &readers[READER_ICY_STREAM];	}	else	{		fr->rd = &readers[READER_STREAM];		debug("stream reader");	}	if(fr->rd->init(fr) < 0) return -1;	return MPG123_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -