Rev 1905 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1905 | serge | 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 | |||
3960 | Serge | 15 | #ifndef NO_FEEDER |
1905 | serge | 16 | struct buffy |
17 | { |
||
18 | unsigned char *data; |
||
19 | ssize_t size; |
||
3960 | Serge | 20 | ssize_t realsize; |
1905 | serge | 21 | struct buffy *next; |
22 | }; |
||
23 | |||
3960 | Serge | 24 | |
1905 | serge | 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. */ |
||
3960 | Serge | 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; |
||
1905 | serge | 40 | }; |
41 | |||
3960 | Serge | 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 | |||
1905 | serge | 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; |
||
3960 | Serge | 58 | /* Custom opaque I/O handle from the client. */ |
59 | void *iohandle; |
||
1905 | serge | 60 | int flags; |
61 | long timeout_sec; |
||
62 | ssize_t (*fdread) (mpg123_handle *, void *, size_t); |
||
3960 | Serge | 63 | /* User can replace the read and lseek functions. The r_* are the stored replacement functions or NULL. */ |
1905 | serge | 64 | ssize_t (*r_read) (int fd, void *buf, size_t count); |
65 | off_t (*r_lseek)(int fd, off_t offset, int whence); |
||
3960 | Serge | 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). */ |
||
1905 | serge | 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); |
||
3960 | Serge | 77 | #ifndef NO_FEEDER |
1905 | serge | 78 | struct bufferchain buffer; /* Not dynamically allocated, these few struct bytes aren't worth the trouble. */ |
3960 | Serge | 79 | #endif |
1905 | serge | 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); |
||
3960 | Serge | 101 | /* Open an external handle. */ |
102 | int open_stream_handle(mpg123_handle *, void *iohandle); |
||
1905 | serge | 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 |
||
3960 | Serge | 118 | #define READER_HANDLEIO 0x40 |
1905 | serge | 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=>=> |