ReactOS  0.4.15-dev-439-g292f67a
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 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
#define debug4(s, a, b, c, d)
Definition: debug.h:64
#define debug2(s, a, b)
Definition: debug.h:62
static int bc_append(struct bufferchain *bc, ssize_t size)
Definition: readers.c:620
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:147
int ret
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
int ssize_t
Definition: rosdhcp.h:48
long off_p
Definition: compat.h:132
long ssize_p
Definition: compat.h:148
#define OFF_P
Definition: compat.h:131

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 }
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:470
#define debug2(s, a, b)
Definition: debug.h:62
smooth NULL
Definition: ftsmooth.c:416
unsigned long size_p
Definition: compat.h:140
GLsizeiptr size
Definition: glext.h:5919
#define SIZE_P
Definition: compat.h:139
Definition: reader.h:16

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 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
#define debug3(s, a, b, c)
Definition: debug.h:63
smooth NULL
Definition: ftsmooth.c:416
GLsizeiptr size
Definition: glext.h:5919
#define SSIZE_P
Definition: compat.h:147
Definition: reader.h:16
long ssize_p
Definition: compat.h:148
static struct buffy * bc_alloc(struct bufferchain *bc, size_t size)
Definition: readers.c:535

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 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
smooth NULL
Definition: ftsmooth.c:416
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 }
LPBATCH_CONTEXT bc
Definition: batch.c:66

◆ 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 }
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:470
static void buffy_del(struct buffy *buf)
Definition: readers.c:488
Definition: reader.h:16

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 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
static void bc_free(struct bufferchain *bc, struct buffy *buf)
Definition: readers.c:553
GLdouble n
Definition: glext.h:7729
#define debug2(s, a, b)
Definition: debug.h:62
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:65

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 }
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:488

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 }
uint16_t size
Definition: btrfs_drv.h:572
LPBATCH_CONTEXT bc
Definition: batch.c:66
GLintptr offset
Definition: glext.h:5920
#define debug2(s, a, b)
Definition: debug.h:62
#define debug3(s, a, b, c)
Definition: debug.h:63
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:669

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 }
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 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 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
#define debug3(s, a, b, c)
Definition: debug.h:63
#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 }
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 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 }
void bc_poolsize(struct bufferchain *bc, size_t pool_size, size_t bufblock)
Definition: readers.c:521
LPBATCH_CONTEXT bc
Definition: batch.c:66
smooth NULL
Definition: ftsmooth.c:416
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 }
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:553
static int bc_fill_pool(struct bufferchain *bc)
Definition: readers.c:567
static void bc_init(struct bufferchain *bc)
Definition: readers.c:596
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 727 of file readers.c.

728 {
729  if(count >= 0 && count <= bc->pos) return bc->pos -= count;
730  else return READER_ERROR;
731 }
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 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 }
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:669

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 error(str)
Definition: mkdosfs.c:1605
LPBATCH_CONTEXT bc
Definition: batch.c:66
#define error1(s, a)
Definition: debug.h:125
GLuint GLuint GLsizei count
Definition: gl.h:1545
struct reader_data rdat
Definition: frame.h:288
_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
#define mdebug(s,...)
Definition: debug.h:58
int ssize_t
Definition: rosdhcp.h:48
static ssize_t bc_give(struct bufferchain *bc, unsigned char *out, ssize_t size)
Definition: readers.c:678
static int bc_add(struct bufferchain *bc, const unsigned char *data, ssize_t size)
Definition: readers.c:637
FILE * stderr
#define debug1(s, a)
Definition: debug.h:61
static UINT PSTR DWORD UINT * need
Definition: parser.c:36

◆ 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 }
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 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 }
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static void buffy_del(struct buffy *buf)
Definition: readers.c:488
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 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 }
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 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;
1083  fr->metaflags |= MPG123_NEW_ID3;
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");
1098  fr->rd = &readers[READER_BUF_STREAM];
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 }
#define READER_SEEKABLE
Definition: reader.h:115
#define READER_BUF_ICY_STREAM
Definition: readers.c:920
static off_t nix_lseek(int fd, off_t offset, int whence)
Definition: readers.c:34
struct mpg123_pars_struct p
Definition: frame.h:289
#define error(str)
Definition: mkdosfs.c:1605
static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count)
Definition: readers.c:92
#define O_NONBLOCK
Definition: port.h:158
#define READER_NONBLOCK
Definition: reader.h:117
struct reader_data rdat
Definition: frame.h:288
static off_t posix_lseek(int fd, off_t offset, int whence)
Definition: readers.c:33
static ssize_t plain_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count)
Definition: readers.c:202
#define MPG123_NEW_ID3
Definition: mpg123.h:1465
smooth NULL
Definition: ftsmooth.c:416
static ssize_t posix_read(int fd, void *buf, size_t count)
Definition: readers.c:32
#define READER_ID3TAG
Definition: reader.h:114
static struct reader readers[]
Definition: readers.c:921
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:596
#define READER_STREAM
Definition: readers.c:916
#define READER_BUFFERED
Definition: reader.h:116
#define READER_ICY_STREAM
Definition: readers.c:917
unsigned char id3buf[128]
Definition: frame.h:296
static ssize_t plain_read(mpg123_handle *fr, void *buf, size_t count)
Definition: readers.c:58
#define READER_BUF_STREAM
Definition: readers.c:919
#define debug(msg)
Definition: key_call.c:71
struct reader * rd
Definition: frame.h:287
static off_t get_fileinfo(mpg123_handle *)
Definition: readers.c:430

◆ 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 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
struct reader_data rdat
Definition: frame.h:288
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 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 }
struct reader_data rdat
Definition: frame.h:288
static int bc_fill_pool(struct bufferchain *bc)
Definition: readers.c:567
static void bc_init(struct bufferchain *bc)
Definition: readers.c:596
#define READER_BUFFERED
Definition: reader.h:116

◆ 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  {
778  ret = READER_ERROR;
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 }
#define error1(s, a)
Definition: debug.h:125
GLuint GLuint GLsizei count
Definition: gl.h:1545
struct reader_data rdat
Definition: frame.h:288
#define debug3(s, a, b, c)
Definition: debug.h:63
#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:637
#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 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 }
GLuint GLuint GLsizei count
Definition: gl.h:1545
struct reader_data rdat
Definition: frame.h:288
#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:678

◆ 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; }
#define READER_ERROR
Definition: reader.h:134

◆ 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 }
LPBATCH_CONTEXT bc
Definition: batch.c:66
#define ssize_t
Definition: config.h:511
struct reader_data rdat
Definition: frame.h:288
static void bc_reset(struct bufferchain *bc)
Definition: readers.c:606
long off_p
Definition: compat.h:132
#define debug1(s, a)
Definition: debug.h:61
#define OFF_P
Definition: compat.h:131

◆ 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 }
static ssize_t bc_skip(struct bufferchain *bc, ssize_t count)
Definition: readers.c:717
__kernel_off_t off_t
Definition: linux.h:201
struct reader_data rdat
Definition: frame.h:288
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 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 READER_MORE
Definition: reader.h:135
int ret
#define long
Definition: qsort.c:33
struct reader * rd
Definition: frame.h:287

◆ 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 }
#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:287

◆ 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 }
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define READER_ERROR
Definition: reader.h:134
r l[0]
Definition: byte_order.h:167
GLsizeiptr size
Definition: glext.h:5919
struct reader * rd
Definition: frame.h:287

◆ 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 }
struct reader_data rdat
Definition: frame.h:288
#define READER_BUFFERED
Definition: reader.h:116

◆ 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 }
__kernel_off_t off_t
Definition: linux.h:201
struct reader_data rdat
Definition: frame.h:288
static off_t io_seek(struct reader_data *rdat, off_t offset, int whence)
Definition: readers.c:1231
#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:296
long off_p
Definition: compat.h:132
#define SEEK_END
Definition: cabinet.c:27
#define debug(msg)
Definition: key_call.c:71
struct reader * rd
Definition: frame.h:287
#define debug1(s, a)
Definition: debug.h:61
#define OFF_P
Definition: compat.h:131

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;
173  fr->metaflags |= MPG123_NEW_ICY;
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 }
#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:125
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define free
Definition: debug_ros.c:5
#define debug2(s, a, b)
Definition: debug.h:62
struct reader_data rdat
Definition: frame.h:288
static ssize_t plain_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count)
Definition: readers.c:202
#define MPG123_NEW_ICY
Definition: mpg123.h:1467
struct icy_meta icy
Definition: frame.h:303
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:287
#define debug1(s, a)
Definition: debug.h:61

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 }
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 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 }
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 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 }
struct reader_data rdat
Definition: frame.h:288
struct icy_meta icy
Definition: frame.h:303
static void bc_init(struct bufferchain *bc)
Definition: readers.c:596
static struct reader bad_reader
Definition: readers.c:1020
#define clear_icy
Definition: intsym.h:209
#define debug(msg)
Definition: key_call.c:71
struct reader * rd
Definition: frame.h:287

◆ 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 }
struct mpg123_pars_struct p
Definition: frame.h:289
#define error(str)
Definition: mkdosfs.c:1605
#define READER_FEED
Definition: readers.c:918
struct reader_data rdat
Definition: frame.h:288
struct icy_meta icy
Definition: frame.h:303
static struct reader readers[]
Definition: readers.c:921
#define NOQUIET
#define clear_icy
Definition: intsym.h:209
#define debug(msg)
Definition: key_call.c:71
struct reader * rd
Definition: frame.h:287

◆ 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;
1173  fr->rd = &readers[READER_ICY_STREAM];
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 }
struct mpg123_pars_struct p
Definition: frame.h:289
struct icy_meta icy
Definition: frame.h:303
static struct reader readers[]
Definition: readers.c:921
#define READER_STREAM
Definition: readers.c:916
#define READER_ICY_STREAM
Definition: readers.c:917
#define debug(msg)
Definition: key_call.c:71
struct reader * rd
Definition: frame.h:287

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 }
static int open_finish(mpg123_handle *fr)
Definition: readers.c:1165
#define compat_open
Definition: intsym.h:13
#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:288
struct icy_meta icy
Definition: frame.h:303
#define error2(s, a, b)
Definition: debug.h:126
#define NOQUIET
#define clear_icy
Definition: intsym.h:209
#define O_RDONLY
Definition: acwin.h:108

◆ 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 }
static int open_finish(mpg123_handle *fr)
Definition: readers.c:1165
struct reader_data rdat
Definition: frame.h:288
struct icy_meta icy
Definition: frame.h:303
#define READER_HANDLEIO
Definition: reader.h:118
#define clear_icy
Definition: intsym.h:209

◆ 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 }
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:288
#define READER_ERROR
Definition: reader.h:134
unsigned long size_p
Definition: compat.h:140
#define SSIZE_P
Definition: compat.h:147
int ret
int ssize_t
Definition: rosdhcp.h:48
#define READER_BUFFERED
Definition: reader.h:116
#define debug1(s, a)
Definition: debug.h:61

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 }
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:62
struct reader_data rdat
Definition: frame.h:288
#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: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); }
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 32 of file readers.c.

32 { 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 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
__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:287

◆ 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 READER_FD_OPENED
Definition: reader.h:113
struct reader_data rdat
Definition: frame.h:288
static void bc_reset(struct bufferchain *bc)
Definition: readers.c:606
smooth NULL
Definition: ftsmooth.c:416
#define compat_close
Definition: intsym.h:16
#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 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  {
234  fr->err = MPG123_LSEEK_FAILED;
235  ret = READER_ERROR; /* not the original value */
236  }
237  return ret;
238 }
__kernel_off_t off_t
Definition: linux.h:201
struct reader_data rdat
Definition: frame.h:288
#define READER_ERROR
Definition: reader.h:134
static off_t io_seek(struct reader_data *rdat, off_t offset, int whence)
Definition: readers.c:1231
int ret

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 }
#define READER_SEEKABLE
Definition: reader.h:115
struct reader_data rdat
Definition: frame.h:288
#define SEEK_SET
Definition: jmemansi.c:26
static off_t stream_lseek(mpg123_handle *fr, off_t pos, int whence)
Definition: readers.c:227
#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 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 }
#define READER_SEEKABLE
Definition: reader.h:115
__kernel_off_t off_t
Definition: linux.h:201
#define frame_index_find
Definition: intsym.h:187
#define debug2(s, a, b)
Definition: debug.h:62
struct reader_data rdat
Definition: frame.h:288
#define READER_ERROR
Definition: reader.h:134
#define read_frame
Definition: intsym.h:241
long off_p
Definition: compat.h:132
struct reader * rd
Definition: frame.h:287
#define debug1(s, a)
Definition: debug.h:61
#define OFF_P
Definition: compat.h:131

◆ 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 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:511
struct reader_data rdat
Definition: frame.h:288
#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:227
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:287

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:911
static int bad_init(mpg123_handle *mh) bugger_off static void bad_close(mpg123_handle *mh)
Definition: readers.c:903
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 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().