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 = 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."); 1075 fr->err = MPG123_MISSING_FEATURE; 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 { 1086 fr->rd = &readers[READER_BUF_ICY_STREAM]; 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 1104 void open_bad(mpg123_handle *mh) 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 1118 int open_feed(mpg123_handle *fr) 1119 { 1120 debug("feed reader"); 1121 #ifdef NO_FEEDER 1122 error("Buffered readers not supported in this build."); 1123 fr->err = MPG123_MISSING_FEATURE; 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. */ 1145 static int open_finish(mpg123_handle *fr) 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 } 1238