1 /* 2 reader: reading input data 3 4 copyright ?-2007 by the mpg123 project - free software under the terms of the LGPL 2.1 5 see COPYING and AUTHORS files in distribution or http://mpg123.org 6 initially written by Thomas Orgis (after code from Michael Hipp) 7 */ 8 9 #ifndef MPG123_READER_H 10 #define MPG123_READER_H 11 12 #include "config.h" 13 #include "mpg123.h" 14 15 #ifndef NO_FEEDER 16 struct buffy 17 { 18 unsigned char *data; 19 ssize_t size; 20 ssize_t realsize; 21 struct buffy *next; 22 }; 23 24 25 struct bufferchain 26 { 27 struct buffy* first; /* The beginning of the chain. */ 28 struct buffy* last; /* The end... of the chain. */ 29 ssize_t size; /* Aggregated size of all buffies. */ 30 /* These positions are relative to buffer chain beginning. */ 31 ssize_t pos; /* Position in whole chain. */ 32 ssize_t firstpos; /* The point of return on non-forget() */ 33 /* The "real" filepos is fileoff + pos. */ 34 off_t fileoff; /* Beginning of chain is at this file offset. */ 35 size_t bufblock; /* Default (minimal) size of buffers. */ 36 size_t pool_size; /* Keep that many buffers in storage. */ 37 size_t pool_fill; /* That many buffers are there. */ 38 /* A pool of buffers to re-use, if activated. It's a linked list that is worked on from the front. */ 39 struct buffy *pool; 40 }; 41 42 /* Call this before any buffer chain use (even bc_init()). */ 43 void bc_prepare(struct bufferchain *, size_t pool_size, size_t bufblock); 44 /* Free persistent data in the buffer chain, after bc_reset(). */ 45 void bc_cleanup(struct bufferchain *); 46 /* Change pool size. This does not actually allocate/free anything on itself, just instructs later operations to free less / allocate more buffers. */ 47 void bc_poolsize(struct bufferchain *, size_t pool_size, size_t bufblock); 48 /* Return available byte count in the buffer. */ 49 size_t bc_fill(struct bufferchain *bc); 50 51 #endif 52 53 struct reader_data 54 { 55 off_t filelen; /* total file length or total buffer size */ 56 off_t filepos; /* position in file or position in buffer chain */ 57 int filept; 58 /* Custom opaque I/O handle from the client. */ 59 void *iohandle; 60 int flags; 61 long timeout_sec; 62 ssize_t (*fdread) (mpg123_handle *, void *, size_t); 63 /* User can replace the read and lseek functions. The r_* are the stored replacement functions or NULL. */ 64 ssize_t (*r_read) (int fd, void *buf, size_t count); 65 off_t (*r_lseek)(int fd, off_t offset, int whence); 66 /* These are custom I/O routines for opaque user handles. 67 They get picked if there's some iohandle set. */ 68 ssize_t (*r_read_handle) (void *handle, void *buf, size_t count); 69 off_t (*r_lseek_handle)(void *handle, off_t offset, int whence); 70 /* An optional cleaner for the handle on closing the stream. */ 71 void (*cleanup_handle)(void *handle); 72 /* These two pointers are the actual workers (default map to POSIX read/lseek). */ 73 ssize_t (*read) (int fd, void *buf, size_t count); 74 off_t (*lseek)(int fd, off_t offset, int whence); 75 /* Buffered readers want that abstracted, set internally. */ 76 ssize_t (*fullread)(mpg123_handle *, unsigned char *, ssize_t); 77 #ifndef NO_FEEDER 78 struct bufferchain buffer; /* Not dynamically allocated, these few struct bytes aren't worth the trouble. */ 79 #endif 80 }; 81 82 /* start to use off_t to properly do LFS in future ... used to be long */ 83 struct reader 84 { 85 int (*init) (mpg123_handle *); 86 void (*close) (mpg123_handle *); 87 ssize_t (*fullread) (mpg123_handle *, unsigned char *, ssize_t); 88 int (*head_read) (mpg123_handle *, unsigned long *newhead); /* succ: TRUE, else <= 0 (FALSE or READER_MORE) */ 89 int (*head_shift) (mpg123_handle *, unsigned long *head); /* succ: TRUE, else <= 0 (FALSE or READER_MORE) */ 90 off_t (*skip_bytes) (mpg123_handle *, off_t len); /* succ: >=0, else error or READER_MORE */ 91 int (*read_frame_body)(mpg123_handle *, unsigned char *, int size); 92 int (*back_bytes) (mpg123_handle *, off_t bytes); 93 int (*seek_frame) (mpg123_handle *, off_t num); 94 off_t (*tell) (mpg123_handle *); 95 void (*rewind) (mpg123_handle *); 96 void (*forget) (mpg123_handle *); 97 }; 98 99 /* Open a file by path or use an opened file descriptor. */ 100 int open_stream(mpg123_handle *, const char *path, int fd); 101 /* Open an external handle. */ 102 int open_stream_handle(mpg123_handle *, void *iohandle); 103 104 /* feed based operation has some specials */ 105 int open_feed(mpg123_handle *); 106 /* externally called function, returns 0 on success, -1 on error */ 107 int feed_more(mpg123_handle *fr, const unsigned char *in, long count); 108 void feed_forget(mpg123_handle *fr); /* forget the data that has been read (free some buffers) */ 109 off_t feed_set_pos(mpg123_handle *fr, off_t pos); /* Set position (inside available data if possible), return wanted byte offset of next feed. */ 110 111 void open_bad(mpg123_handle *); 112 113 #define READER_FD_OPENED 0x1 114 #define READER_ID3TAG 0x2 115 #define READER_SEEKABLE 0x4 116 #define READER_BUFFERED 0x8 117 #define READER_NONBLOCK 0x20 118 #define READER_HANDLEIO 0x40 119 120 #define READER_STREAM 0 121 #define READER_ICY_STREAM 1 122 #define READER_FEED 2 123 /* These two add a little buffering to enable small seeks for peek ahead. */ 124 #define READER_BUF_STREAM 3 125 #define READER_BUF_ICY_STREAM 4 126 127 #ifdef READ_SYSTEM 128 #define READER_SYSTEM 5 129 #define READERS 6 130 #else 131 #define READERS 5 132 #endif 133 134 #define READER_ERROR MPG123_ERR 135 #define READER_MORE MPG123_NEED_MORE 136 137 #endif 138