ReactOS 0.4.15-dev-7842-g558ab78
readers.c File Reference
#include "mpg123lib_intern.h"
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "compat.h"
#include "debug.h"
Include dependency graph for readers.c:

Go to the source code of this file.

Macros

#define bugger_off   { mh->err = MPG123_NO_READER; return MPG123_ERR; }
 
#define READER_STREAM   0
 
#define READER_ICY_STREAM   1
 
#define READER_FEED   2
 
#define READER_BUF_STREAM   3
 
#define READER_BUF_ICY_STREAM   4
 
#define O_BINARY   (0)
 

Functions

static int default_init (mpg123_handle *fr)
 
static off_t get_fileinfo (mpg123_handle *)
 
static ssize_t posix_read (int fd, void *buf, size_t count)
 
static off_t posix_lseek (int fd, off_t offset, int whence)
 
static off_t nix_lseek (int fd, off_t offset, int whence)
 
static ssize_t plain_fullread (mpg123_handle *fr, unsigned char *buf, ssize_t count)
 
static off_t io_seek (struct reader_data *rdat, off_t offset, int whence)
 
static ssize_t io_read (struct reader_data *rdat, void *buf, size_t count)
 
static void bc_init (struct bufferchain *bc)
 
static void bc_reset (struct bufferchain *bc)
 
static int bc_append (struct bufferchain *bc, ssize_t size)
 
static int bc_add (struct bufferchain *bc, const unsigned char *data, ssize_t size)
 
static ssize_t bc_give (struct bufferchain *bc, unsigned char *out, ssize_t size)
 
static ssize_t bc_skip (struct bufferchain *bc, ssize_t count)
 
static ssize_t bc_seekback (struct bufferchain *bc, ssize_t count)
 
static void bc_forget (struct bufferchain *bc)
 
static ssize_t plain_read (mpg123_handle *fr, void *buf, size_t count)
 
static ssize_t icy_fullread (mpg123_handle *fr, unsigned char *buf, ssize_t count)
 
static off_t stream_lseek (mpg123_handle *fr, off_t pos, int whence)
 
static void stream_close (mpg123_handle *fr)
 
static int stream_seek_frame (mpg123_handle *fr, off_t newframe)
 
static int generic_head_read (mpg123_handle *fr, unsigned long *newhead)
 
static int generic_head_shift (mpg123_handle *fr, unsigned long *head)
 
static off_t stream_skip_bytes (mpg123_handle *fr, off_t len)
 
static int stream_back_bytes (mpg123_handle *fr, off_t bytes)
 
static int generic_read_frame_body (mpg123_handle *fr, unsigned char *buf, int size)
 
static off_t generic_tell (mpg123_handle *fr)
 
static void stream_rewind (mpg123_handle *fr)
 
static struct buffybuffy_new (size_t size, size_t minsize)
 
static void buffy_del (struct buffy *buf)
 
static void buffy_del_chain (struct buffy *buf)
 
void bc_prepare (struct bufferchain *bc, size_t pool_size, size_t bufblock)
 
size_t bc_fill (struct bufferchain *bc)
 
void bc_poolsize (struct bufferchain *bc, size_t pool_size, size_t bufblock)
 
void bc_cleanup (struct bufferchain *bc)
 
static struct buffybc_alloc (struct bufferchain *bc, size_t size)
 
static void bc_free (struct bufferchain *bc, struct buffy *buf)
 
static int bc_fill_pool (struct bufferchain *bc)
 
static ssize_t bc_need_more (struct bufferchain *bc)
 
static int feed_init (mpg123_handle *fr)
 
int feed_more (mpg123_handle *fr, const unsigned char *in, long count)
 
static ssize_t feed_read (mpg123_handle *fr, unsigned char *out, ssize_t count)
 
static off_t feed_skip_bytes (mpg123_handle *fr, off_t len)
 
static int feed_back_bytes (mpg123_handle *fr, off_t bytes)
 
static int feed_seek_frame (mpg123_handle *fr, off_t num)
 
static void buffered_forget (mpg123_handle *fr)
 
off_t feed_set_pos (mpg123_handle *fr, off_t pos)
 
static ssize_t buffered_fullread (mpg123_handle *fr, unsigned char *out, ssize_t count)
 
static int bad_init (mpg123_handle *mh) bugger_off static void bad_close(mpg123_handle *mh)
 
static ssize_t bad_fullread (mpg123_handle *mh, unsigned char *data, ssize_t count) bugger_off static int bad_head_read(mpg123_handle *mh
 
static ssize_t unsigned long *newhead static bugger_off int bad_head_shift (mpg123_handle *mh, unsigned long *head) bugger_off static off_t bad_skip_bytes(mpg123_handle *mh
 
static ssize_t unsigned long *newhead static bugger_off int off_t len static bugger_off int bad_read_frame_body (mpg123_handle *mh, unsigned char *data, int size) bugger_off static int bad_back_bytes(mpg123_handle *mh
 
static ssize_t unsigned long *newhead static bugger_off int off_t len static bugger_off int off_t bytes static bugger_off int bad_seek_frame (mpg123_handle *mh, off_t num) bugger_off static off_t bad_tell(mpg123_handle *mh) bugger_off static void bad_rewind(mpg123_handle *mh)
 
void open_bad (mpg123_handle *mh)
 
int open_feed (mpg123_handle *fr)
 
static int open_finish (mpg123_handle *fr)
 
int open_stream (mpg123_handle *fr, const char *bs_filenam, int fd)
 
int open_stream_handle (mpg123_handle *fr, void *iohandle)
 

Variables

static struct reader readers []
 
static struct reader bad_reader
 

Macro Definition Documentation

◆ bugger_off

#define bugger_off   { mh->err = MPG123_NO_READER; return MPG123_ERR; }

Definition at line 902 of file readers.c.

◆ O_BINARY

#define O_BINARY   (0)

◆ READER_BUF_ICY_STREAM

#define READER_BUF_ICY_STREAM   4

Definition at line 920 of file readers.c.

◆ READER_BUF_STREAM

#define READER_BUF_STREAM   3

Definition at line 919 of file readers.c.

◆ READER_FEED

#define READER_FEED   2

Definition at line 918 of file readers.c.

◆ READER_ICY_STREAM

#define READER_ICY_STREAM   1

Definition at line 917 of file readers.c.

◆ READER_STREAM

#define READER_STREAM   0

Definition at line 916 of file readers.c.

Function Documentation

◆ bad_fullread()

static ssize_t bad_fullread ( mpg123_handle mh,
unsigned char data,
ssize_t  count 
)
static

◆ bad_head_shift()

static ssize_t unsigned long *newhead static bugger_off int bad_head_shift ( mpg123_handle mh,
unsigned long head 
)
static

◆ bad_init()

static int bad_init ( mpg123_handle mh)
static

Definition at line 903 of file readers.c.

904 {}

◆ bad_read_frame_body()

static ssize_t unsigned long *newhead static bugger_off int off_t len static bugger_off int bad_read_frame_body ( mpg123_handle mh,
unsigned char data,
int  size 
)
static

◆ bad_seek_frame()

static ssize_t unsigned long *newhead static bugger_off int off_t len static bugger_off int off_t bytes static bugger_off int bad_seek_frame ( mpg123_handle mh,
off_t  num 
)
static

Definition at line 911 of file readers.c.

913 {}

◆ bc_add()

static int bc_add ( struct bufferchain bc,
const unsigned char data,
ssize_t  size 
)
static

Definition at line 637 of file readers.c.

638{
639 int ret = 0;
640 ssize_t part = 0;
641 debug2("bc_add: adding %"SSIZE_P" bytes at %"OFF_P, (ssize_p)size, (off_p)(bc->fileoff+bc->size));
642 if(size >=4) debug4("first bytes: %02x %02x %02x %02x", data[0], data[1], data[2], data[3]);
643
644 while(size > 0)
645 {
646 /* Try to fill up the last buffer block. */
647 if(bc->last != NULL && bc->last->size < bc->last->realsize)
648 {
649 part = bc->last->realsize - bc->last->size;
650 if(part > size) part = size;
651
652 debug2("bc_add: adding %"SSIZE_P" B to existing block %p", (ssize_p)part, (void*)bc->last);
653 memcpy(bc->last->data+bc->last->size, data, part);
654 bc->last->size += part;
655 size -= part;
656 bc->size += part;
657 data += part;
658 }
659
660 /* If there is still data left, put it into a new buffer block. */
661 if(size > 0 && (ret = bc_append(bc, size)) != 0)
662 break;
663 }
664
665 return ret;
666}
PBATCH_CONTEXT bc
Definition: batch.c:67
#define NULL
Definition: types.h:112
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static int bc_append(struct bufferchain *bc, ssize_t size)
Definition: readers.c:620
int ssize_t
Definition: rosdhcp.h:48
#define OFF_P
Definition: compat.h:131
#define SSIZE_P
Definition: compat.h:147
long off_p
Definition: compat.h:132
long ssize_p
Definition: compat.h:148
#define debug2(s, a, b)
Definition: debug.h:62
#define debug4(s, a, b, c, d)
Definition: debug.h:64
int ret

Referenced by buffered_fullread(), and feed_more().

◆ bc_alloc()

static struct buffy * bc_alloc ( struct bufferchain bc,
size_t  size 
)
static

Definition at line 535 of file readers.c.

536{
537 /* Easy route: Just try the first available buffer.
538 Size does not matter, it's only a hint for creation of new buffers. */
539 if(bc->pool)
540 {
541 struct buffy *buf = bc->pool;
542 bc->pool = buf->next;
543 buf->next = NULL; /* That shall be set to a sensible value later. */
544 buf->size = 0;
545 --bc->pool_fill;
546 debug2("bc_alloc: picked %p from pool (fill now %"SIZE_P")", (void*)buf, (size_p)bc->pool_fill);
547 return buf;
548 }
549 else return buffy_new(size, bc->bufblock);
550}
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static struct buffy * buffy_new(size_t size, size_t minsize)
Definition: readers.c:470
#define SIZE_P
Definition: compat.h:139
unsigned long size_p
Definition: compat.h:140
Definition: reader.h:17

Referenced by bc_append().

◆ bc_append()

static int bc_append ( struct bufferchain bc,
ssize_t  size 
)
static

Definition at line 620 of file readers.c.

621{
622 struct buffy *newbuf;
623 if(size < 1) return -1;
624
625 newbuf = bc_alloc(bc, size);
626 if(newbuf == NULL) return -2;
627
628 if(bc->last != NULL) bc->last->next = newbuf;
629 else if(bc->first == NULL) bc->first = newbuf;
630
631 bc->last = newbuf;
632 debug3("bc_append: new last buffer %p with %"SSIZE_P" B (really %"SSIZE_P")", (void*)bc->last, (ssize_p)bc->last->size, (ssize_p)bc->last->realsize);
633 return 0;
634}
static struct buffy * bc_alloc(struct bufferchain *bc, size_t size)
Definition: readers.c:535
#define debug3(s, a, b, c)
Definition: debug.h:63

Referenced by bc_add().

◆ bc_cleanup()

void bc_cleanup ( struct bufferchain bc)

Definition at line 527 of file readers.c.

528{
529 buffy_del_chain(bc->pool);
530 bc->pool = NULL;
531 bc->pool_fill = 0;
532}
static void buffy_del_chain(struct buffy *buf)
Definition: readers.c:498

◆ bc_fill()

size_t bc_fill ( struct bufferchain bc)

Definition at line 516 of file readers.c.

517{
518 return (size_t)(bc->size - bc->pos);
519}

◆ bc_fill_pool()

static int bc_fill_pool ( struct bufferchain bc)
static

Definition at line 567 of file readers.c.

568{
569 /* Remove superfluous ones. */
570 while(bc->pool_fill > bc->pool_size)
571 {
572 /* Lazyness: Just work on the front. */
573 struct buffy* buf = bc->pool;
574 bc->pool = buf->next;
575 buffy_del(buf);
576 --bc->pool_fill;
577 }
578
579 /* Add missing ones. */
580 while(bc->pool_fill < bc->pool_size)
581 {
582 /* Again, just work on the front. */
583 struct buffy* buf;
584 buf = buffy_new(0, bc->bufblock); /* Use default block size. */
585 if(!buf) return -1;
586
587 buf->next = bc->pool;
588 bc->pool = buf;
589 ++bc->pool_fill;
590 }
591
592 return 0;
593}
static void buffy_del(struct buffy *buf)
Definition: readers.c:488

Referenced by bc_reset(), and feed_init().

◆ bc_forget()

static void bc_forget ( struct bufferchain bc)
static

Definition at line 734 of file readers.c.

735{
736 struct buffy *b = bc->first;
737 /* free all buffers that are def'n'tly outdated */
738 /* we have buffers until filepos... delete all buffers fully below it */
739 if(b) debug2("bc_forget: block %lu pos %lu", (unsigned long)b->size, (unsigned long)bc->pos);
740 else debug("forget with nothing there!");
741
742 while(b != NULL && bc->pos >= b->size)
743 {
744 struct buffy *n = b->next; /* != NULL or this is indeed the end and the last cycle anyway */
745 if(n == NULL) bc->last = NULL; /* Going to delete the last buffy... */
746 bc->fileoff += b->size;
747 bc->pos -= b->size;
748 bc->size -= b->size;
749
750 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);
751
752 bc_free(bc, b);
753 b = n;
754 }
755 bc->first = b;
756 bc->firstpos = bc->pos;
757}
GLdouble n
Definition: glext.h:7729
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define b
Definition: ke_i.h:79
#define debug(msg)
Definition: key_call.c:71
static void bc_free(struct bufferchain *bc, struct buffy *buf)
Definition: readers.c:553
#define debug5(s, a, b, c, d, e)
Definition: debug.h:65
struct buffy * next
Definition: reader.h:21

Referenced by buffered_forget().

◆ bc_free()

static void bc_free ( struct bufferchain bc,
struct buffy buf 
)
static

Definition at line 553 of file readers.c.

554{
555 if(!buf) return;
556
557 if(bc->pool_fill < bc->pool_size)
558 {
559 buf->next = bc->pool;
560 bc->pool = buf;
561 ++bc->pool_fill;
562 }
563 else buffy_del(buf);
564}

Referenced by bc_forget(), and bc_reset().

◆ bc_give()

static ssize_t bc_give ( struct bufferchain bc,
unsigned char out,
ssize_t  size 
)
static

Definition at line 678 of file readers.c.

679{
680 struct buffy *b = bc->first;
681 ssize_t gotcount = 0;
682 ssize_t offset = 0;
683 if(bc->size - bc->pos < size) return bc_need_more(bc);
684
685 /* find the current buffer */
686 while(b != NULL && (offset + b->size) <= bc->pos)
687 {
688 offset += b->size;
689 b = b->next;
690 }
691 /* now start copying from there */
692 while(gotcount < size && (b != NULL))
693 {
694 ssize_t loff = bc->pos - offset;
695 ssize_t chunk = size - gotcount; /* amount of bytes to get from here... */
696 if(chunk > b->size - loff) chunk = b->size - loff;
697
698#ifdef EXTRA_DEBUG
699 debug3("copying %liB from %p+%li",(long)chunk, b->data, (long)loff);
700#endif
701
702 memcpy(out+gotcount, b->data+loff, chunk);
703 gotcount += chunk;
704 bc->pos += chunk;
705 offset += b->size;
706 b = b->next;
707 }
708#ifdef EXTRA_DEBUG
709 debug2("got %li bytes, pos advanced to %li", (long)gotcount, (long)bc->pos);
710#endif
711
712 return gotcount;
713}
GLintptr offset
Definition: glext.h:5920
static ssize_t bc_need_more(struct bufferchain *bc)
Definition: readers.c:669
static FILE * out
Definition: regtests2xml.c:44
uint16_t size
Definition: btrfs_drv.h:563

Referenced by buffered_fullread(), and feed_read().

◆ bc_init()

static void bc_init ( struct bufferchain bc)
static

Definition at line 596 of file readers.c.

597{
598 bc->first = NULL;
599 bc->last = bc->first;
600 bc->size = 0;
601 bc->pos = 0;
602 bc->firstpos = 0;
603 bc->fileoff = 0;
604}

Referenced by bc_prepare(), bc_reset(), default_init(), feed_init(), and open_bad().

◆ bc_need_more()

static ssize_t bc_need_more ( struct bufferchain bc)
static

Definition at line 669 of file readers.c.

670{
671 debug3("hit end, back to beginning (%li - %li < %li)", (long)bc->size, (long)bc->pos, (long)bc->size);
672 /* go back to firstpos, undo the previous reads */
673 bc->pos = bc->firstpos;
674 return READER_MORE;
675}
#define READER_MORE
Definition: reader.h:135

Referenced by bc_give(), and bc_skip().

◆ bc_poolsize()

void bc_poolsize ( struct bufferchain bc,
size_t  pool_size,
size_t  bufblock 
)

Definition at line 521 of file readers.c.

522{
523 bc->pool_size = pool_size;
524 bc->bufblock = bufblock;
525}

◆ bc_prepare()

void bc_prepare ( struct bufferchain bc,
size_t  pool_size,
size_t  bufblock 
)

Definition at line 508 of file readers.c.

509{
510 bc_poolsize(bc, pool_size, bufblock);
511 bc->pool = NULL;
512 bc->pool_fill = 0;
513 bc_init(bc); /* Ensure that members are zeroed for read-only use. */
514}
#define bc_poolsize
Definition: intsym.h:249
static void bc_init(struct bufferchain *bc)
Definition: readers.c:596

◆ bc_reset()

static void bc_reset ( struct bufferchain bc)
static

Definition at line 606 of file readers.c.

607{
608 /* Free current chain, possibly stuffing back into the pool. */
609 while(bc->first)
610 {
611 struct buffy* buf = bc->first;
612 bc->first = buf->next;
613 bc_free(bc, buf);
614 }
615 bc_fill_pool(bc); /* Ignoring an error here... */
616 bc_init(bc);
617}
static int bc_fill_pool(struct bufferchain *bc)
Definition: readers.c:567

Referenced by feed_set_pos(), and stream_close().

◆ bc_seekback()

static ssize_t bc_seekback ( struct bufferchain bc,
ssize_t  count 
)
static

Definition at line 727 of file readers.c.

728{
729 if(count >= 0 && count <= bc->pos) return bc->pos -= count;
730 else return READER_ERROR;
731}
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define READER_ERROR
Definition: reader.h:134

Referenced by feed_back_bytes().

◆ bc_skip()

static ssize_t bc_skip ( struct bufferchain bc,
ssize_t  count 
)
static

Definition at line 717 of file readers.c.

718{
719 if(count >= 0)
720 {
721 if(bc->size - bc->pos < count) return bc_need_more(bc);
722 else return bc->pos += count;
723 }
724 else return READER_ERROR;
725}

Referenced by feed_skip_bytes().

◆ buffered_forget()

static void buffered_forget ( mpg123_handle fr)
static

Definition at line 816 of file readers.c.

817{
818 bc_forget(&fr->rdat.buffer);
819 fr->rdat.filepos = fr->rdat.buffer.fileoff + fr->rdat.buffer.pos;
820}
static void bc_forget(struct bufferchain *bc)
Definition: readers.c:734
struct reader_data rdat
Definition: frame.h:288

◆ buffered_fullread()

static ssize_t buffered_fullread ( mpg123_handle fr,
unsigned char out,
ssize_t  count 
)
static

Definition at line 842 of file readers.c.

843{
844 struct bufferchain *bc = &fr->rdat.buffer;
845 ssize_t gotcount;
846 if(VERBOSE3)
847 mdebug("buffered_fullread: want %zd", count);
848 if(bc->size - bc->pos < count)
849 { /* Add more stuff to buffer. If hitting end of file, adjust count. */
850 unsigned char readbuf[4096];
851 ssize_t need = count - (bc->size-bc->pos);
852 while(need>0)
853 {
854 int ret;
855 ssize_t got = fr->rdat.fullread(fr, readbuf, sizeof(readbuf));
856 if(got < 0)
857 {
858 if(NOQUIET) error("buffer reading");
859 return READER_ERROR;
860 }
861
862 if(VERBOSE3) debug1("buffered_fullread: buffering %li bytes from stream (if > 0)", (long)got);
863 if(got > 0 && (ret=bc_add(bc, readbuf, got)) != 0)
864 {
865 if(NOQUIET) error1("unable to add to chain, return: %i", ret);
866 return READER_ERROR;
867 }
868
869 need -= got; /* May underflow here... */
870 if(got < sizeof(readbuf)) /* That naturally catches got == 0, too. */
871 {
872 if(VERBOSE3) fprintf(stderr, "Note: Input data end.\n");
873 break; /* End. */
874 }
875 }
876 if(bc->size - bc->pos < count)
877 count = bc->size - bc->pos; /* We want only what we got. */
878 }
879 gotcount = bc_give(bc, out, count);
880 if(VERBOSE3)
881 mdebug("buffered_fullread: got %zd", gotcount);
882 if(gotcount != count){ if(NOQUIET) error("gotcount != count"); return READER_ERROR; }
883 else return gotcount;
884}
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define error(str)
Definition: mkdosfs.c:1605
static UINT PSTR DWORD UINT * need
Definition: parser.c:36
#define NOQUIET
#define VERBOSE3
static int bc_add(struct bufferchain *bc, const unsigned char *data, ssize_t size)
Definition: readers.c:637
static ssize_t bc_give(struct bufferchain *bc, unsigned char *out, ssize_t size)
Definition: readers.c:678
#define debug1(s, a)
Definition: debug.h:61
#define mdebug(s,...)
Definition: debug.h:58
#define error1(s, a)
Definition: debug.h:125

◆ buffy_del()

static void buffy_del ( struct buffy buf)
static

Definition at line 488 of file readers.c.

489{
490 if(buf)
491 {
492 free(buf->data);
493 free(buf);
494 }
495}
#define free
Definition: debug_ros.c:5

Referenced by bc_fill_pool(), bc_free(), and buffy_del_chain().

◆ buffy_del_chain()

static void buffy_del_chain ( struct buffy buf)
static

Definition at line 498 of file readers.c.

499{
500 while(buf)
501 {
502 struct buffy* next = buf->next;
503 buffy_del(buf);
504 buf = next;
505 }
506}
static unsigned __int64 next
Definition: rand_nt.c:6

Referenced by bc_cleanup().

◆ buffy_new()

static struct buffy * buffy_new ( size_t  size,
size_t  minsize 
)
static

Definition at line 470 of file readers.c.

471{
472 struct buffy *newbuf;
473 newbuf = malloc(sizeof(struct buffy));
474 if(newbuf == NULL) return NULL;
475
476 newbuf->realsize = size > minsize ? size : minsize;
477 newbuf->data = malloc(newbuf->realsize);
478 if(newbuf->data == NULL)
479 {
480 free(newbuf);
481 return NULL;
482 }
483 newbuf->size = 0;
484 newbuf->next = NULL;
485 return newbuf;
486}
#define malloc
Definition: debug_ros.c:4
ssize_t realsize
Definition: reader.h:20
unsigned char * data
Definition: reader.h:18
ssize_t size
Definition: reader.h:19

Referenced by bc_alloc(), and bc_fill_pool().

◆ default_init()

static int default_init ( mpg123_handle fr)
static

Definition at line 1036 of file readers.c.

1037{
1038#ifdef TIMEOUT_READ
1039 if(fr->p.timeout > 0)
1040 {
1041 int flags;
1042 if(fr->rdat.r_read != NULL)
1043 {
1044 if(NOQUIET)
1045 error( "Timeout reading does not work with user-provided"
1046 " read function. Implement it yourself!" );
1047 return -1;
1048 }
1049 flags = fcntl(fr->rdat.filept, F_GETFL);
1050 flags |= O_NONBLOCK;
1051 fcntl(fr->rdat.filept, F_SETFL, flags);
1052 fr->rdat.fdread = timeout_read;
1053 fr->rdat.timeout_sec = fr->p.timeout;
1054 fr->rdat.flags |= READER_NONBLOCK;
1055 }
1056 else
1057#endif
1058 fr->rdat.fdread = plain_read;
1059
1060 fr->rdat.read = fr->rdat.r_read != NULL ? fr->rdat.r_read : posix_read;
1061 fr->rdat.lseek = fr->rdat.r_lseek != NULL ? fr->rdat.r_lseek : posix_lseek;
1062#ifndef NO_ICY
1063 /* ICY streams of any sort shall not be seekable. */
1064 if(fr->p.icy_interval > 0) fr->rdat.lseek = nix_lseek;
1065#endif
1066
1067 fr->rdat.filelen = fr->p.flags & MPG123_NO_PEEK_END ? -1 : get_fileinfo(fr);
1068 fr->rdat.filepos = 0;
1069 if(fr->p.flags & MPG123_FORCE_SEEKABLE)
1070 fr->rdat.flags |= READER_SEEKABLE;
1071 /*
1072 Don't enable seeking on ICY streams, just plain normal files.
1073 This check is necessary since the client can enforce ICY parsing on files that would otherwise be seekable.
1074 It is a task for the future to make the ICY parsing safe with seeks ... or not.
1075 */
1076 if(fr->rdat.filelen >= 0)
1077 {
1078 debug("seekable stream");
1079 fr->rdat.flags |= READER_SEEKABLE;
1080 if(!strncmp((char*)fr->id3buf,"TAG",3))
1081 {
1082 fr->rdat.flags |= READER_ID3TAG;
1084 }
1085 }
1086 /* Switch reader to a buffered one, if allowed. */
1087 else if(fr->p.flags & MPG123_SEEKBUFFER)
1088 {
1089#ifdef NO_FEEDER
1090 if(NOQUIET)
1091 error("Buffered readers not supported in this build.");
1093 return -1;
1094#else
1095 if (fr->rd == &readers[READER_STREAM])
1096 {
1097 debug("switching to buffered stream reader");
1099 fr->rdat.fullread = plain_fullread;
1100 }
1101#ifndef NO_ICY
1102 else if(fr->rd == &readers[READER_ICY_STREAM])
1103 {
1104 debug("switching to buffered ICY stream reader");
1106 fr->rdat.fullread = icy_fullread;
1107 }
1108#endif
1109 else
1110 {
1111 if(NOQUIET) error("mpg123 Programmer's fault: invalid reader");
1112 return -1;
1113 }
1114 bc_init(&fr->rdat.buffer);
1115 fr->rdat.filelen = 0; /* We carry the offset, but never know how big the stream is. */
1116 fr->rdat.flags |= READER_BUFFERED;
1117#endif /* NO_ICY */
1118 }
1119 return 0;
1120}
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
GLbitfield flags
Definition: glext.h:7161
@ MPG123_MISSING_FEATURE
Definition: mpg123.h:421
@ MPG123_SEEKBUFFER
Definition: mpg123.h:222
@ MPG123_NO_PEEK_END
Definition: mpg123.h:231
@ MPG123_FORCE_SEEKABLE
Definition: mpg123.h:237
#define MPG123_NEW_ID3
Definition: mpg123.h:1465
#define O_NONBLOCK
Definition: port.h:158
static ssize_t plain_read(mpg123_handle *fr, void *buf, size_t count)
Definition: readers.c:58
static off_t nix_lseek(int fd, off_t offset, int whence)
Definition: readers.c:34
static off_t get_fileinfo(mpg123_handle *)
Definition: readers.c:430
#define READER_BUF_ICY_STREAM
Definition: readers.c:920
#define READER_ICY_STREAM
Definition: readers.c:917
#define READER_STREAM
Definition: readers.c:916
static off_t posix_lseek(int fd, off_t offset, int whence)
Definition: readers.c:33
static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count)
Definition: readers.c:92
static ssize_t posix_read(int fd, void *buf, size_t count)
Definition: readers.c:32
static struct reader readers[]
Definition: readers.c:921
static ssize_t plain_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count)
Definition: readers.c:202
#define READER_BUF_STREAM
Definition: readers.c:919
#define READER_BUFFERED
Definition: reader.h:116
#define READER_ID3TAG
Definition: reader.h:114
#define READER_SEEKABLE
Definition: reader.h:115
#define READER_NONBLOCK
Definition: reader.h:117
struct mpg123_pars_struct p
Definition: frame.h:289
struct reader * rd
Definition: frame.h:287
unsigned char id3buf[128]
Definition: frame.h:296

◆ feed_back_bytes()

static int feed_back_bytes ( mpg123_handle fr,
off_t  bytes 
)
static

Definition at line 805 of file readers.c.

806{
807 if(bytes >=0)
808 return bc_seekback(&fr->rdat.buffer, (ssize_t)bytes) >= 0 ? 0 : READER_ERROR;
809 else
810 return feed_skip_bytes(fr, -bytes) >= 0 ? 0 : READER_ERROR;
811}
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
static ssize_t bc_seekback(struct bufferchain *bc, ssize_t count)
Definition: readers.c:727
static off_t feed_skip_bytes(mpg123_handle *fr, off_t len)
Definition: readers.c:796

◆ feed_init()

static int feed_init ( mpg123_handle fr)
static

Definition at line 761 of file readers.c.

762{
763 bc_init(&fr->rdat.buffer);
764 bc_fill_pool(&fr->rdat.buffer);
765 fr->rdat.filelen = 0;
766 fr->rdat.filepos = 0;
767 fr->rdat.flags |= READER_BUFFERED;
768 return 0;
769}

◆ feed_more()

int feed_more ( mpg123_handle fr,
const unsigned char in,
long  count 
)

Definition at line 772 of file readers.c.

773{
774 int ret = 0;
775 if(VERBOSE3) debug("feed_more");
776 if((ret = bc_add(&fr->rdat.buffer, in, count)) != 0)
777 {
779 if(NOQUIET) error1("Failed to add buffer, return: %i", ret);
780 }
781 else /* Not talking about filelen... that stays at 0. */
782
783 if(VERBOSE3) debug3("feed_more: %p %luB bufsize=%lu", fr->rdat.buffer.last->data,
784 (unsigned long)fr->rdat.buffer.last->size, (unsigned long)fr->rdat.buffer.size);
785 return ret;
786}
GLuint in
Definition: glext.h:9616

◆ feed_read()

static ssize_t feed_read ( mpg123_handle fr,
unsigned char out,
ssize_t  count 
)
static

Definition at line 788 of file readers.c.

789{
790 ssize_t gotcount = bc_give(&fr->rdat.buffer, out, count);
791 if(gotcount >= 0 && gotcount != count) return READER_ERROR;
792 else return gotcount;
793}

◆ feed_seek_frame()

static int feed_seek_frame ( mpg123_handle fr,
off_t  num 
)
static

Definition at line 813 of file readers.c.

813{ return READER_ERROR; }

◆ feed_set_pos()

off_t feed_set_pos ( mpg123_handle fr,
off_t  pos 
)

Definition at line 822 of file readers.c.

823{
824 struct bufferchain *bc = &fr->rdat.buffer;
825 if(pos >= bc->fileoff && pos-bc->fileoff < bc->size)
826 { /* We have the position! */
827 bc->pos = (ssize_t)(pos - bc->fileoff);
828 debug1("feed_set_pos inside, next feed from %"OFF_P, (off_p)(bc->fileoff+bc->size));
829 return bc->fileoff+bc->size; /* Next input after end of buffer... */
830 }
831 else
832 { /* I expect to get the specific position on next feed. Forget what I have now. */
833 bc_reset(bc);
834 bc->fileoff = pos;
835 debug1("feed_set_pos outside, buffer reset, next feed from %"OFF_P, (off_p)pos);
836 return pos; /* Next input from exactly that position. */
837 }
838}
static void bc_reset(struct bufferchain *bc)
Definition: readers.c:606
#define ssize_t
Definition: config.h:517

◆ feed_skip_bytes()

static off_t feed_skip_bytes ( mpg123_handle fr,
off_t  len 
)
static

Definition at line 796 of file readers.c.

797{
798 /* This is either the new buffer offset or some negative error value. */
799 off_t res = bc_skip(&fr->rdat.buffer, (ssize_t)len);
800 if(res < 0) return res;
801
802 return fr->rdat.buffer.fileoff+res;
803}
__kernel_off_t off_t
Definition: linux.h:201
GLuint res
Definition: glext.h:9613
GLenum GLsizei len
Definition: glext.h:6722
static ssize_t bc_skip(struct bufferchain *bc, ssize_t count)
Definition: readers.c:717

Referenced by feed_back_bytes().

◆ generic_head_read()

static int generic_head_read ( mpg123_handle fr,
unsigned long newhead 
)
static

Definition at line 303 of file readers.c.

304{
305 unsigned char hbuf[4];
306 int ret = fr->rd->fullread(fr,hbuf,4);
307 if(ret == READER_MORE) return ret;
308 if(ret != 4) return FALSE;
309
310 *newhead = ((unsigned long) hbuf[0] << 24) |
311 ((unsigned long) hbuf[1] << 16) |
312 ((unsigned long) hbuf[2] << 8) |
313 (unsigned long) hbuf[3];
314
315 return TRUE;
316}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define long
Definition: qsort.c:33

◆ generic_head_shift()

static int generic_head_shift ( mpg123_handle fr,
unsigned long head 
)
static

Definition at line 319 of file readers.c.

320{
321 unsigned char hbuf;
322 int ret = fr->rd->fullread(fr,&hbuf,1);
323 if(ret == READER_MORE) return ret;
324 if(ret != 1) return FALSE;
325
326 *head <<= 8;
327 *head |= hbuf;
328 *head &= 0xffffffff;
329 return TRUE;
330}
struct outqueuenode * head
Definition: adnsresfilter.c:66

◆ generic_read_frame_body()

static int generic_read_frame_body ( mpg123_handle fr,
unsigned char buf,
int  size 
)
static

Definition at line 388 of file readers.c.

389{
390 long l;
391 l=fr->rd->fullread(fr,buf,size);
392 return (l >= 0 && l<size) ? READER_ERROR : l;
393}
r l[0]
Definition: byte_order.h:168

◆ generic_tell()

static off_t generic_tell ( mpg123_handle fr)
static

Definition at line 395 of file readers.c.

396{
397#ifndef NO_FEEDER
398 if(fr->rdat.flags & READER_BUFFERED)
399 fr->rdat.filepos = fr->rdat.buffer.fileoff+fr->rdat.buffer.pos;
400#endif
401
402 return fr->rdat.filepos;
403}

◆ get_fileinfo()

static off_t get_fileinfo ( mpg123_handle fr)
static

Definition at line 430 of file readers.c.

431{
432 off_t len;
433
434 if((len=io_seek(&fr->rdat,0,SEEK_END)) < 0)
435 {
436 debug("cannot seek to end");
437 return -1;
438 } else if(len >= 128)
439 {
440 if(io_seek(&fr->rdat,-128,SEEK_END) < 0)
441 {
442 debug("cannot seek to END-128");
443 return -1;
444 }
445 if(fr->rd->fullread(fr,(unsigned char *)fr->id3buf,128) != 128)
446 {
447 debug("cannot read ID3v1?!");
448 return -1;
449 }
450 if(!strncmp((char*)fr->id3buf,"TAG",3)) len -= 128;
451 } else
452 {
453 debug("stream too short for ID3");
454 }
455
456 if(io_seek(&fr->rdat,0,SEEK_SET) < 0)
457 {
458 debug("cannot seek back");
459 return -1;
460 }
461
462 debug1("returning length: %"OFF_P, (off_p)len);
463 return len;
464}
#define SEEK_END
Definition: cabinet.c:29
#define SEEK_SET
Definition: jmemansi.c:26
static off_t io_seek(struct reader_data *rdat, off_t offset, int whence)
Definition: readers.c:1231

Referenced by default_init().

◆ icy_fullread()

static ssize_t icy_fullread ( mpg123_handle fr,
unsigned char buf,
ssize_t  count 
)
static

Definition at line 92 of file readers.c.

93{
94 ssize_t ret,cnt;
95 cnt = 0;
96 if(fr->rdat.flags & READER_SEEKABLE)
97 {
98 if(NOQUIET) error("mpg123 programmer error: I don't do ICY on seekable streams.");
99 return -1;
100 }
101 /*
102 There used to be a check for expected file end here (length value or ID3 flag).
103 This is not needed:
104 1. EOF is indicated by fdread returning zero bytes anyway.
105 2. We get false positives of EOF for either files that grew or
106 3. ... files that have ID3v1 tags in between (stream with intro).
107 */
108
109 while(cnt < count)
110 {
111 /* all icy code is inside this if block, everything else is the plain fullread we know */
112 /* debug1("read: %li left", (long) count-cnt); */
113 if(fr->icy.next < count-cnt)
114 {
115 unsigned char temp_buff;
116 size_t meta_size;
117 ssize_t cut_pos;
118
119 /* we are near icy-metaint boundary, read up to the boundary */
120 if(fr->icy.next > 0)
121 {
122 cut_pos = fr->icy.next;
123 ret = fr->rdat.fdread(fr,buf+cnt,cut_pos);
124 if(ret < 1)
125 {
126 if(ret == 0) break; /* Just EOF. */
127 if(NOQUIET) error("icy boundary read");
128
129 return READER_ERROR;
130 }
131
132 if(!(fr->rdat.flags & READER_BUFFERED)) fr->rdat.filepos += ret;
133 cnt += ret;
134 fr->icy.next -= ret;
135 if(fr->icy.next > 0)
136 {
137 debug1("another try... still %li left", (long)fr->icy.next);
138 continue;
139 }
140 }
141 /* now off to read icy data */
142
143 /* one byte icy-meta size (must be multiplied by 16 to get icy-meta length) */
144
145 ret = fr->rdat.fdread(fr,&temp_buff,1); /* Getting one single byte hast to suceed. */
146 if(ret < 0){ if(NOQUIET) error("reading icy size"); return READER_ERROR; }
147 if(ret == 0) break;
148
149 debug2("got meta-size byte: %u, at filepos %li", temp_buff, (long)fr->rdat.filepos );
150 if(!(fr->rdat.flags & READER_BUFFERED)) fr->rdat.filepos += ret; /* 1... */
151
152 if((meta_size = ((size_t) temp_buff) * 16))
153 {
154 /* we have got some metadata */
155 char *meta_buff;
156 /* TODO: Get rid of this malloc ... perhaps hooking into the reader buffer pool? */
157 meta_buff = malloc(meta_size+1);
158 if(meta_buff != NULL)
159 {
160 ssize_t left = meta_size;
161 while(left > 0)
162 {
163 ret = fr->rdat.fdread(fr,meta_buff+meta_size-left,left);
164 /* 0 is error here, too... there _must_ be the ICY data, the server promised! */
165 if(ret < 1){ if(NOQUIET) error("reading icy-meta"); return READER_ERROR; }
166 left -= ret;
167 }
168 meta_buff[meta_size] = 0; /* string paranoia */
169 if(!(fr->rdat.flags & READER_BUFFERED)) fr->rdat.filepos += ret;
170
171 if(fr->icy.data) free(fr->icy.data);
172 fr->icy.data = meta_buff;
174 debug2("icy-meta: %s size: %d bytes", fr->icy.data, (int)meta_size);
175 }
176 else
177 {
178 if(NOQUIET) error1("cannot allocate memory for meta_buff (%lu bytes) ... trying to skip the metadata!", (unsigned long)meta_size);
179 fr->rd->skip_bytes(fr, meta_size);
180 }
181 }
182 fr->icy.next = fr->icy.interval;
183 }
184 else
185 {
186 ret = plain_fullread(fr, buf+cnt, count-cnt);
187 if(ret < 0){ if(NOQUIET) error1("reading the rest of %li", (long)(count-cnt)); return READER_ERROR; }
188 if(ret == 0) break;
189
190 cnt += ret;
191 fr->icy.next -= ret;
192 }
193 }
194 /* debug1("done reading, got %li", (long)cnt); */
195 return cnt;
196}
GLint left
Definition: glext.h:7726
#define MPG123_NEW_ICY
Definition: mpg123.h:1467
struct icy_meta icy
Definition: frame.h:303

Referenced by default_init().

◆ io_read()

static ssize_t io_read ( struct reader_data rdat,
void buf,
size_t  count 
)
static

Definition at line 1245 of file readers.c.

1246{
1247 if(rdat->flags & READER_HANDLEIO)
1248 {
1249 if(rdat->r_read_handle != NULL)
1250 {
1251 return rdat->r_read_handle(rdat->iohandle, buf, count);
1252 }
1253 else return -1;
1254 }
1255 else
1256 return rdat->read(rdat->filept, buf, count);
1257}
#define READER_HANDLEIO
Definition: reader.h:118
ssize_t(* r_read_handle)(void *handle, void *buf, size_t count)
Definition: reader.h:68
ssize_t(* read)(int fd, void *buf, size_t count)
Definition: reader.h:73
int flags
Definition: reader.h:60
int filept
Definition: reader.h:57
void * iohandle
Definition: reader.h:59

Referenced by plain_read().

◆ io_seek()

static off_t io_seek ( struct reader_data rdat,
off_t  offset,
int  whence 
)
static

Definition at line 1231 of file readers.c.

1232{
1233 if(rdat->flags & READER_HANDLEIO)
1234 {
1235 if(rdat->r_lseek_handle != NULL)
1236 {
1237 return rdat->r_lseek_handle(rdat->iohandle, offset, whence);
1238 }
1239 else return -1;
1240 }
1241 else
1242 return rdat->lseek(rdat->filept, offset, whence);
1243}
off_t(* lseek)(int fd, off_t offset, int whence)
Definition: reader.h:74
off_t(* r_lseek_handle)(void *handle, off_t offset, int whence)
Definition: reader.h:69

Referenced by get_fileinfo(), and stream_lseek().

◆ nix_lseek()

static off_t nix_lseek ( int  fd,
off_t  offset,
int  whence 
)
static

Definition at line 34 of file readers.c.

34{ return -1; }

Referenced by default_init().

◆ open_bad()

void open_bad ( mpg123_handle mh)

Definition at line 1123 of file readers.c.

1124{
1125 debug("open_bad");
1126#ifndef NO_ICY
1127 clear_icy(&mh->icy);
1128#endif
1129 mh->rd = &bad_reader;
1130 mh->rdat.flags = 0;
1131#ifndef NO_FEEDER
1132 bc_init(&mh->rdat.buffer);
1133#endif
1134 mh->rdat.filelen = -1;
1135}
#define clear_icy
Definition: intsym.h:209
static struct reader bad_reader
Definition: readers.c:1020

◆ open_feed()

int open_feed ( mpg123_handle fr)

Definition at line 1137 of file readers.c.

1138{
1139 debug("feed reader");
1140#ifdef NO_FEEDER
1141 if(NOQUIET)
1142 error("Buffered readers not supported in this build.");
1144 return -1;
1145#else
1146#ifndef NO_ICY
1147 if(fr->p.icy_interval > 0)
1148 {
1149 if(NOQUIET) error("Feed reader cannot do ICY parsing!");
1150
1151 return -1;
1152 }
1153 clear_icy(&fr->icy);
1154#endif
1155 fr->rd = &readers[READER_FEED];
1156 fr->rdat.flags = 0;
1157 if(fr->rd->init(fr) < 0) return -1;
1158
1159 debug("feed reader init successful");
1160 return 0;
1161#endif /* NO_FEEDER */
1162}
#define READER_FEED
Definition: readers.c:918

◆ open_finish()

static int open_finish ( mpg123_handle fr)
static

Definition at line 1165 of file readers.c.

1166{
1167#ifndef NO_ICY
1168 if(fr->p.icy_interval > 0)
1169 {
1170 debug("ICY reader");
1171 fr->icy.interval = fr->p.icy_interval;
1172 fr->icy.next = fr->icy.interval;
1174 }
1175 else
1176#endif
1177 {
1178 fr->rd = &readers[READER_STREAM];
1179 debug("stream reader");
1180 }
1181
1182 if(fr->rd->init(fr) < 0) return -1;
1183
1184 return MPG123_OK;
1185}
@ MPG123_OK
Definition: mpg123.h:383

Referenced by open_stream(), and open_stream_handle().

◆ open_stream()

int open_stream ( mpg123_handle fr,
const char bs_filenam,
int  fd 
)

Definition at line 1187 of file readers.c.

1188{
1189 int filept_opened = 1;
1190 int filept; /* descriptor of opened file/stream */
1191
1192 clear_icy(&fr->icy); /* can be done inside frame_clear ...? */
1193
1194 if(!bs_filenam) /* no file to open, got a descriptor (stdin) */
1195 {
1196 filept = fd;
1197 filept_opened = 0; /* and don't try to close it... */
1198 }
1199 #ifndef O_BINARY
1200 #define O_BINARY (0)
1201 #endif
1202 else if((filept = compat_open(bs_filenam, O_RDONLY|O_BINARY)) < 0) /* a plain old file to open... */
1203 {
1204 if(NOQUIET) error2("Cannot open file %s: %s", bs_filenam, strerror(errno));
1205 fr->err = MPG123_BAD_FILE;
1206 return MPG123_ERR; /* error... */
1207 }
1208
1209 /* now we have something behind filept and can init the reader */
1210 fr->rdat.filelen = -1;
1211 fr->rdat.filept = filept;
1212 fr->rdat.flags = 0;
1213 if(filept_opened) fr->rdat.flags |= READER_FD_OPENED;
1214
1215 return open_finish(fr);
1216}
#define O_RDONLY
Definition: acwin.h:108
@ MPG123_ERR
Definition: mpg123.h:382
@ MPG123_BAD_FILE
Definition: mpg123.h:405
#define compat_open
Definition: intsym.h:13
const char * strerror(int err)
Definition: compat_str.c:23
#define O_BINARY
static int open_finish(mpg123_handle *fr)
Definition: readers.c:1165
#define errno
Definition: errno.h:18
#define error2(s, a, b)
Definition: debug.h:126
#define READER_FD_OPENED
Definition: reader.h:113
static int fd
Definition: io.c:51

◆ open_stream_handle()

int open_stream_handle ( mpg123_handle fr,
void iohandle 
)

Definition at line 1218 of file readers.c.

1219{
1220 clear_icy(&fr->icy); /* can be done inside frame_clear ...? */
1221 fr->rdat.filelen = -1;
1222 fr->rdat.filept = -1;
1223 fr->rdat.iohandle = iohandle;
1224 fr->rdat.flags = 0;
1225 fr->rdat.flags |= READER_HANDLEIO;
1226
1227 return open_finish(fr);
1228}

◆ plain_fullread()

static ssize_t plain_fullread ( mpg123_handle fr,
unsigned char buf,
ssize_t  count 
)
static

Definition at line 202 of file readers.c.

203{
204 ssize_t ret,cnt=0;
205
206#ifdef EXTRA_DEBUG
207 debug1("plain fullread of %"SSIZE_P, (size_p)count);
208#endif
209 /*
210 There used to be a check for expected file end here (length value or ID3 flag).
211 This is not needed:
212 1. EOF is indicated by fdread returning zero bytes anyway.
213 2. We get false positives of EOF for either files that grew or
214 3. ... files that have ID3v1 tags in between (stream with intro).
215 */
216 while(cnt < count)
217 {
218 ret = fr->rdat.fdread(fr,buf+cnt,count-cnt);
219 if(ret < 0) return READER_ERROR;
220 if(ret == 0) break;
221 if(!(fr->rdat.flags & READER_BUFFERED)) fr->rdat.filepos += ret;
222 cnt += ret;
223 }
224 return cnt;
225}

Referenced by default_init(), and icy_fullread().

◆ plain_read()

static ssize_t plain_read ( mpg123_handle fr,
void buf,
size_t  count 
)
static

Definition at line 58 of file readers.c.

59{
60 ssize_t ret = io_read(&fr->rdat, buf, count);
61 if(VERBOSE3) debug2("read %li bytes of %li", (long)ret, (long)count);
62 return ret;
63}
static ssize_t io_read(struct reader_data *rdat, void *buf, size_t count)
Definition: readers.c:1245

Referenced by default_init().

◆ posix_lseek()

static off_t posix_lseek ( int  fd,
off_t  offset,
int  whence 
)
static

Definition at line 33 of file readers.c.

33{ return lseek(fd, offset, whence); }
#define lseek
Definition: syshdrs.h:47

Referenced by default_init().

◆ posix_read()

static ssize_t posix_read ( int  fd,
void buf,
size_t  count 
)
static

Definition at line 32 of file readers.c.

32{ return read(fd, buf, count); }
#define read
Definition: acwin.h:96

Referenced by default_init().

◆ stream_back_bytes()

static int stream_back_bytes ( mpg123_handle fr,
off_t  bytes 
)
static

Definition at line 377 of file readers.c.

378{
379 off_t want = fr->rd->tell(fr)-bytes;
380 if(want < 0) return READER_ERROR;
381 if(stream_skip_bytes(fr,-bytes) != want) return READER_ERROR;
382
383 return 0;
384}
static off_t stream_skip_bytes(mpg123_handle *fr, off_t len)
Definition: readers.c:333

◆ stream_close()

static void stream_close ( mpg123_handle fr)
static

Definition at line 240 of file readers.c.

241{
242 if(fr->rdat.flags & READER_FD_OPENED) compat_close(fr->rdat.filept);
243
244 fr->rdat.filept = 0;
245
246#ifndef NO_FEEDER
247 if(fr->rdat.flags & READER_BUFFERED) bc_reset(&fr->rdat.buffer);
248#endif
249 if(fr->rdat.flags & READER_HANDLEIO)
250 {
251 if(fr->rdat.cleanup_handle != NULL) fr->rdat.cleanup_handle(fr->rdat.iohandle);
252
253 fr->rdat.iohandle = NULL;
254 }
255}
#define compat_close
Definition: intsym.h:16

◆ stream_lseek()

static off_t stream_lseek ( mpg123_handle fr,
off_t  pos,
int  whence 
)
static

Definition at line 227 of file readers.c.

228{
229 off_t ret;
230 ret = io_seek(&fr->rdat, pos, whence);
231 if (ret >= 0) fr->rdat.filepos = ret;
232 else
233 {
235 ret = READER_ERROR; /* not the original value */
236 }
237 return ret;
238}
@ MPG123_LSEEK_FAILED
Definition: mpg123.h:423

Referenced by stream_rewind(), and stream_skip_bytes().

◆ stream_rewind()

static void stream_rewind ( mpg123_handle fr)
static

Definition at line 406 of file readers.c.

407{
408 if(fr->rdat.flags & READER_SEEKABLE)
409 {
410 fr->rdat.filepos = stream_lseek(fr,0,SEEK_SET);
411#ifndef NO_FEEDER
412 fr->rdat.buffer.fileoff = fr->rdat.filepos;
413#endif
414 }
415#ifndef NO_FEEDER
416 if(fr->rdat.flags & READER_BUFFERED)
417 {
418 fr->rdat.buffer.pos = 0;
419 fr->rdat.buffer.firstpos = 0;
420 fr->rdat.filepos = fr->rdat.buffer.fileoff;
421 }
422#endif
423}
static off_t stream_lseek(mpg123_handle *fr, off_t pos, int whence)
Definition: readers.c:227

◆ stream_seek_frame()

static int stream_seek_frame ( mpg123_handle fr,
off_t  newframe 
)
static

Definition at line 257 of file readers.c.

258{
259 debug2("seek_frame to %"OFF_P" (from %"OFF_P")", (off_p)newframe, (off_p)fr->num);
260 /* Seekable streams can go backwards and jump forwards.
261 Non-seekable streams still can go forward, just not jump. */
262 if((fr->rdat.flags & READER_SEEKABLE) || (newframe >= fr->num))
263 {
264 off_t preframe; /* a leading frame we jump to */
265 off_t seek_to; /* the byte offset we want to reach */
266 off_t to_skip; /* bytes to skip to get there (can be negative) */
267 /*
268 now seek to nearest leading index position and read from there until newframe is reached.
269 We use skip_bytes, which handles seekable and non-seekable streams
270 (the latter only for positive offset, which we ensured before entering here).
271 */
272 seek_to = frame_index_find(fr, newframe, &preframe);
273 /* No need to seek to index position if we are closer already.
274 But I am picky about fr->num == newframe, play safe by reading the frame again.
275 If you think that's stupid, don't call a seek to the current frame. */
276 if(fr->num >= newframe || fr->num < preframe)
277 {
278 to_skip = seek_to - fr->rd->tell(fr);
279 if(fr->rd->skip_bytes(fr, to_skip) != seek_to)
280 return READER_ERROR;
281
282 debug2("going to %lu; just got %lu", (long unsigned)newframe, (long unsigned)preframe);
283 fr->num = preframe-1; /* Watch out! I am going to read preframe... fr->num should indicate the frame before! */
284 }
285 while(fr->num < newframe)
286 {
287 /* try to be non-fatal now... frameNum only gets advanced on success anyway */
288 if(!read_frame(fr)) break;
289 }
290 /* Now the wanted frame should be ready for decoding. */
291 debug1("arrived at %lu", (long unsigned)fr->num);
292
293 return MPG123_OK;
294 }
295 else
296 {
297 fr->err = MPG123_NO_SEEK;
298 return READER_ERROR; /* invalid, no seek happened */
299 }
300}
@ MPG123_NO_SEEK
Definition: mpg123.h:406
#define frame_index_find
Definition: intsym.h:187
#define read_frame
Definition: intsym.h:241

◆ stream_skip_bytes()

static off_t stream_skip_bytes ( mpg123_handle fr,
off_t  len 
)
static

Definition at line 333 of file readers.c.

334{
335 if(fr->rdat.flags & READER_SEEKABLE)
336 {
338 return (ret < 0) ? READER_ERROR : ret;
339 }
340 else if(len >= 0)
341 {
342 unsigned char buf[1024]; /* ThOr: Compaq cxx complained and it makes sense to me... or should one do a cast? What for? */
343 ssize_t ret;
344 while (len > 0)
345 {
346 ssize_t num = len < (off_t)sizeof(buf) ? (ssize_t)len : (ssize_t)sizeof(buf);
347 ret = fr->rd->fullread(fr, buf, num);
348 if (ret < 0) return ret;
349 else if(ret == 0) break; /* EOF... an error? interface defined to tell the actual position... */
350 len -= ret;
351 }
352 return fr->rd->tell(fr);
353 }
354#ifndef NO_FEEDER
355 else if(fr->rdat.flags & READER_BUFFERED)
356 { /* Perhaps we _can_ go a bit back. */
357 if(fr->rdat.buffer.pos >= -len)
358 {
359 fr->rdat.buffer.pos += len;
360 return fr->rd->tell(fr);
361 }
362 else
363 {
364 fr->err = MPG123_NO_SEEK;
365 return READER_ERROR;
366 }
367 }
368#endif
369 else
370 {
371 fr->err = MPG123_NO_SEEK;
372 return READER_ERROR;
373 }
374}
#define off_t
Definition: dosfsck.h:5
GLuint GLuint num
Definition: glext.h:9618
#define SEEK_CUR
Definition: util.h:63

Referenced by stream_back_bytes().

Variable Documentation

◆ bad_reader

struct reader bad_reader
static
Initial value:
=
{
bad_close,
bad_head_read,
bad_skip_bytes,
bad_back_bytes,
bad_tell,
bad_rewind,
}
static ssize_t unsigned long *newhead static bugger_off int off_t len static bugger_off int off_t bytes static bugger_off int bad_seek_frame(mpg123_handle *mh, off_t num) bugger_off static off_t bad_tell(mpg123_handle *mh) bugger_off static void bad_rewind(mpg123_handle *mh)
Definition: readers.c:911
static ssize_t unsigned long *newhead static bugger_off int off_t len static bugger_off int bad_read_frame_body(mpg123_handle *mh, unsigned char *data, int size) bugger_off static int bad_back_bytes(mpg123_handle *mh
static ssize_t unsigned long *newhead static bugger_off int bad_head_shift(mpg123_handle *mh, unsigned long *head) bugger_off static off_t bad_skip_bytes(mpg123_handle *mh
static int bad_init(mpg123_handle *mh) bugger_off static void bad_close(mpg123_handle *mh)
Definition: readers.c:903
static ssize_t bad_fullread(mpg123_handle *mh, unsigned char *data, ssize_t count) bugger_off static int bad_head_read(mpg123_handle *mh

Definition at line 1020 of file readers.c.

Referenced by open_bad().

◆ readers

struct reader readers[]
static

Definition at line 921 of file readers.c.

Referenced by default_init(), open_feed(), open_finish(), SCardListReadersA(), and SCardListReadersW().