88c0fed26a57193be45dd51c5ac83b94450dfd15
[reactos.git] / reactos / sdk / lib / 3rdparty / libmpg123 / readers.c
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 }