ReactOS  0.4.14-dev-49-gfb4591c
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 889 of file readers.c.

◆ O_BINARY

#define O_BINARY   (0)

◆ READER_BUF_ICY_STREAM

#define READER_BUF_ICY_STREAM   4

Definition at line 907 of file readers.c.

◆ READER_BUF_STREAM

#define READER_BUF_STREAM   3

Definition at line 906 of file readers.c.

◆ READER_FEED

#define READER_FEED   2

Definition at line 905 of file readers.c.

◆ READER_ICY_STREAM

#define READER_ICY_STREAM   1

Definition at line 904 of file readers.c.

◆ READER_STREAM

#define READER_STREAM   0

Definition at line 903 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 890 of file readers.c.

891  {}

◆ 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 898 of file readers.c.

900  {}

◆ bc_add()

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

Definition at line 625 of file readers.c.

626 {
627  int ret = 0;
628  ssize_t part = 0;
629  debug2("bc_add: adding %"SSIZE_P" bytes at %"OFF_P, (ssize_p)size, (off_p)(bc->fileoff+bc->size));
630  if(size >=4) debug4("first bytes: %02x %02x %02x %02x", data[0], data[1], data[2], data[3]);
631 
632  while(size > 0)
633  {
634  /* Try to fill up the last buffer block. */
635  if(bc->last != NULL && bc->last->size < bc->last->realsize)
636  {
637  part = bc->last->realsize - bc->last->size;
638  if(part > size) part = size;
639 
640  debug2("bc_add: adding %"SSIZE_P" B to existing block %p", (ssize_p)part, (void*)bc->last);
641  memcpy(bc->last->data+bc->last->size, data, part);
642  bc->last->size += part;
643  size -= part;
644  bc->size += part;
645  data += part;
646  }
647 
648  /* If there is still data left, put it into a new buffer block. */
649  if(size > 0 && (ret = bc_append(bc, size)) != 0)
650  break;
651  }
652 
653  return ret;
654 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
#define debug4(s, a, b, c, d)
Definition: debug.h:55
#define debug2(s, a, b)
Definition: debug.h:53
static int bc_append(struct bufferchain *bc, ssize_t size)
Definition: readers.c:608
smooth NULL
Definition: ftsmooth.c:416
GLsizeiptr size
Definition: glext.h:5919
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define SSIZE_P
Definition: compat.h:145
int ret
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
int ssize_t
Definition: rosdhcp.h:48
long off_p
Definition: compat.h:130
long ssize_p
Definition: compat.h:146
#define OFF_P
Definition: compat.h:129

Referenced by buffered_fullread(), and feed_more().

◆ bc_alloc()

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

Definition at line 523 of file readers.c.

524 {
525  /* Easy route: Just try the first available buffer.
526  Size does not matter, it's only a hint for creation of new buffers. */
527  if(bc->pool)
528  {
529  struct buffy *buf = bc->pool;
530  bc->pool = buf->next;
531  buf->next = NULL; /* That shall be set to a sensible value later. */
532  buf->size = 0;
533  --bc->pool_fill;
534  debug2("bc_alloc: picked %p from pool (fill now %"SIZE_P")", (void*)buf, (size_p)bc->pool_fill);
535  return buf;
536  }
537  else return buffy_new(size, bc->bufblock);
538 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
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:458
#define debug2(s, a, b)
Definition: debug.h:53
smooth NULL
Definition: ftsmooth.c:416
unsigned long size_p
Definition: compat.h:138
GLsizeiptr size
Definition: glext.h:5919
#define SIZE_P
Definition: compat.h:137
Definition: reader.h:16

Referenced by bc_append().

◆ bc_append()

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

Definition at line 608 of file readers.c.

609 {
610  struct buffy *newbuf;
611  if(size < 1) return -1;
612 
613  newbuf = bc_alloc(bc, size);
614  if(newbuf == NULL) return -2;
615 
616  if(bc->last != NULL) bc->last->next = newbuf;
617  else if(bc->first == NULL) bc->first = newbuf;
618 
619  bc->last = newbuf;
620  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);
621  return 0;
622 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
#define debug3(s, a, b, c)
Definition: debug.h:54
smooth NULL
Definition: ftsmooth.c:416
GLsizeiptr size
Definition: glext.h:5919
#define SSIZE_P
Definition: compat.h:145
Definition: reader.h:16
long ssize_p
Definition: compat.h:146
static struct buffy * bc_alloc(struct bufferchain *bc, size_t size)
Definition: readers.c:523

Referenced by bc_add().

◆ bc_cleanup()

void bc_cleanup ( struct bufferchain bc)

Definition at line 515 of file readers.c.

516 {
517  buffy_del_chain(bc->pool);
518  bc->pool = NULL;
519  bc->pool_fill = 0;
520 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
smooth NULL
Definition: ftsmooth.c:416
static void buffy_del_chain(struct buffy *buf)
Definition: readers.c:486

◆ bc_fill()

size_t bc_fill ( struct bufferchain bc)

Definition at line 504 of file readers.c.

505 {
506  return (size_t)(bc->size - bc->pos);
507 }
LPBATCH_CONTEXT bc
Definition: batch.c:66

◆ bc_fill_pool()

static int bc_fill_pool ( struct bufferchain bc)
static

Definition at line 555 of file readers.c.

556 {
557  /* Remove superfluous ones. */
558  while(bc->pool_fill > bc->pool_size)
559  {
560  /* Lazyness: Just work on the front. */
561  struct buffy* buf = bc->pool;
562  bc->pool = buf->next;
563  buffy_del(buf);
564  --bc->pool_fill;
565  }
566 
567  /* Add missing ones. */
568  while(bc->pool_fill < bc->pool_size)
569  {
570  /* Again, just work on the front. */
571  struct buffy* buf;
572  buf = buffy_new(0, bc->bufblock); /* Use default block size. */
573  if(!buf) return -1;
574 
575  buf->next = bc->pool;
576  bc->pool = buf;
577  ++bc->pool_fill;
578  }
579 
580  return 0;
581 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
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:458
static void buffy_del(struct buffy *buf)
Definition: readers.c:476
Definition: reader.h:16

Referenced by bc_reset(), and feed_init().

◆ bc_forget()

static void bc_forget ( struct bufferchain bc)
static

Definition at line 722 of file readers.c.

723 {
724  struct buffy *b = bc->first;
725  /* free all buffers that are def'n'tly outdated */
726  /* we have buffers until filepos... delete all buffers fully below it */
727  if(b) debug2("bc_forget: block %lu pos %lu", (unsigned long)b->size, (unsigned long)bc->pos);
728  else debug("forget with nothing there!");
729 
730  while(b != NULL && bc->pos >= b->size)
731  {
732  struct buffy *n = b->next; /* != NULL or this is indeed the end and the last cycle anyway */
733  if(n == NULL) bc->last = NULL; /* Going to delete the last buffy... */
734  bc->fileoff += b->size;
735  bc->pos -= b->size;
736  bc->size -= b->size;
737 
738  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);
739 
740  bc_free(bc, b);
741  b = n;
742  }
743  bc->first = b;
744  bc->firstpos = bc->pos;
745 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
static void bc_free(struct bufferchain *bc, struct buffy *buf)
Definition: readers.c:541
GLdouble n
Definition: glext.h:7729
#define debug2(s, a, b)
Definition: debug.h:53
smooth NULL
Definition: ftsmooth.c:416
#define b
Definition: ke_i.h:79
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
struct buffy * next
Definition: reader.h:21
Definition: reader.h:16
#define debug(msg)
Definition: key_call.c:71
#define debug5(s, a, b, c, d, e)
Definition: debug.h:56

Referenced by buffered_forget().

◆ bc_free()

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

Definition at line 541 of file readers.c.

542 {
543  if(!buf) return;
544 
545  if(bc->pool_fill < bc->pool_size)
546  {
547  buf->next = bc->pool;
548  bc->pool = buf;
549  ++bc->pool_fill;
550  }
551  else buffy_del(buf);
552 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static void buffy_del(struct buffy *buf)
Definition: readers.c:476

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 666 of file readers.c.

667 {
668  struct buffy *b = bc->first;
669  ssize_t gotcount = 0;
670  ssize_t offset = 0;
671  if(bc->size - bc->pos < size) return bc_need_more(bc);
672 
673  /* find the current buffer */
674  while(b != NULL && (offset + b->size) <= bc->pos)
675  {
676  offset += b->size;
677  b = b->next;
678  }
679  /* now start copying from there */
680  while(gotcount < size && (b != NULL))
681  {
682  ssize_t loff = bc->pos - offset;
683  ssize_t chunk = size - gotcount; /* amount of bytes to get from here... */
684  if(chunk > b->size - loff) chunk = b->size - loff;
685 
686 #ifdef EXTRA_DEBUG
687  debug3("copying %liB from %p+%li",(long)chunk, b->data, (long)loff);
688 #endif
689 
690  memcpy(out+gotcount, b->data+loff, chunk);
691  gotcount += chunk;
692  bc->pos += chunk;
693  offset += b->size;
694  b = b->next;
695  }
696 #ifdef EXTRA_DEBUG
697  debug2("got %li bytes, pos advanced to %li", (long)gotcount, (long)bc->pos);
698 #endif
699 
700  return gotcount;
701 }
uint16_t size
Definition: btrfs_drv.h:550
LPBATCH_CONTEXT bc
Definition: batch.c:66
GLintptr offset
Definition: glext.h:5920
#define debug2(s, a, b)
Definition: debug.h:53
#define debug3(s, a, b, c)
Definition: debug.h:54
smooth NULL
Definition: ftsmooth.c:416
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLsizeiptr size
Definition: glext.h:5919
static FILE * out
Definition: regtests2xml.c:44
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
int ssize_t
Definition: rosdhcp.h:48
Definition: reader.h:16
static ssize_t bc_need_more(struct bufferchain *bc)
Definition: readers.c:657

Referenced by buffered_fullread(), and feed_read().

◆ bc_init()

static void bc_init ( struct bufferchain bc)
static

Definition at line 584 of file readers.c.

585 {
586  bc->first = NULL;
587  bc->last = bc->first;
588  bc->size = 0;
589  bc->pos = 0;
590  bc->firstpos = 0;
591  bc->fileoff = 0;
592 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
smooth NULL
Definition: ftsmooth.c:416

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 657 of file readers.c.

658 {
659  debug3("hit end, back to beginning (%li - %li < %li)", (long)bc->size, (long)bc->pos, (long)bc->size);
660  /* go back to firstpos, undo the previous reads */
661  bc->pos = bc->firstpos;
662  return READER_MORE;
663 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
#define debug3(s, a, b, c)
Definition: debug.h:54
#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 509 of file readers.c.

510 {
511  bc->pool_size = pool_size;
512  bc->bufblock = bufblock;
513 }
LPBATCH_CONTEXT bc
Definition: batch.c:66

Referenced by bc_prepare().

◆ bc_prepare()

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

Definition at line 496 of file readers.c.

497 {
498  bc_poolsize(bc, pool_size, bufblock);
499  bc->pool = NULL;
500  bc->pool_fill = 0;
501  bc_init(bc); /* Ensure that members are zeroed for read-only use. */
502 }
void bc_poolsize(struct bufferchain *bc, size_t pool_size, size_t bufblock)
Definition: readers.c:509
LPBATCH_CONTEXT bc
Definition: batch.c:66
smooth NULL
Definition: ftsmooth.c:416
static void bc_init(struct bufferchain *bc)
Definition: readers.c:584

◆ bc_reset()

static void bc_reset ( struct bufferchain bc)
static

Definition at line 594 of file readers.c.

595 {
596  /* Free current chain, possibly stuffing back into the pool. */
597  while(bc->first)
598  {
599  struct buffy* buf = bc->first;
600  bc->first = buf->next;
601  bc_free(bc, buf);
602  }
603  bc_fill_pool(bc); /* Ignoring an error here... */
604  bc_init(bc);
605 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static void bc_free(struct bufferchain *bc, struct buffy *buf)
Definition: readers.c:541
static int bc_fill_pool(struct bufferchain *bc)
Definition: readers.c:555
static void bc_init(struct bufferchain *bc)
Definition: readers.c:584
Definition: reader.h:16

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 715 of file readers.c.

716 {
717  if(count >= 0 && count <= bc->pos) return bc->pos -= count;
718  else return READER_ERROR;
719 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
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 705 of file readers.c.

706 {
707  if(count >= 0)
708  {
709  if(bc->size - bc->pos < count) return bc_need_more(bc);
710  else return bc->pos += count;
711  }
712  else return READER_ERROR;
713 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define READER_ERROR
Definition: reader.h:134
static ssize_t bc_need_more(struct bufferchain *bc)
Definition: readers.c:657

Referenced by feed_skip_bytes().

◆ buffered_forget()

static void buffered_forget ( mpg123_handle fr)
static

Definition at line 804 of file readers.c.

805 {
806  bc_forget(&fr->rdat.buffer);
807  fr->rdat.filepos = fr->rdat.buffer.fileoff + fr->rdat.buffer.pos;
808 }
static void bc_forget(struct bufferchain *bc)
Definition: readers.c:722
struct reader_data rdat
Definition: frame.h:286

◆ buffered_fullread()

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

Definition at line 830 of file readers.c.

831 {
832  struct bufferchain *bc = &fr->rdat.buffer;
833  ssize_t gotcount;
834  if(bc->size - bc->pos < count)
835  { /* Add more stuff to buffer. If hitting end of file, adjust count. */
836  unsigned char readbuf[4096];
837  ssize_t need = count - (bc->size-bc->pos);
838  while(need>0)
839  {
840  int ret;
841  ssize_t got = fr->rdat.fullread(fr, readbuf, sizeof(readbuf));
842  if(got < 0)
843  {
844  if(NOQUIET) error("buffer reading");
845  return READER_ERROR;
846  }
847 
848  if(VERBOSE3) debug1("buffered_fullread: buffering %li bytes from stream (if > 0)", (long)got);
849  if(got > 0 && (ret=bc_add(bc, readbuf, got)) != 0)
850  {
851  if(NOQUIET) error1("unable to add to chain, return: %i", ret);
852  return READER_ERROR;
853  }
854 
855  need -= got; /* May underflow here... */
856  if(got < sizeof(readbuf)) /* That naturally catches got == 0, too. */
857  {
858  if(VERBOSE3) fprintf(stderr, "Note: Input data end.\n");
859  break; /* End. */
860  }
861  }
862  if(bc->size - bc->pos < count)
863  count = bc->size - bc->pos; /* We want only what we got. */
864  }
865  gotcount = bc_give(bc, out, count);
866 
867  if(VERBOSE3) debug2("wanted %li, got %li", (long)count, (long)gotcount);
868 
869  if(gotcount != count){ if(NOQUIET) error("gotcount != count"); return READER_ERROR; }
870  else return gotcount;
871 }
#define error(str)
Definition: mkdosfs.c:1605
LPBATCH_CONTEXT bc
Definition: batch.c:66
#define error1(s, a)
Definition: debug.h:109
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define debug2(s, a, b)
Definition: debug.h:53
struct reader_data rdat
Definition: frame.h:286
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define READER_ERROR
Definition: reader.h:134
#define VERBOSE3
static FILE * out
Definition: regtests2xml.c:44
#define NOQUIET
int ret
int ssize_t
Definition: rosdhcp.h:48
static ssize_t bc_give(struct bufferchain *bc, unsigned char *out, ssize_t size)
Definition: readers.c:666
static int bc_add(struct bufferchain *bc, const unsigned char *data, ssize_t size)
Definition: readers.c:625
FILE * stderr
#define debug1(s, a)
Definition: debug.h:52
static UINT PSTR DWORD UINT * need
Definition: parser.c:36

◆ buffy_del()

static void buffy_del ( struct buffy buf)
static

Definition at line 476 of file readers.c.

477 {
478  if(buf)
479  {
480  free(buf->data);
481  free(buf);
482  }
483 }
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#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 486 of file readers.c.

487 {
488  while(buf)
489  {
490  struct buffy* next = buf->next;
491  buffy_del(buf);
492  buf = next;
493  }
494 }
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static void buffy_del(struct buffy *buf)
Definition: readers.c:476
static unsigned __int64 next
Definition: rand_nt.c:6
Definition: reader.h:16

Referenced by bc_cleanup().

◆ buffy_new()

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

Definition at line 458 of file readers.c.

459 {
460  struct buffy *newbuf;
461  newbuf = malloc(sizeof(struct buffy));
462  if(newbuf == NULL) return NULL;
463 
464  newbuf->realsize = size > minsize ? size : minsize;
465  newbuf->data = malloc(newbuf->realsize);
466  if(newbuf->data == NULL)
467  {
468  free(newbuf);
469  return NULL;
470  }
471  newbuf->size = 0;
472  newbuf->next = NULL;
473  return newbuf;
474 }
unsigned char * data
Definition: reader.h:18
#define free
Definition: debug_ros.c:5
ssize_t realsize
Definition: reader.h:20
smooth NULL
Definition: ftsmooth.c:416
GLsizeiptr size
Definition: glext.h:5919
ssize_t size
Definition: reader.h:19
struct buffy * next
Definition: reader.h:21
Definition: reader.h:16
#define malloc
Definition: debug_ros.c:4

Referenced by bc_alloc(), and bc_fill_pool().

◆ default_init()

static int default_init ( mpg123_handle fr)
static

Definition at line 1023 of file readers.c.

1024 {
1025 #ifdef TIMEOUT_READ
1026  if(fr->p.timeout > 0)
1027  {
1028  int flags;
1029  if(fr->rdat.r_read != NULL)
1030  {
1031  error("Timeout reading does not work with user-provided read function. Implement it yourself!");
1032  return -1;
1033  }
1034  flags = fcntl(fr->rdat.filept, F_GETFL);
1035  flags |= O_NONBLOCK;
1036  fcntl(fr->rdat.filept, F_SETFL, flags);
1037  fr->rdat.fdread = timeout_read;
1038  fr->rdat.timeout_sec = fr->p.timeout;
1039  fr->rdat.flags |= READER_NONBLOCK;
1040  }
1041  else
1042 #endif
1043  fr->rdat.fdread = plain_read;
1044 
1045  fr->rdat.read = fr->rdat.r_read != NULL ? fr->rdat.r_read : posix_read;
1046  fr->rdat.lseek = fr->rdat.r_lseek != NULL ? fr->rdat.r_lseek : posix_lseek;
1047 #ifndef NO_ICY
1048  /* ICY streams of any sort shall not be seekable. */
1049  if(fr->p.icy_interval > 0) fr->rdat.lseek = nix_lseek;
1050 #endif
1051 
1052  fr->rdat.filelen = fr->p.flags & MPG123_NO_PEEK_END ? -1 : get_fileinfo(fr);
1053  fr->rdat.filepos = 0;
1054  if(fr->p.flags & MPG123_FORCE_SEEKABLE)
1055  fr->rdat.flags |= READER_SEEKABLE;
1056  /*
1057  Don't enable seeking on ICY streams, just plain normal files.
1058  This check is necessary since the client can enforce ICY parsing on files that would otherwise be seekable.
1059  It is a task for the future to make the ICY parsing safe with seeks ... or not.
1060  */
1061  if(fr->rdat.filelen >= 0)
1062  {
1063  fr->rdat.flags |= READER_SEEKABLE;
1064  if(!strncmp((char*)fr->id3buf,"TAG",3))
1065  {
1066  fr->rdat.flags |= READER_ID3TAG;
1067  fr->metaflags |= MPG123_NEW_ID3;
1068  }
1069  }
1070  /* Switch reader to a buffered one, if allowed. */
1071  else if(fr->p.flags & MPG123_SEEKBUFFER)
1072  {
1073 #ifdef NO_FEEDER
1074  error("Buffered readers not supported in this build.");
1076  return -1;
1077 #else
1078  if (fr->rd == &readers[READER_STREAM])
1079  {
1080  fr->rd = &readers[READER_BUF_STREAM];
1081  fr->rdat.fullread = plain_fullread;
1082  }
1083 #ifndef NO_ICY
1084  else if(fr->rd == &readers[READER_ICY_STREAM])
1085  {
1087  fr->rdat.fullread = icy_fullread;
1088  }
1089 #endif
1090  else
1091  {
1092  if(NOQUIET) error("mpg123 Programmer's fault: invalid reader");
1093  return -1;
1094  }
1095  bc_init(&fr->rdat.buffer);
1096  fr->rdat.filelen = 0; /* We carry the offset, but never know how big the stream is. */
1097  fr->rdat.flags |= READER_BUFFERED;
1098 #endif /* NO_FEEDER */
1099  }
1100  return 0;
1101 }
#define READER_SEEKABLE
Definition: reader.h:115
#define READER_BUF_ICY_STREAM
Definition: readers.c:907
static off_t nix_lseek(int fd, off_t offset, int whence)
Definition: readers.c:33
struct mpg123_pars_struct p
Definition: frame.h:287
#define error(str)
Definition: mkdosfs.c:1605
static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count)
Definition: readers.c:91
#define O_NONBLOCK
Definition: port.h:158
#define READER_NONBLOCK
Definition: reader.h:117
struct reader_data rdat
Definition: frame.h:286
static off_t posix_lseek(int fd, off_t offset, int whence)
Definition: readers.c:32
static ssize_t plain_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count)
Definition: readers.c:201
#define MPG123_NEW_ID3
Definition: mpg123.h:1241
smooth NULL
Definition: ftsmooth.c:416
static ssize_t posix_read(int fd, void *buf, size_t count)
Definition: readers.c:31
#define READER_ID3TAG
Definition: reader.h:114
static struct reader readers[]
Definition: readers.c:908
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
GLbitfield flags
Definition: glext.h:7161
#define NOQUIET
static void bc_init(struct bufferchain *bc)
Definition: readers.c:584
#define READER_STREAM
Definition: readers.c:903
#define READER_BUFFERED
Definition: reader.h:116
#define READER_ICY_STREAM
Definition: readers.c:904
unsigned char id3buf[128]
Definition: frame.h:294
static ssize_t plain_read(mpg123_handle *fr, void *buf, size_t count)
Definition: readers.c:57
#define READER_BUF_STREAM
Definition: readers.c:906
struct reader * rd
Definition: frame.h:285
static off_t get_fileinfo(mpg123_handle *)
Definition: readers.c:435

◆ feed_back_bytes()

static int feed_back_bytes ( mpg123_handle fr,
off_t  bytes 
)
static

Definition at line 793 of file readers.c.

794 {
795  if(bytes >=0)
796  return bc_seekback(&fr->rdat.buffer, (ssize_t)bytes) >= 0 ? 0 : READER_ERROR;
797  else
798  return feed_skip_bytes(fr, -bytes) >= 0 ? 0 : READER_ERROR;
799 }
static ssize_t bc_seekback(struct bufferchain *bc, ssize_t count)
Definition: readers.c:715
static off_t feed_skip_bytes(mpg123_handle *fr, off_t len)
Definition: readers.c:784
struct reader_data rdat
Definition: frame.h:286
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define READER_ERROR
Definition: reader.h:134
int ssize_t
Definition: rosdhcp.h:48

◆ feed_init()

static int feed_init ( mpg123_handle fr)
static

Definition at line 749 of file readers.c.

750 {
751  bc_init(&fr->rdat.buffer);
752  bc_fill_pool(&fr->rdat.buffer);
753  fr->rdat.filelen = 0;
754  fr->rdat.filepos = 0;
755  fr->rdat.flags |= READER_BUFFERED;
756  return 0;
757 }
struct reader_data rdat
Definition: frame.h:286
static int bc_fill_pool(struct bufferchain *bc)
Definition: readers.c:555
static void bc_init(struct bufferchain *bc)
Definition: readers.c:584
#define READER_BUFFERED
Definition: reader.h:116

◆ feed_more()

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

Definition at line 760 of file readers.c.

761 {
762  int ret = 0;
763  if(VERBOSE3) debug("feed_more");
764  if((ret = bc_add(&fr->rdat.buffer, in, count)) != 0)
765  {
766  ret = READER_ERROR;
767  if(NOQUIET) error1("Failed to add buffer, return: %i", ret);
768  }
769  else /* Not talking about filelen... that stays at 0. */
770 
771  if(VERBOSE3) debug3("feed_more: %p %luB bufsize=%lu", fr->rdat.buffer.last->data,
772  (unsigned long)fr->rdat.buffer.last->size, (unsigned long)fr->rdat.buffer.size);
773  return ret;
774 }
#define error1(s, a)
Definition: debug.h:109
GLuint GLuint GLsizei count
Definition: gl.h:1545
struct reader_data rdat
Definition: frame.h:286
#define debug3(s, a, b, c)
Definition: debug.h:54
#define READER_ERROR
Definition: reader.h:134
#define VERBOSE3
#define NOQUIET
int ret
GLuint in
Definition: glext.h:9616
static int bc_add(struct bufferchain *bc, const unsigned char *data, ssize_t size)
Definition: readers.c:625
#define debug(msg)
Definition: key_call.c:71

◆ feed_read()

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

Definition at line 776 of file readers.c.

777 {
778  ssize_t gotcount = bc_give(&fr->rdat.buffer, out, count);
779  if(gotcount >= 0 && gotcount != count) return READER_ERROR;
780  else return gotcount;
781 }
GLuint GLuint GLsizei count
Definition: gl.h:1545
struct reader_data rdat
Definition: frame.h:286
#define READER_ERROR
Definition: reader.h:134
static FILE * out
Definition: regtests2xml.c:44
int ssize_t
Definition: rosdhcp.h:48
static ssize_t bc_give(struct bufferchain *bc, unsigned char *out, ssize_t size)
Definition: readers.c:666

◆ feed_seek_frame()

static int feed_seek_frame ( mpg123_handle fr,
off_t  num 
)
static

Definition at line 801 of file readers.c.

801 { return READER_ERROR; }
#define READER_ERROR
Definition: reader.h:134

◆ feed_set_pos()

off_t feed_set_pos ( mpg123_handle fr,
off_t  pos 
)

Definition at line 810 of file readers.c.

811 {
812  struct bufferchain *bc = &fr->rdat.buffer;
813  if(pos >= bc->fileoff && pos-bc->fileoff < bc->size)
814  { /* We have the position! */
815  bc->pos = (ssize_t)(pos - bc->fileoff);
816  debug1("feed_set_pos inside, next feed from %"OFF_P, (off_p)(bc->fileoff+bc->size));
817  return bc->fileoff+bc->size; /* Next input after end of buffer... */
818  }
819  else
820  { /* I expect to get the specific position on next feed. Forget what I have now. */
821  bc_reset(bc);
822  bc->fileoff = pos;
823  debug1("feed_set_pos outside, buffer reset, next feed from %"OFF_P, (off_p)pos);
824  return pos; /* Next input from exactly that position. */
825  }
826 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
#define ssize_t
Definition: config.h:469
struct reader_data rdat
Definition: frame.h:286
static void bc_reset(struct bufferchain *bc)
Definition: readers.c:594
long off_p
Definition: compat.h:130
#define debug1(s, a)
Definition: debug.h:52
#define OFF_P
Definition: compat.h:129

◆ feed_skip_bytes()

static off_t feed_skip_bytes ( mpg123_handle fr,
off_t  len 
)
static

Definition at line 784 of file readers.c.

785 {
786  /* This is either the new buffer offset or some negative error value. */
787  off_t res = bc_skip(&fr->rdat.buffer, (ssize_t)len);
788  if(res < 0) return res;
789 
790  return fr->rdat.buffer.fileoff+res;
791 }
static ssize_t bc_skip(struct bufferchain *bc, ssize_t count)
Definition: readers.c:705
__kernel_off_t off_t
Definition: linux.h:201
struct reader_data rdat
Definition: frame.h:286
GLenum GLsizei len
Definition: glext.h:6722
int ssize_t
Definition: rosdhcp.h:48
GLuint res
Definition: glext.h:9613

Referenced by feed_back_bytes().

◆ generic_head_read()

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

Definition at line 302 of file readers.c.

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

◆ generic_head_shift()

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

Definition at line 318 of file readers.c.

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

◆ generic_read_frame_body()

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

Definition at line 387 of file readers.c.

388 {
389  long l;
390 
391  if((l=fr->rd->fullread(fr,buf,size)) != size)
392  {
393  long ll = l;
394  if(ll <= 0) ll = 0;
395  return READER_MORE;
396  }
397  return l;
398 }
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
r l[0]
Definition: byte_order.h:167
#define READER_MORE
Definition: reader.h:135
GLsizeiptr size
Definition: glext.h:5919
w ll
Definition: byte_order.h:166
struct reader * rd
Definition: frame.h:285

◆ generic_tell()

static off_t generic_tell ( mpg123_handle fr)
static

Definition at line 400 of file readers.c.

401 {
402 #ifndef NO_FEEDER
403  if(fr->rdat.flags & READER_BUFFERED)
404  fr->rdat.filepos = fr->rdat.buffer.fileoff+fr->rdat.buffer.pos;
405 #endif
406 
407  return fr->rdat.filepos;
408 }
struct reader_data rdat
Definition: frame.h:286
#define READER_BUFFERED
Definition: reader.h:116

◆ get_fileinfo()

static off_t get_fileinfo ( mpg123_handle fr)
static

Definition at line 435 of file readers.c.

436 {
437  off_t len;
438 
439  if((len=io_seek(&fr->rdat,0,SEEK_END)) < 0) return -1;
440 
441  if(io_seek(&fr->rdat,-128,SEEK_END) < 0) return -1;
442 
443  if(fr->rd->fullread(fr,(unsigned char *)fr->id3buf,128) != 128) return -1;
444 
445  if(!strncmp((char*)fr->id3buf,"TAG",3)) len -= 128;
446 
447  if(io_seek(&fr->rdat,0,SEEK_SET) < 0) return -1;
448 
449  if(len <= 0) return -1;
450 
451  return len;
452 }
__kernel_off_t off_t
Definition: linux.h:201
struct reader_data rdat
Definition: frame.h:286
static off_t io_seek(struct reader_data *rdat, off_t offset, int whence)
Definition: readers.c:1211
#define SEEK_SET
Definition: jmemansi.c:26
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
GLenum GLsizei len
Definition: glext.h:6722
unsigned char id3buf[128]
Definition: frame.h:294
#define SEEK_END
Definition: cabinet.c:27
struct reader * rd
Definition: frame.h:285

Referenced by default_init().

◆ icy_fullread()

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

Definition at line 91 of file readers.c.

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

Referenced by default_init().

◆ io_read()

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

Definition at line 1225 of file readers.c.

1226 {
1227  if(rdat->flags & READER_HANDLEIO)
1228  {
1229  if(rdat->r_read_handle != NULL)
1230  {
1231  return rdat->r_read_handle(rdat->iohandle, buf, count);
1232  }
1233  else return -1;
1234  }
1235  else
1236  return rdat->read(rdat->filept, buf, count);
1237 }
int filept
Definition: reader.h:57
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLuint GLsizei count
Definition: gl.h:1545
void * iohandle
Definition: reader.h:59
smooth NULL
Definition: ftsmooth.c:416
int flags
Definition: reader.h:60
#define READER_HANDLEIO
Definition: reader.h:118
ssize_t(* read)(int fd, void *buf, size_t count)
Definition: reader.h:73
ssize_t(* r_read_handle)(void *handle, void *buf, size_t count)
Definition: reader.h:68

Referenced by plain_read().

◆ io_seek()

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

Definition at line 1211 of file readers.c.

1212 {
1213  if(rdat->flags & READER_HANDLEIO)
1214  {
1215  if(rdat->r_lseek_handle != NULL)
1216  {
1217  return rdat->r_lseek_handle(rdat->iohandle, offset, whence);
1218  }
1219  else return -1;
1220  }
1221  else
1222  return rdat->lseek(rdat->filept, offset, whence);
1223 }
int filept
Definition: reader.h:57
GLintptr offset
Definition: glext.h:5920
void * iohandle
Definition: reader.h:59
smooth NULL
Definition: ftsmooth.c:416
int flags
Definition: reader.h:60
#define READER_HANDLEIO
Definition: reader.h:118
off_t(* r_lseek_handle)(void *handle, off_t offset, int whence)
Definition: reader.h:69
off_t(* lseek)(int fd, off_t offset, int whence)
Definition: reader.h:74

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 33 of file readers.c.

33 { return -1; }

Referenced by default_init().

◆ open_bad()

void open_bad ( mpg123_handle mh)

Definition at line 1104 of file readers.c.

1105 {
1106  debug("open_bad");
1107 #ifndef NO_ICY
1108  clear_icy(&mh->icy);
1109 #endif
1110  mh->rd = &bad_reader;
1111  mh->rdat.flags = 0;
1112 #ifndef NO_FEEDER
1113  bc_init(&mh->rdat.buffer);
1114 #endif
1115  mh->rdat.filelen = -1;
1116 }
struct reader_data rdat
Definition: frame.h:286
struct icy_meta icy
Definition: frame.h:299
static void bc_init(struct bufferchain *bc)
Definition: readers.c:584
static struct reader bad_reader
Definition: readers.c:1007
#define clear_icy
Definition: intsym.h:199
#define debug(msg)
Definition: key_call.c:71
struct reader * rd
Definition: frame.h:285

◆ open_feed()

int open_feed ( mpg123_handle fr)

Definition at line 1118 of file readers.c.

1119 {
1120  debug("feed reader");
1121 #ifdef NO_FEEDER
1122  error("Buffered readers not supported in this build.");
1124  return -1;
1125 #else
1126 #ifndef NO_ICY
1127  if(fr->p.icy_interval > 0)
1128  {
1129  if(NOQUIET) error("Feed reader cannot do ICY parsing!");
1130 
1131  return -1;
1132  }
1133  clear_icy(&fr->icy);
1134 #endif
1135  fr->rd = &readers[READER_FEED];
1136  fr->rdat.flags = 0;
1137  if(fr->rd->init(fr) < 0) return -1;
1138 
1139  debug("feed reader init successful");
1140  return 0;
1141 #endif /* NO_FEEDER */
1142 }
struct mpg123_pars_struct p
Definition: frame.h:287
#define error(str)
Definition: mkdosfs.c:1605
#define READER_FEED
Definition: readers.c:905
struct reader_data rdat
Definition: frame.h:286
struct icy_meta icy
Definition: frame.h:299
static struct reader readers[]
Definition: readers.c:908
#define NOQUIET
#define clear_icy
Definition: intsym.h:199
#define debug(msg)
Definition: key_call.c:71
struct reader * rd
Definition: frame.h:285

◆ open_finish()

static int open_finish ( mpg123_handle fr)
static

Definition at line 1145 of file readers.c.

1146 {
1147 #ifndef NO_ICY
1148  if(fr->p.icy_interval > 0)
1149  {
1150  debug("ICY reader");
1151  fr->icy.interval = fr->p.icy_interval;
1152  fr->icy.next = fr->icy.interval;
1153  fr->rd = &readers[READER_ICY_STREAM];
1154  }
1155  else
1156 #endif
1157  {
1158  fr->rd = &readers[READER_STREAM];
1159  debug("stream reader");
1160  }
1161 
1162  if(fr->rd->init(fr) < 0) return -1;
1163 
1164  return MPG123_OK;
1165 }
struct mpg123_pars_struct p
Definition: frame.h:287
struct icy_meta icy
Definition: frame.h:299
static struct reader readers[]
Definition: readers.c:908
#define READER_STREAM
Definition: readers.c:903
#define READER_ICY_STREAM
Definition: readers.c:904
#define debug(msg)
Definition: key_call.c:71
struct reader * rd
Definition: frame.h:285

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 1167 of file readers.c.

1168 {
1169  int filept_opened = 1;
1170  int filept; /* descriptor of opened file/stream */
1171 
1172  clear_icy(&fr->icy); /* can be done inside frame_clear ...? */
1173 
1174  if(!bs_filenam) /* no file to open, got a descriptor (stdin) */
1175  {
1176  filept = fd;
1177  filept_opened = 0; /* and don't try to close it... */
1178  }
1179  #ifndef O_BINARY
1180  #define O_BINARY (0)
1181  #endif
1182  else if((filept = compat_open(bs_filenam, O_RDONLY|O_BINARY)) < 0) /* a plain old file to open... */
1183  {
1184  if(NOQUIET) error2("Cannot open file %s: %s", bs_filenam, strerror(errno));
1185  fr->err = MPG123_BAD_FILE;
1186  return MPG123_ERR; /* error... */
1187  }
1188 
1189  /* now we have something behind filept and can init the reader */
1190  fr->rdat.filelen = -1;
1191  fr->rdat.filept = filept;
1192  fr->rdat.flags = 0;
1193  if(filept_opened) fr->rdat.flags |= READER_FD_OPENED;
1194 
1195  return open_finish(fr);
1196 }
static int open_finish(mpg123_handle *fr)
Definition: readers.c:1145
#define compat_open
Definition: intsym.h:12
#define O_BINARY
#define READER_FD_OPENED
Definition: reader.h:113
static int fd
Definition: io.c:51
int errno
const char * strerror(int err)
Definition: compat_str.c:23
struct reader_data rdat
Definition: frame.h:286
struct icy_meta icy
Definition: frame.h:299
#define error2(s, a, b)
Definition: debug.h:110
#define NOQUIET
#define clear_icy
Definition: intsym.h:199
#define O_RDONLY
Definition: acwin.h:108

◆ open_stream_handle()

int open_stream_handle ( mpg123_handle fr,
void iohandle 
)

Definition at line 1198 of file readers.c.

1199 {
1200  clear_icy(&fr->icy); /* can be done inside frame_clear ...? */
1201  fr->rdat.filelen = -1;
1202  fr->rdat.filept = -1;
1203  fr->rdat.iohandle = iohandle;
1204  fr->rdat.flags = 0;
1205  fr->rdat.flags |= READER_HANDLEIO;
1206 
1207  return open_finish(fr);
1208 }
static int open_finish(mpg123_handle *fr)
Definition: readers.c:1145
struct reader_data rdat
Definition: frame.h:286
struct icy_meta icy
Definition: frame.h:299
#define READER_HANDLEIO
Definition: reader.h:118
#define clear_icy
Definition: intsym.h:199

◆ plain_fullread()

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

Definition at line 201 of file readers.c.

202 {
203  ssize_t ret,cnt=0;
204 
205 #ifdef EXTRA_DEBUG
206  debug1("plain fullread of %"SSIZE_P, (size_p)count);
207 #endif
208  /*
209  There used to be a check for expected file end here (length value or ID3 flag).
210  This is not needed:
211  1. EOF is indicated by fdread returning zero bytes anyway.
212  2. We get false positives of EOF for either files that grew or
213  3. ... files that have ID3v1 tags in between (stream with intro).
214  */
215  while(cnt < count)
216  {
217  ret = fr->rdat.fdread(fr,buf+cnt,count-cnt);
218  if(ret < 0) return READER_ERROR;
219  if(ret == 0) break;
220  if(!(fr->rdat.flags & READER_BUFFERED)) fr->rdat.filepos += ret;
221  cnt += ret;
222  }
223  return cnt;
224 }
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLuint GLsizei count
Definition: gl.h:1545
struct reader_data rdat
Definition: frame.h:286
#define READER_ERROR
Definition: reader.h:134
unsigned long size_p
Definition: compat.h:138
#define SSIZE_P
Definition: compat.h:145
int ret
int ssize_t
Definition: rosdhcp.h:48
#define READER_BUFFERED
Definition: reader.h:116
#define debug1(s, a)
Definition: debug.h:52

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 57 of file readers.c.

58 {
59  ssize_t ret = io_read(&fr->rdat, buf, count);
60  if(VERBOSE3) debug2("read %li bytes of %li", (long)ret, (long)count);
61  return ret;
62 }
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define debug2(s, a, b)
Definition: debug.h:53
struct reader_data rdat
Definition: frame.h:286
#define VERBOSE3
int ret
int ssize_t
Definition: rosdhcp.h:48
static ssize_t io_read(struct reader_data *rdat, void *buf, size_t count)
Definition: readers.c:1225

Referenced by default_init().

◆ posix_lseek()

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

Definition at line 32 of file readers.c.

32 { return lseek(fd, offset, whence); }
GLintptr offset
Definition: glext.h:5920
static int fd
Definition: io.c:51
_Check_return_opt_ _CRTIMP long __cdecl lseek(_In_ int _FileHandle, _In_ long _Offset, _In_ int _Origin)

Referenced by default_init().

◆ posix_read()

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

Definition at line 31 of file readers.c.

31 { return read(fd, buf, count); }
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLuint GLsizei count
Definition: gl.h:1545
static int fd
Definition: io.c:51
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)

Referenced by default_init().

◆ stream_back_bytes()

static int stream_back_bytes ( mpg123_handle fr,
off_t  bytes 
)
static

Definition at line 376 of file readers.c.

377 {
378  off_t want = fr->rd->tell(fr)-bytes;
379  if(want < 0) return READER_ERROR;
380  if(stream_skip_bytes(fr,-bytes) != want) return READER_ERROR;
381 
382  return 0;
383 }
static off_t stream_skip_bytes(mpg123_handle *fr, off_t len)
Definition: readers.c:332
__kernel_off_t off_t
Definition: linux.h:201
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define READER_ERROR
Definition: reader.h:134
struct reader * rd
Definition: frame.h:285

◆ stream_close()

static void stream_close ( mpg123_handle fr)
static

Definition at line 239 of file readers.c.

240 {
241  if(fr->rdat.flags & READER_FD_OPENED) compat_close(fr->rdat.filept);
242 
243  fr->rdat.filept = 0;
244 
245 #ifndef NO_FEEDER
246  if(fr->rdat.flags & READER_BUFFERED) bc_reset(&fr->rdat.buffer);
247 #endif
248  if(fr->rdat.flags & READER_HANDLEIO)
249  {
250  if(fr->rdat.cleanup_handle != NULL) fr->rdat.cleanup_handle(fr->rdat.iohandle);
251 
252  fr->rdat.iohandle = NULL;
253  }
254 }
#define READER_FD_OPENED
Definition: reader.h:113
struct reader_data rdat
Definition: frame.h:286
static void bc_reset(struct bufferchain *bc)
Definition: readers.c:594
smooth NULL
Definition: ftsmooth.c:416
#define compat_close
Definition: intsym.h:15
#define READER_HANDLEIO
Definition: reader.h:118
#define READER_BUFFERED
Definition: reader.h:116

◆ stream_lseek()

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

Definition at line 226 of file readers.c.

227 {
228  off_t ret;
229  ret = io_seek(&fr->rdat, pos, whence);
230  if (ret >= 0) fr->rdat.filepos = ret;
231  else
232  {
233  fr->err = MPG123_LSEEK_FAILED;
234  ret = READER_ERROR; /* not the original value */
235  }
236  return ret;
237 }
__kernel_off_t off_t
Definition: linux.h:201
struct reader_data rdat
Definition: frame.h:286
#define READER_ERROR
Definition: reader.h:134
static off_t io_seek(struct reader_data *rdat, off_t offset, int whence)
Definition: readers.c:1211
int ret

Referenced by stream_rewind(), and stream_skip_bytes().

◆ stream_rewind()

static void stream_rewind ( mpg123_handle fr)
static

Definition at line 411 of file readers.c.

412 {
413  if(fr->rdat.flags & READER_SEEKABLE)
414  {
415  fr->rdat.filepos = stream_lseek(fr,0,SEEK_SET);
416 #ifndef NO_FEEDER
417  fr->rdat.buffer.fileoff = fr->rdat.filepos;
418 #endif
419  }
420 #ifndef NO_FEEDER
421  if(fr->rdat.flags & READER_BUFFERED)
422  {
423  fr->rdat.buffer.pos = 0;
424  fr->rdat.buffer.firstpos = 0;
425  fr->rdat.filepos = fr->rdat.buffer.fileoff;
426  }
427 #endif
428 }
#define READER_SEEKABLE
Definition: reader.h:115
struct reader_data rdat
Definition: frame.h:286
#define SEEK_SET
Definition: jmemansi.c:26
static off_t stream_lseek(mpg123_handle *fr, off_t pos, int whence)
Definition: readers.c:226
#define READER_BUFFERED
Definition: reader.h:116

◆ stream_seek_frame()

static int stream_seek_frame ( mpg123_handle fr,
off_t  newframe 
)
static

Definition at line 256 of file readers.c.

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

◆ stream_skip_bytes()

static off_t stream_skip_bytes ( mpg123_handle fr,
off_t  len 
)
static

Definition at line 332 of file readers.c.

333 {
334  if(fr->rdat.flags & READER_SEEKABLE)
335  {
337  return (ret < 0) ? READER_ERROR : ret;
338  }
339  else if(len >= 0)
340  {
341  unsigned char buf[1024]; /* ThOr: Compaq cxx complained and it makes sense to me... or should one do a cast? What for? */
342  ssize_t ret;
343  while (len > 0)
344  {
345  ssize_t num = len < (off_t)sizeof(buf) ? (ssize_t)len : (ssize_t)sizeof(buf);
346  ret = fr->rd->fullread(fr, buf, num);
347  if (ret < 0) return ret;
348  else if(ret == 0) break; /* EOF... an error? interface defined to tell the actual position... */
349  len -= ret;
350  }
351  return fr->rd->tell(fr);
352  }
353 #ifndef NO_FEEDER
354  else if(fr->rdat.flags & READER_BUFFERED)
355  { /* Perhaps we _can_ go a bit back. */
356  if(fr->rdat.buffer.pos >= -len)
357  {
358  fr->rdat.buffer.pos += len;
359  return fr->rd->tell(fr);
360  }
361  else
362  {
363  fr->err = MPG123_NO_SEEK;
364  return READER_ERROR;
365  }
366  }
367 #endif
368  else
369  {
370  fr->err = MPG123_NO_SEEK;
371  return READER_ERROR;
372  }
373 }
#define SEEK_CUR
Definition: util.h:63
#define READER_SEEKABLE
Definition: reader.h:115
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
__kernel_off_t off_t
Definition: linux.h:201
#define ssize_t
Definition: config.h:469
struct reader_data rdat
Definition: frame.h:286
#define READER_ERROR
Definition: reader.h:134
#define off_t
Definition: dosfsck.h:5
GLuint GLuint num
Definition: glext.h:9618
static off_t stream_lseek(mpg123_handle *fr, off_t pos, int whence)
Definition: readers.c:226
int ret
GLenum GLsizei len
Definition: glext.h:6722
int ssize_t
Definition: rosdhcp.h:48
#define READER_BUFFERED
Definition: reader.h:116
struct reader * rd
Definition: frame.h:285

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 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 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:898
static int bad_init(mpg123_handle *mh) bugger_off static void bad_close(mpg123_handle *mh)
Definition: readers.c:890
smooth NULL
Definition: ftsmooth.c:416
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

Definition at line 1007 of file readers.c.

Referenced by open_bad().

◆ readers

struct reader readers[]
static

Definition at line 908 of file readers.c.

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