ReactOS  0.4.14-dev-358-gbef841c
readers.c
Go to the documentation of this file.
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);
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);
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 */
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... */
333 {
334  if(fr->rdat.flags & READER_SEEKABLE)
335  {
337  return (ret < 0) ? READER_ERROR : ret;
338  }
339  else if(len >= 0)
340  {
341  unsigned char buf[1024]; /* ThOr: Compaq cxx complained and it makes sense to me... or should one do a cast? What for? */
342  ssize_t ret;
343  while (len > 0)
344  {
345  ssize_t num = len < (off_t)sizeof(buf) ? (ssize_t)len : (ssize_t)sizeof(buf);
346  ret = fr->rd->fullread(fr, buf, num);
347  if (ret < 0) return ret;
348  else if(ret == 0) break; /* EOF... an error? interface defined to tell the actual position... */
349  len -= ret;
350  }
351  return fr->rd->tell(fr);
352  }
353 #ifndef NO_FEEDER
354  else if(fr->rdat.flags & READER_BUFFERED)
355  { /* Perhaps we _can_ go a bit back. */
356  if(fr->rdat.buffer.pos >= -len)
357  {
358  fr->rdat.buffer.pos += len;
359  return fr->rd->tell(fr);
360  }
361  else
362  {
363  fr->err = MPG123_NO_SEEK;
364  return READER_ERROR;
365  }
366  }
367 #endif
368  else
369  {
370  fr->err = MPG123_NO_SEEK;
371  return READER_ERROR;
372  }
373 }
374 
375 /* Return 0 on success... */
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 
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  */
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. */
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! */
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 
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... */
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 
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 
802 
803 /* Not just for feed reader, also for self-feeding buffered reader. */
805 {
806  bc_forget(&fr->rdat.buffer);
807  fr->rdat.filepos = fr->rdat.buffer.fileoff + fr->rdat.buffer.pos;
808 }
809 
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 
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 {
876  return -1;
877 }
879 {
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; }
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
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,
920  generic_tell,
922  NULL
923  } ,
924  { /* READER_ICY_STREAM */
925  default_init,
926  stream_close,
927  icy_fullread,
934  generic_tell,
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,
957  generic_tell,
960  },
961  { /* READER_BUF_STREAM */
962  default_init,
963  stream_close,
971  generic_tell,
974  } ,
975  { /* READER_BUF_ICY_STREAM */
976  default_init,
977  stream_close,
985  generic_tell,
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,
1014  bad_skip_bytes,
1016  bad_back_bytes,
1018  bad_tell,
1019  bad_rewind,
1020  NULL
1021 };
1022 
1024 {
1025 #ifdef TIMEOUT_READ
1026  if(fr->p.timeout > 0)
1027  {
1028  int flags;
1029  if(fr->rdat.r_read != NULL)
1030  {
1031  error("Timeout reading does not work with user-provided read function. Implement it yourself!");
1032  return -1;
1033  }
1034  flags = fcntl(fr->rdat.filept, F_GETFL);
1035  flags |= O_NONBLOCK;
1036  fcntl(fr->rdat.filept, F_SETFL, flags);
1037  fr->rdat.fdread = timeout_read;
1038  fr->rdat.timeout_sec = fr->p.timeout;
1039  fr->rdat.flags |= READER_NONBLOCK;
1040  }
1041  else
1042 #endif
1043  fr->rdat.fdread = plain_read;
1044 
1045  fr->rdat.read = fr->rdat.r_read != NULL ? fr->rdat.r_read : posix_read;
1046  fr->rdat.lseek = fr->rdat.r_lseek != NULL ? fr->rdat.r_lseek : posix_lseek;
1047 #ifndef NO_ICY
1048  /* ICY streams of any sort shall not be seekable. */
1049  if(fr->p.icy_interval > 0) fr->rdat.lseek = nix_lseek;
1050 #endif
1051 
1052  fr->rdat.filelen = fr->p.flags & MPG123_NO_PEEK_END ? -1 : get_fileinfo(fr);
1053  fr->rdat.filepos = 0;
1054  if(fr->p.flags & MPG123_FORCE_SEEKABLE)
1055  fr->rdat.flags |= READER_SEEKABLE;
1056  /*
1057  Don't enable seeking on ICY streams, just plain normal files.
1058  This check is necessary since the client can enforce ICY parsing on files that would otherwise be seekable.
1059  It is a task for the future to make the ICY parsing safe with seeks ... or not.
1060  */
1061  if(fr->rdat.filelen >= 0)
1062  {
1063  fr->rdat.flags |= READER_SEEKABLE;
1064  if(!strncmp((char*)fr->id3buf,"TAG",3))
1065  {
1066  fr->rdat.flags |= READER_ID3TAG;
1067  fr->metaflags |= MPG123_NEW_ID3;
1068  }
1069  }
1070  /* Switch reader to a buffered one, if allowed. */
1071  else if(fr->p.flags & MPG123_SEEKBUFFER)
1072  {
1073 #ifdef NO_FEEDER
1074  error("Buffered readers not supported in this build.");
1076  return -1;
1077 #else
1078  if (fr->rd == &readers[READER_STREAM])
1079  {
1080  fr->rd = &readers[READER_BUF_STREAM];
1081  fr->rdat.fullread = plain_fullread;
1082  }
1083 #ifndef NO_ICY
1084  else if(fr->rd == &readers[READER_ICY_STREAM])
1085  {
1087  fr->rdat.fullread = icy_fullread;
1088  }
1089 #endif
1090  else
1091  {
1092  if(NOQUIET) error("mpg123 Programmer's fault: invalid reader");
1093  return -1;
1094  }
1095  bc_init(&fr->rdat.buffer);
1096  fr->rdat.filelen = 0; /* We carry the offset, but never know how big the stream is. */
1097  fr->rdat.flags |= READER_BUFFERED;
1098 #endif /* NO_FEEDER */
1099  }
1100  return 0;
1101 }
1102 
1103 
1105 {
1106  debug("open_bad");
1107 #ifndef NO_ICY
1108  clear_icy(&mh->icy);
1109 #endif
1110  mh->rd = &bad_reader;
1111  mh->rdat.flags = 0;
1112 #ifndef NO_FEEDER
1113  bc_init(&mh->rdat.buffer);
1114 #endif
1115  mh->rdat.filelen = -1;
1116 }
1117 
1119 {
1120  debug("feed reader");
1121 #ifdef NO_FEEDER
1122  error("Buffered readers not supported in this build.");
1124  return -1;
1125 #else
1126 #ifndef NO_ICY
1127  if(fr->p.icy_interval > 0)
1128  {
1129  if(NOQUIET) error("Feed reader cannot do ICY parsing!");
1130 
1131  return -1;
1132  }
1133  clear_icy(&fr->icy);
1134 #endif
1135  fr->rd = &readers[READER_FEED];
1136  fr->rdat.flags = 0;
1137  if(fr->rd->init(fr) < 0) return -1;
1138 
1139  debug("feed reader init successful");
1140  return 0;
1141 #endif /* NO_FEEDER */
1142 }
1143 
1144 /* Final code common to open_stream and open_stream_handle. */
1146 {
1147 #ifndef NO_ICY
1148  if(fr->p.icy_interval > 0)
1149  {
1150  debug("ICY reader");
1151  fr->icy.interval = fr->p.icy_interval;
1152  fr->icy.next = fr->icy.interval;
1153  fr->rd = &readers[READER_ICY_STREAM];
1154  }
1155  else
1156 #endif
1157  {
1158  fr->rd = &readers[READER_STREAM];
1159  debug("stream reader");
1160  }
1161 
1162  if(fr->rd->init(fr) < 0) return -1;
1163 
1164  return MPG123_OK;
1165 }
1166 
1167 int open_stream(mpg123_handle *fr, const char *bs_filenam, int fd)
1168 {
1169  int filept_opened = 1;
1170  int filept; /* descriptor of opened file/stream */
1171 
1172  clear_icy(&fr->icy); /* can be done inside frame_clear ...? */
1173 
1174  if(!bs_filenam) /* no file to open, got a descriptor (stdin) */
1175  {
1176  filept = fd;
1177  filept_opened = 0; /* and don't try to close it... */
1178  }
1179  #ifndef O_BINARY
1180  #define O_BINARY (0)
1181  #endif
1182  else if((filept = compat_open(bs_filenam, O_RDONLY|O_BINARY)) < 0) /* a plain old file to open... */
1183  {
1184  if(NOQUIET) error2("Cannot open file %s: %s", bs_filenam, strerror(errno));
1185  fr->err = MPG123_BAD_FILE;
1186  return MPG123_ERR; /* error... */
1187  }
1188 
1189  /* now we have something behind filept and can init the reader */
1190  fr->rdat.filelen = -1;
1191  fr->rdat.filept = filept;
1192  fr->rdat.flags = 0;
1193  if(filept_opened) fr->rdat.flags |= READER_FD_OPENED;
1194 
1195  return open_finish(fr);
1196 }
1197 
1198 int open_stream_handle(mpg123_handle *fr, void *iohandle)
1199 {
1200  clear_icy(&fr->icy); /* can be done inside frame_clear ...? */
1201  fr->rdat.filelen = -1;
1202  fr->rdat.filept = -1;
1203  fr->rdat.iohandle = iohandle;
1204  fr->rdat.flags = 0;
1205  fr->rdat.flags |= READER_HANDLEIO;
1206 
1207  return open_finish(fr);
1208 }
1209 
1210 /* Wrappers for actual reading/seeking... I'm full of wrappers here. */
1211 static off_t io_seek(struct reader_data *rdat, off_t offset, int whence)
1212 {
1213  if(rdat->flags & READER_HANDLEIO)
1214  {
1215  if(rdat->r_lseek_handle != NULL)
1216  {
1217  return rdat->r_lseek_handle(rdat->iohandle, offset, whence);
1218  }
1219  else return -1;
1220  }
1221  else
1222  return rdat->lseek(rdat->filept, offset, whence);
1223 }
1224 
1225 static ssize_t io_read(struct reader_data *rdat, void *buf, size_t count)
1226 {
1227  if(rdat->flags & READER_HANDLEIO)
1228  {
1229  if(rdat->r_read_handle != NULL)
1230  {
1231  return rdat->r_read_handle(rdat->iohandle, buf, count);
1232  }
1233  else return -1;
1234  }
1235  else
1236  return rdat->read(rdat->filept, buf, count);
1237 }
Definition: winsock.h:66
static ssize_t bad_fullread(mpg123_handle *mh, unsigned char *data, ssize_t count) bugger_off static int bad_head_read(mpg123_handle *mh
int filept
Definition: reader.h:57
#define SEEK_CUR
Definition: util.h:63
static off_t generic_tell(mpg123_handle *fr)
Definition: readers.c:400
static int open_finish(mpg123_handle *fr)
Definition: readers.c:1145
#define TRUE
Definition: types.h:120
#define READER_SEEKABLE
Definition: reader.h:115
uint16_t size
Definition: btrfs_drv.h:556
static ssize_t unsigned long *newhead static bugger_off int off_t len static bugger_off int off_t bytes static bugger_off int bad_seek_frame(mpg123_handle *mh, off_t num) bugger_off static off_t bad_tell(mpg123_handle *mh) bugger_off static void bad_rewind(mpg123_handle *mh)
Definition: readers.c:898
#define READER_BUF_ICY_STREAM
Definition: readers.c:907
static int feed_back_bytes(mpg123_handle *fr, off_t bytes)
Definition: readers.c:793
static off_t nix_lseek(int fd, off_t offset, int whence)
Definition: readers.c:33
struct mpg123_pars_struct p
Definition: frame.h:287
#define compat_open
Definition: intsym.h:12
void bc_poolsize(struct bufferchain *bc, size_t pool_size, size_t bufblock)
Definition: readers.c:509
#define error(str)
Definition: mkdosfs.c:1605
static ssize_t bc_skip(struct bufferchain *bc, ssize_t count)
Definition: readers.c:705
static ssize_t icy_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count)
Definition: readers.c:91
static off_t stream_skip_bytes(mpg123_handle *fr, off_t len)
Definition: readers.c:332
#define O_BINARY
LPBATCH_CONTEXT bc
Definition: batch.c:66
struct outqueuenode * head
Definition: adnsresfilter.c:66
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define error1(s, a)
Definition: debug.h:109
static int stream_seek_frame(mpg123_handle *fr, off_t newframe)
Definition: readers.c:256
static void bc_free(struct bufferchain *bc, struct buffy *buf)
Definition: readers.c:541
void open_bad(mpg123_handle *mh)
Definition: readers.c:1104
GLuint GLuint GLsizei count
Definition: gl.h:1545
unsigned char * data
Definition: reader.h:18
#define O_NONBLOCK
Definition: port.h:158
#define free
Definition: debug_ros.c:5
#define READER_FEED
Definition: readers.c:905
__kernel_off_t off_t
Definition: linux.h:201
static ssize_t bc_seekback(struct bufferchain *bc, ssize_t count)
Definition: readers.c:715
static void bc_forget(struct bufferchain *bc)
Definition: readers.c:722
static struct buffy * buffy_new(size_t size, size_t minsize)
Definition: readers.c:458
GLintptr offset
Definition: glext.h:5920
GLdouble n
Definition: glext.h:7729
static ssize_t buffered_fullread(mpg123_handle *fr, unsigned char *out, ssize_t count)
Definition: readers.c:830
#define debug4(s, a, b, c, d)
Definition: debug.h:55
#define frame_index_find
Definition: intsym.h:176
#define READER_FD_OPENED
Definition: reader.h:113
#define READER_NONBLOCK
Definition: reader.h:117
static int fd
Definition: io.c:51
_Check_return_opt_ _CRTIMP long __cdecl lseek(_In_ int _FileHandle, _In_ long _Offset, _In_ int _Origin)
#define ssize_t
Definition: config.h:469
int errno
static off_t feed_skip_bytes(mpg123_handle *fr, off_t len)
Definition: readers.c:784
static int generic_head_read(mpg123_handle *fr, unsigned long *newhead)
Definition: readers.c:302
#define FD_ZERO(set)
Definition: winsock.h:96
#define debug2(s, a, b)
Definition: debug.h:53
#define FD_SET(fd, set)
Definition: winsock.h:89
const char * strerror(int err)
Definition: compat_str.c:23
struct reader_data rdat
Definition: frame.h:286
#define debug3(s, a, b, c)
Definition: debug.h:54
static void buffered_forget(mpg123_handle *fr)
Definition: readers.c:804
ssize_t realsize
Definition: reader.h:20
static off_t posix_lseek(int fd, off_t offset, int whence)
Definition: readers.c:32
static ssize_t plain_fullread(mpg123_handle *fr, unsigned char *buf, ssize_t count)
Definition: readers.c:201
static int bad_init(mpg123_handle *mh) bugger_off static void bad_close(mpg123_handle *mh)
Definition: readers.c:890
int feed_more(mpg123_handle *fr, const unsigned char *in, long count)
Definition: readers.c:760
static int bc_fill_pool(struct bufferchain *bc)
Definition: readers.c:555
#define MPG123_NEW_ICY
Definition: mpg123.h:1243
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define MPG123_NEW_ID3
Definition: mpg123.h:1241
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
static void buffy_del(struct buffy *buf)
Definition: readers.c:476
static int bc_append(struct bufferchain *bc, ssize_t size)
Definition: readers.c:608
void * iohandle
Definition: reader.h:59
struct icy_meta icy
Definition: frame.h:299
static void bc_reset(struct bufferchain *bc)
Definition: readers.c:594
smooth NULL
Definition: ftsmooth.c:416
ssize_t(* fullread)(mpg123_handle *, unsigned char *, ssize_t)
Definition: reader.h:87
#define READER_ERROR
Definition: reader.h:134
static off_t io_seek(struct reader_data *rdat, off_t offset, int whence)
Definition: readers.c:1211
#define off_t
Definition: dosfsck.h:5
#define VERBOSE3
#define b
Definition: ke_i.h:79
#define error2(s, a, b)
Definition: debug.h:110
static ssize_t posix_read(int fd, void *buf, size_t count)
Definition: readers.c:31
r l[0]
Definition: byte_order.h:167
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
#define READER_MORE
Definition: reader.h:135
#define SEEK_SET
Definition: jmemansi.c:26
#define READER_ID3TAG
Definition: reader.h:114
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
unsigned long size_p
Definition: compat.h:138
GLsizeiptr size
Definition: glext.h:5919
#define bugger_off
Definition: readers.c:889
#define compat_close
Definition: intsym.h:15
static struct reader readers[]
Definition: readers.c:908
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
static int feed_init(mpg123_handle *fr)
Definition: readers.c:749
static FILE * out
Definition: regtests2xml.c:44
off_t feed_set_pos(mpg123_handle *fr, off_t pos)
Definition: readers.c:810
GLuint GLuint num
Definition: glext.h:9618
GLint left
Definition: glext.h:7726
static int feed_seek_frame(mpg123_handle *fr, off_t num)
Definition: readers.c:801
ssize_t size
Definition: reader.h:19
int flags
Definition: reader.h:60
static ssize_t feed_read(mpg123_handle *fr, unsigned char *out, ssize_t count)
Definition: readers.c:776
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
static off_t stream_lseek(mpg123_handle *fr, off_t pos, int whence)
Definition: readers.c:226
#define NOQUIET
static int stream_back_bytes(mpg123_handle *fr, off_t bytes)
Definition: readers.c:376
#define SSIZE_P
Definition: compat.h:145
#define READER_HANDLEIO
Definition: reader.h:118
int ret
static void bc_init(struct bufferchain *bc)
Definition: readers.c:584
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 struct reader bad_reader
Definition: readers.c:1007
off_t(* r_lseek_handle)(void *handle, off_t offset, int whence)
Definition: reader.h:69
#define READER_STREAM
Definition: readers.c:903
size_t bc_fill(struct bufferchain *bc)
Definition: readers.c:504
static void stream_rewind(mpg123_handle *fr)
Definition: readers.c:411
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
int ssize_t
Definition: rosdhcp.h:48
#define READER_BUFFERED
Definition: reader.h:116
off_t(* lseek)(int fd, off_t offset, int whence)
Definition: reader.h:74
static int generic_read_frame_body(mpg123_handle *fr, unsigned char *buf, int size)
Definition: readers.c:387
static ssize_t bc_give(struct bufferchain *bc, unsigned char *out, ssize_t size)
Definition: readers.c:666
ssize_t(* read)(int fd, void *buf, size_t count)
Definition: reader.h:73
struct buffy * next
Definition: reader.h:21
int open_stream(mpg123_handle *fr, const char *bs_filenam, int fd)
Definition: readers.c:1167
static unsigned __int64 next
Definition: rand_nt.c:6
GLuint in
Definition: glext.h:9616
#define read_frame
Definition: intsym.h:231
#define READER_ICY_STREAM
Definition: readers.c:904
#define clear_icy
Definition: intsym.h:199
unsigned char id3buf[128]
Definition: frame.h:294
static ssize_t io_read(struct reader_data *rdat, void *buf, size_t count)
Definition: readers.c:1225
static void buffy_del_chain(struct buffy *buf)
Definition: readers.c:486
void bc_cleanup(struct bufferchain *bc)
Definition: readers.c:515
#define long
Definition: qsort.c:33
#define SIZE_P
Definition: compat.h:137
w ll
Definition: byte_order.h:166
Definition: reader.h:16
static int bc_add(struct bufferchain *bc, const unsigned char *data, ssize_t size)
Definition: readers.c:625
Definition: reader.h:83
static ssize_t plain_read(mpg123_handle *fr, void *buf, size_t count)
Definition: readers.c:57
void bc_prepare(struct bufferchain *bc, size_t pool_size, size_t bufblock)
Definition: readers.c:496
long off_p
Definition: compat.h:130
#define READER_BUF_STREAM
Definition: readers.c:906
GLuint res
Definition: glext.h:9613
static ssize_t bc_need_more(struct bufferchain *bc)
Definition: readers.c:657
FILE * stderr
int open_feed(mpg123_handle *fr)
Definition: readers.c:1118
#define SEEK_END
Definition: cabinet.c:27
#define debug(msg)
Definition: key_call.c:71
#define malloc
Definition: debug_ros.c:4
struct reader * rd
Definition: frame.h:285
ssize_t(* r_read_handle)(void *handle, void *buf, size_t count)
Definition: reader.h:68
#define debug5(s, a, b, c, d, e)
Definition: debug.h:56
static void stream_close(mpg123_handle *fr)
Definition: readers.c:239
static int generic_head_shift(mpg123_handle *fr, unsigned long *head)
Definition: readers.c:318
static off_t get_fileinfo(mpg123_handle *)
Definition: readers.c:435
static int default_init(mpg123_handle *fr)
Definition: readers.c:1023
long ssize_p
Definition: compat.h:146
#define debug1(s, a)
Definition: debug.h:52
static struct buffy * bc_alloc(struct bufferchain *bc, size_t size)
Definition: readers.c:523
int open_stream_handle(mpg123_handle *fr, void *iohandle)
Definition: readers.c:1198
static UINT PSTR DWORD UINT * need
Definition: parser.c:36
#define OFF_P
Definition: compat.h:129
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
#define O_RDONLY
Definition: acwin.h:108