Subversion Repositories Kolibri OS

Rev

Rev 1905 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /* TODO: Check all read calls (in loops, especially!) for return value 0 (EOF)! */
  2.  
  3. /*
  4.         readers.c: reading input data
  5.  
  6.         copyright ?-2008 by the mpg123 project - free software under the terms of the LGPL 2.1
  7.         see COPYING and AUTHORS files in distribution or http://mpg123.org
  8.         initially written by Michael Hipp
  9. */
  10.  
  11. #include "mpg123lib_intern.h"
  12. #include <sys/stat.h>
  13. #include <fcntl.h>
  14. #include <errno.h>
  15. /* For select(), I need select.h according to POSIX 2001, else: sys/time.h sys/types.h unistd.h (the latter two included in compat.h already). */
  16. #ifdef HAVE_SYS_SELECT_H
  17. #include <sys/select.h>
  18. #endif
  19. #ifdef HAVE_SYS_TIME_H
  20. #include <sys/time.h>
  21. #endif
  22. #ifdef _MSC_VER
  23. #include <io.h>
  24. #endif
  25.  
  26. #include "compat.h"
  27. #include "debug.h"
  28.  
  29. static int default_init(mpg123_handle *fr);
  30. static off_t get_fileinfo(mpg123_handle *);
  31. static ssize_t posix_read(int fd, void *buf, size_t count){ return read(fd, buf, count); }
  32. static off_t   posix_lseek(int fd, off_t offset, int whence){ return lseek(fd, offset, whence); }
  33. static off_t     nix_lseek(int fd, off_t offset, int whence){ return -1; }
  34.  
  35. static ssize_t plain_fullread(mpg123_handle *fr,unsigned char *buf, ssize_t count);
  36.  
  37. /* Wrapper to decide between descriptor-based and external handle-based I/O. */
  38. static off_t io_seek(struct reader_data *rdat, off_t offset, int whence);
  39. static ssize_t io_read(struct reader_data *rdat, void *buf, size_t count);
  40.  
  41. #ifndef NO_FEEDER
  42. /* Bufferchain methods. */
  43. static void bc_init(struct bufferchain *bc);
  44. static void bc_reset(struct bufferchain *bc);
  45. static int bc_append(struct bufferchain *bc, ssize_t size);
  46. #if 0
  47. static void bc_drop(struct bufferchain *bc);
  48. #endif
  49. static int bc_add(struct bufferchain *bc, const unsigned char *data, ssize_t size);
  50. static ssize_t bc_give(struct bufferchain *bc, unsigned char *out, ssize_t size);
  51. static ssize_t bc_skip(struct bufferchain *bc, ssize_t count);
  52. static ssize_t bc_seekback(struct bufferchain *bc, ssize_t count);
  53. static void bc_forget(struct bufferchain *bc);
  54. #endif
  55.  
  56. /* A normal read and a read with timeout. */
  57. static ssize_t plain_read(mpg123_handle *fr, void *buf, size_t count)
  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. }
  63.  
  64. #ifdef TIMEOUT_READ
  65.  
  66. /* Wait for data becoming available, allowing soft-broken network connection to die
  67.    This is needed for Shoutcast servers that have forgotten about us while connection was temporarily down. */
  68. static ssize_t timeout_read(mpg123_handle *fr, void *buf, size_t count)
  69. {
  70.         struct timeval tv;
  71.         ssize_t ret = 0;
  72.         fd_set fds;
  73.         tv.tv_sec = fr->rdat.timeout_sec;
  74.         tv.tv_usec = 0;
  75.         FD_ZERO(&fds);
  76.         FD_SET(fr->rdat.filept, &fds);
  77.         ret = select(fr->rdat.filept+1, &fds, NULL, NULL, &tv);
  78.         /* This works only with "my" read function. Not user-replaced. */
  79.         if(ret > 0) ret = read(fr->rdat.filept, buf, count);
  80.         else
  81.         {
  82.                 ret=-1; /* no activity is the error */
  83.                 if(NOQUIET) error("stream timed out");
  84.         }
  85.         return ret;
  86. }
  87. #endif
  88.  
  89. #ifndef NO_ICY
  90. /* stream based operation  with icy meta data*/
  91. static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count)
  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. }
  196. #else
  197. #define icy_fullread NULL
  198. #endif /* NO_ICY */
  199.  
  200. /* stream based operation */
  201. static ssize_t plain_fullread(mpg123_handle *fr,unsigned char *buf, ssize_t count)
  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. }
  225.  
  226. static off_t stream_lseek(mpg123_handle *fr, off_t pos, int whence)
  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. }
  238.  
  239. static void stream_close(mpg123_handle *fr)
  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. }
  255.  
  256. static int stream_seek_frame(mpg123_handle *fr, off_t newframe)
  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. }
  300.  
  301. /* return FALSE on error, TRUE on success, READER_MORE on occasion */
  302. static int generic_head_read(mpg123_handle *fr,unsigned long *newhead)
  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. }
  316.  
  317. /* return FALSE on error, TRUE on success, READER_MORE on occasion */
  318. static int generic_head_shift(mpg123_handle *fr,unsigned long *head)
  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. }
  330.  
  331. /* returns reached position... negative ones are bad... */
  332. static off_t stream_skip_bytes(mpg123_handle *fr,off_t len)
  333. {
  334.         if(fr->rdat.flags & READER_SEEKABLE)
  335.         {
  336.                 off_t ret = stream_lseek(fr, len, SEEK_CUR);
  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. }
  374.  
  375. /* Return 0 on success... */
  376. static int stream_back_bytes(mpg123_handle *fr, off_t bytes)
  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. }
  384.  
  385.  
  386. /* returns size on success... */
  387. static int generic_read_frame_body(mpg123_handle *fr,unsigned char *buf, int size)
  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. }
  399.  
  400. static off_t generic_tell(mpg123_handle *fr)
  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. }
  409.  
  410. /* This does not (fully) work for non-seekable streams... You have to check for that flag, pal! */
  411. static void stream_rewind(mpg123_handle *fr)
  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. }
  429.  
  430. /*
  431.  * returns length of a file (if filept points to a file)
  432.  * reads the last 128 bytes information into buffer
  433.  * ... that is not totally safe...
  434.  */
  435. static off_t get_fileinfo(mpg123_handle *fr)
  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. }
  453.  
  454. #ifndef NO_FEEDER
  455. /* Methods for the buffer chain, mainly used for feed reader, but not just that. */
  456.  
  457.  
  458. static struct buffy* buffy_new(size_t size, size_t minsize)
  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. }
  475.  
  476. static void buffy_del(struct buffy* buf)
  477. {
  478.         if(buf)
  479.         {
  480.                 free(buf->data);
  481.                 free(buf);
  482.         }
  483. }
  484.  
  485. /* Delete this buffy and all following buffies. */
  486. static void buffy_del_chain(struct buffy* buf)
  487. {
  488.         while(buf)
  489.         {
  490.                 struct buffy* next = buf->next;
  491.                 buffy_del(buf);
  492.                 buf = next;
  493.         }
  494. }
  495.  
  496. void bc_prepare(struct bufferchain *bc, size_t pool_size, size_t bufblock)
  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. }
  503.  
  504. size_t bc_fill(struct bufferchain *bc)
  505. {
  506.         return (size_t)(bc->size - bc->pos);
  507. }
  508.  
  509. void bc_poolsize(struct bufferchain *bc, size_t pool_size, size_t bufblock)
  510. {
  511.         bc->pool_size = pool_size;
  512.         bc->bufblock = bufblock;
  513. }
  514.  
  515. void bc_cleanup(struct bufferchain *bc)
  516. {
  517.         buffy_del_chain(bc->pool);
  518.         bc->pool = NULL;
  519.         bc->pool_fill = 0;
  520. }
  521.  
  522. /* Fetch a buffer from the pool (if possible) or create one. */
  523. static struct buffy* bc_alloc(struct bufferchain *bc, size_t size)
  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. }
  539.  
  540. /* Either stuff the buffer back into the pool or free it for good. */
  541. static void bc_free(struct bufferchain *bc, struct buffy* buf)
  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. }
  553.  
  554. /* Make the buffer count in the pool match the pool size. */
  555. static int bc_fill_pool(struct bufferchain *bc)
  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. }
  582.  
  583.  
  584. static void bc_init(struct bufferchain *bc)
  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. }
  593.  
  594. static void bc_reset(struct bufferchain *bc)
  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. }
  606.  
  607. /* Create a new buffy at the end to be filled. */
  608. static int bc_append(struct bufferchain *bc, ssize_t size)
  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. }
  623.  
  624. /* Append a new buffer and copy content to it. */
  625. static int bc_add(struct bufferchain *bc, const unsigned char *data, ssize_t size)
  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. }
  655.  
  656. /* Common handler for "You want more than I can give." situation. */
  657. static ssize_t bc_need_more(struct bufferchain *bc)
  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. }
  664.  
  665. /* Give some data, advancing position but not forgetting yet. */
  666. static ssize_t bc_give(struct bufferchain *bc, unsigned char *out, ssize_t size)
  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. }
  702.  
  703. /* Skip some bytes and return the new position.
  704.    The buffers are still there, just the read pointer is moved! */
  705. static ssize_t bc_skip(struct bufferchain *bc, ssize_t count)
  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. }
  714.  
  715. static ssize_t bc_seekback(struct bufferchain *bc, ssize_t count)
  716. {
  717.         if(count >= 0 && count <= bc->pos) return bc->pos -= count;
  718.         else return READER_ERROR;
  719. }
  720.  
  721. /* Throw away buffies that we passed. */
  722. static void bc_forget(struct bufferchain *bc)
  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. }
  746.  
  747. /* reader for input via manually provided buffers */
  748.  
  749. static int feed_init(mpg123_handle *fr)
  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. }
  758.  
  759. /* externally called function, returns 0 on success, -1 on error */
  760. int feed_more(mpg123_handle *fr, const unsigned char *in, long count)
  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. }
  775.  
  776. static ssize_t feed_read(mpg123_handle *fr, unsigned char *out, ssize_t count)
  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. }
  782.  
  783. /* returns reached position... negative ones are bad... */
  784. static off_t feed_skip_bytes(mpg123_handle *fr,off_t len)
  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. }
  792.  
  793. static int feed_back_bytes(mpg123_handle *fr, off_t bytes)
  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. }
  800.  
  801. static int feed_seek_frame(mpg123_handle *fr, off_t num){ return READER_ERROR; }
  802.  
  803. /* Not just for feed reader, also for self-feeding buffered reader. */
  804. static void buffered_forget(mpg123_handle *fr)
  805. {
  806.         bc_forget(&fr->rdat.buffer);
  807.         fr->rdat.filepos = fr->rdat.buffer.fileoff + fr->rdat.buffer.pos;
  808. }
  809.  
  810. off_t feed_set_pos(mpg123_handle *fr, off_t pos)
  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. }
  827.  
  828. /* The specific stuff for buffered stream reader. */
  829.  
  830. static ssize_t buffered_fullread(mpg123_handle *fr, unsigned char *out, ssize_t count)
  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. }
  872. #else
  873. int feed_more(mpg123_handle *fr, const unsigned char *in, long count)
  874. {
  875.         fr->err = MPG123_MISSING_FEATURE;
  876.         return -1;
  877. }
  878. off_t feed_set_pos(mpg123_handle *fr, off_t pos)
  879. {
  880.         fr->err = MPG123_MISSING_FEATURE;
  881.         return -1;
  882. }
  883. #endif /* NO_FEEDER */
  884.  
  885. /*****************************************************************
  886.  * read frame helper
  887.  */
  888.  
  889. #define bugger_off { mh->err = MPG123_NO_READER; return MPG123_ERR; }
  890. static int bad_init(mpg123_handle *mh) bugger_off
  891. static void bad_close(mpg123_handle *mh){}
  892. static ssize_t bad_fullread(mpg123_handle *mh, unsigned char *data, ssize_t count) bugger_off
  893. static int bad_head_read(mpg123_handle *mh, unsigned long *newhead) bugger_off
  894. static int bad_head_shift(mpg123_handle *mh, unsigned long *head) bugger_off
  895. static off_t bad_skip_bytes(mpg123_handle *mh, off_t len) bugger_off
  896. static int bad_read_frame_body(mpg123_handle *mh, unsigned char *data, int size) bugger_off
  897. static int bad_back_bytes(mpg123_handle *mh, off_t bytes) bugger_off
  898. static int bad_seek_frame(mpg123_handle *mh, off_t num) bugger_off
  899. static off_t bad_tell(mpg123_handle *mh) bugger_off
  900. static void bad_rewind(mpg123_handle *mh){}
  901. #undef bugger_off
  902.  
  903. #define READER_STREAM 0
  904. #define READER_ICY_STREAM 1
  905. #define READER_FEED       2
  906. #define READER_BUF_STREAM 3
  907. #define READER_BUF_ICY_STREAM 4
  908. static struct reader readers[] =
  909. {
  910.         { /* READER_STREAM */
  911.                 default_init,
  912.                 stream_close,
  913.                 plain_fullread,
  914.                 generic_head_read,
  915.                 generic_head_shift,
  916.                 stream_skip_bytes,
  917.                 generic_read_frame_body,
  918.                 stream_back_bytes,
  919.                 stream_seek_frame,
  920.                 generic_tell,
  921.                 stream_rewind,
  922.                 NULL
  923.         } ,
  924.         { /* READER_ICY_STREAM */
  925.                 default_init,
  926.                 stream_close,
  927.                 icy_fullread,
  928.                 generic_head_read,
  929.                 generic_head_shift,
  930.                 stream_skip_bytes,
  931.                 generic_read_frame_body,
  932.                 stream_back_bytes,
  933.                 stream_seek_frame,
  934.                 generic_tell,
  935.                 stream_rewind,
  936.                 NULL
  937.         },
  938. #ifdef NO_FEEDER
  939. #define feed_init NULL
  940. #define feed_read NULL
  941. #define buffered_fullread NULL
  942. #define feed_seek_frame NULL
  943. #define feed_back_bytes NULL
  944. #define feed_skip_bytes NULL
  945. #define buffered_forget NULL
  946. #endif
  947.         { /* READER_FEED */
  948.                 feed_init,
  949.                 stream_close,
  950.                 feed_read,
  951.                 generic_head_read,
  952.                 generic_head_shift,
  953.                 feed_skip_bytes,
  954.                 generic_read_frame_body,
  955.                 feed_back_bytes,
  956.                 feed_seek_frame,
  957.                 generic_tell,
  958.                 stream_rewind,
  959.                 buffered_forget
  960.         },
  961.         { /* READER_BUF_STREAM */
  962.                 default_init,
  963.                 stream_close,
  964.                 buffered_fullread,
  965.                 generic_head_read,
  966.                 generic_head_shift,
  967.                 stream_skip_bytes,
  968.                 generic_read_frame_body,
  969.                 stream_back_bytes,
  970.                 stream_seek_frame,
  971.                 generic_tell,
  972.                 stream_rewind,
  973.                 buffered_forget
  974.         } ,
  975.         { /* READER_BUF_ICY_STREAM */
  976.                 default_init,
  977.                 stream_close,
  978.                 buffered_fullread,
  979.                 generic_head_read,
  980.                 generic_head_shift,
  981.                 stream_skip_bytes,
  982.                 generic_read_frame_body,
  983.                 stream_back_bytes,
  984.                 stream_seek_frame,
  985.                 generic_tell,
  986.                 stream_rewind,
  987.                 buffered_forget
  988.         },
  989. #ifdef READ_SYSTEM
  990.         ,{
  991.                 system_init,
  992.                 NULL,   /* filled in by system_init() */
  993.                 fullread,
  994.                 NULL,
  995.                 NULL,
  996.                 NULL,
  997.                 NULL,
  998.                 NULL,
  999.                 NULL,
  1000.                 NULL,
  1001.                 NULL,
  1002.                 NULL,
  1003.         }
  1004. #endif
  1005. };
  1006.  
  1007. static struct reader bad_reader =
  1008. {
  1009.         bad_init,
  1010.         bad_close,
  1011.         bad_fullread,
  1012.         bad_head_read,
  1013.         bad_head_shift,
  1014.         bad_skip_bytes,
  1015.         bad_read_frame_body,
  1016.         bad_back_bytes,
  1017.         bad_seek_frame,
  1018.         bad_tell,
  1019.         bad_rewind,
  1020.         NULL
  1021. };
  1022.  
  1023. static int default_init(mpg123_handle *fr)
  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 = get_fileinfo(fr);
  1053.         fr->rdat.filepos = 0;
  1054.         /*
  1055.                 Don't enable seeking on ICY streams, just plain normal files.
  1056.                 This check is necessary since the client can enforce ICY parsing on files that would otherwise be seekable.
  1057.                 It is a task for the future to make the ICY parsing safe with seeks ... or not.
  1058.         */
  1059.         if(fr->rdat.filelen >= 0)
  1060.         {
  1061.                 fr->rdat.flags |= READER_SEEKABLE;
  1062.                 if(!strncmp((char*)fr->id3buf,"TAG",3))
  1063.                 {
  1064.                         fr->rdat.flags |= READER_ID3TAG;
  1065.                         fr->metaflags  |= MPG123_NEW_ID3;
  1066.                 }
  1067.         }
  1068.         /* Switch reader to a buffered one, if allowed. */
  1069.         else if(fr->p.flags & MPG123_SEEKBUFFER)
  1070.         {
  1071. #ifdef NO_FEEDER
  1072.                 error("Buffered readers not supported in this build.");
  1073.                 fr->err = MPG123_MISSING_FEATURE;
  1074.                 return -1;
  1075. #else
  1076.                 if     (fr->rd == &readers[READER_STREAM])
  1077.                 {
  1078.                         fr->rd = &readers[READER_BUF_STREAM];
  1079.                         fr->rdat.fullread = plain_fullread;
  1080.                 }
  1081. #ifndef NO_ICY
  1082.                 else if(fr->rd == &readers[READER_ICY_STREAM])
  1083.                 {
  1084.                         fr->rd = &readers[READER_BUF_ICY_STREAM];
  1085.                         fr->rdat.fullread = icy_fullread;
  1086.                 }
  1087. #endif
  1088.                 else
  1089.                 {
  1090.                         if(NOQUIET) error("mpg123 Programmer's fault: invalid reader");
  1091.                         return -1;
  1092.                 }
  1093.                 bc_init(&fr->rdat.buffer);
  1094.                 fr->rdat.filelen = 0; /* We carry the offset, but never know how big the stream is. */
  1095.                 fr->rdat.flags |= READER_BUFFERED;
  1096. #endif /* NO_FEEDER */
  1097.         }
  1098.         return 0;
  1099. }
  1100.  
  1101.  
  1102. void open_bad(mpg123_handle *mh)
  1103. {
  1104.         debug("open_bad");
  1105. #ifndef NO_ICY
  1106.         clear_icy(&mh->icy);
  1107. #endif
  1108.         mh->rd = &bad_reader;
  1109.         mh->rdat.flags = 0;
  1110. #ifndef NO_FEEDER
  1111.         bc_init(&mh->rdat.buffer);
  1112. #endif
  1113.         mh->rdat.filelen = -1;
  1114. }
  1115.  
  1116. int open_feed(mpg123_handle *fr)
  1117. {
  1118.         debug("feed reader");
  1119. #ifdef NO_FEEDER
  1120.         error("Buffered readers not supported in this build.");
  1121.         fr->err = MPG123_MISSING_FEATURE;
  1122.         return -1;
  1123. #else
  1124. #ifndef NO_ICY
  1125.         if(fr->p.icy_interval > 0)
  1126.         {
  1127.                 if(NOQUIET) error("Feed reader cannot do ICY parsing!");
  1128.  
  1129.                 return -1;
  1130.         }
  1131.         clear_icy(&fr->icy);
  1132. #endif
  1133.         fr->rd = &readers[READER_FEED];
  1134.         fr->rdat.flags = 0;
  1135.         if(fr->rd->init(fr) < 0) return -1;
  1136.  
  1137.         debug("feed reader init successful");
  1138.         return 0;
  1139. #endif /* NO_FEEDER */
  1140. }
  1141.  
  1142. /* Final code common to open_stream and open_stream_handle. */
  1143. static int open_finish(mpg123_handle *fr)
  1144. {
  1145. #ifndef NO_ICY
  1146.         if(fr->p.icy_interval > 0)
  1147.         {
  1148.                 debug("ICY reader");
  1149.                 fr->icy.interval = fr->p.icy_interval;
  1150.                 fr->icy.next = fr->icy.interval;
  1151.                 fr->rd = &readers[READER_ICY_STREAM];
  1152.         }
  1153.         else
  1154. #endif
  1155.         {
  1156.                 fr->rd = &readers[READER_STREAM];
  1157.                 debug("stream reader");
  1158.         }
  1159.  
  1160.         if(fr->rd->init(fr) < 0) return -1;
  1161.  
  1162.         return MPG123_OK;
  1163. }
  1164.  
  1165. int open_stream(mpg123_handle *fr, const char *bs_filenam, int fd)
  1166. {
  1167.         int filept_opened = 1;
  1168.         int filept; /* descriptor of opened file/stream */
  1169.  
  1170.         clear_icy(&fr->icy); /* can be done inside frame_clear ...? */
  1171.  
  1172.         if(!bs_filenam) /* no file to open, got a descriptor (stdin) */
  1173.         {
  1174.                 filept = fd;
  1175.                 filept_opened = 0; /* and don't try to close it... */
  1176.         }
  1177.         #ifndef O_BINARY
  1178.         #define O_BINARY (0)
  1179.         #endif
  1180.         else if((filept = compat_open(bs_filenam, O_RDONLY|O_BINARY)) < 0) /* a plain old file to open... */
  1181.         {
  1182.                 if(NOQUIET) error2("Cannot open file %s: %s", bs_filenam, strerror(errno));
  1183.                 fr->err = MPG123_BAD_FILE;
  1184.                 return MPG123_ERR; /* error... */
  1185.         }
  1186.  
  1187.         /* now we have something behind filept and can init the reader */
  1188.         fr->rdat.filelen = -1;
  1189.         fr->rdat.filept  = filept;
  1190.         fr->rdat.flags = 0;
  1191.         if(filept_opened)       fr->rdat.flags |= READER_FD_OPENED;
  1192.  
  1193.         return open_finish(fr);
  1194. }
  1195.  
  1196. int open_stream_handle(mpg123_handle *fr, void *iohandle)
  1197. {
  1198.         clear_icy(&fr->icy); /* can be done inside frame_clear ...? */
  1199.         fr->rdat.filelen = -1;
  1200.         fr->rdat.filept  = -1;
  1201.         fr->rdat.iohandle = iohandle;
  1202.         fr->rdat.flags = 0;
  1203.         fr->rdat.flags |= READER_HANDLEIO;
  1204.  
  1205.         return open_finish(fr);
  1206. }
  1207.  
  1208. /* Wrappers for actual reading/seeking... I'm full of wrappers here. */
  1209. static off_t io_seek(struct reader_data *rdat, off_t offset, int whence)
  1210. {
  1211.         if(rdat->flags & READER_HANDLEIO)
  1212.         {
  1213.                 if(rdat->r_lseek_handle != NULL)
  1214.                 {
  1215.                         return rdat->r_lseek_handle(rdat->iohandle, offset, whence);
  1216.                 }
  1217.                 else return -1;
  1218.         }
  1219.         else
  1220.         return rdat->lseek(rdat->filept, offset, whence);
  1221. }
  1222.  
  1223. static ssize_t io_read(struct reader_data *rdat, void *buf, size_t count)
  1224. {
  1225.         if(rdat->flags & READER_HANDLEIO)
  1226.         {
  1227.                 if(rdat->r_read_handle != NULL)
  1228.                 {
  1229.                         return rdat->r_read_handle(rdat->iohandle, buf, count);
  1230.                 }
  1231.                 else return -1;
  1232.         }
  1233.         else
  1234.         return rdat->read(rdat->filept, buf, count);
  1235. }
  1236.