1 #ifndef IO_H 2 #define IO_H 3 4 /* curl sometimes needs this */ 5 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 #include <sys/time.h> 9 #ifdef HAVE_SYS_SELECT_H 10 # include <sys/select.h> 11 #endif 12 #include <unistd.h> /* for [s]size_t */ 13 #include <pthread.h> 14 #ifdef HAVE_CURL 15 # include <curl/curl.h> 16 #endif 17 18 #include "fifo_buf.h" 19 20 #ifdef __cplusplus 21 extern "C" { 22 #endif 23 24 enum io_source 25 { 26 IO_SOURCE_FD, 27 IO_SOURCE_MMAP, 28 IO_SOURCE_CURL 29 }; 30 31 #ifdef HAVE_CURL 32 struct io_stream_curl 33 { 34 CURLM *multi_handle; /* we use the multi interface to get the 35 data in pieces */ 36 CURL *handle; /* the actual used handle */ 37 CURLMcode multi_status; /* curl status of the last multi operation */ 38 CURLcode status; /* curl status of the last easy operation */ 39 char *url; 40 struct curl_slist *http_headers; /* HTTP headers to send with 41 the request */ 42 char *buf; /* buffer for data that curl gives us */ 43 long buf_fill; 44 int need_perform_loop; /* do we need the perform() loop? */ 45 int got_locn; /* received a location header */ 46 char *mime_type; /* mime type of the stream */ 47 int wake_up_pipe[2]; /* pipes used to wake up the curl read 48 loop that does select() */ 49 struct curl_slist *http200_aliases; /* list of aliases for http 50 response's status line */ 51 size_t icy_meta_int; /* how often are icy metadata sent? 52 0 - disabled, in bytes */ 53 size_t icy_meta_count; /* how many bytes was read from the last 54 metadata packet */ 55 }; 56 #endif 57 58 struct io_stream; 59 60 typedef void (*buf_fill_callback_t) (struct io_stream *s, size_t fill, 61 size_t buf_size, void *data_ptr); 62 63 struct io_stream 64 { 65 enum io_source source; /* source of the file */ 66 int fd; 67 off_t size; /* size of the file */ 68 int errno_val; /* errno value of the last operation - 0 if ok */ 69 int read_error; /* set to != 0 if the last read operation dailed */ 70 char *strerror; /* error string */ 71 int opened; /* was the stream opened (open(), mmap(), etc.)? */ 72 int eof; /* was the end of file reached? */ 73 int after_seek; /* are we after seek and need to do fresh read()? */ 74 int buffered; /* are we using the buffer? */ 75 off_t pos; /* current position in the file from the user point of view */ 76 size_t prebuffer; /* number of bytes left to prebuffer */ 77 pthread_mutex_t io_mutex; /* mutex for IO operations */ 78 79 #ifdef HAVE_MMAP 80 void *mem; 81 off_t mem_pos; 82 #endif 83 84 #ifdef HAVE_CURL 85 struct io_stream_curl curl; 86 #endif 87 88 struct fifo_buf buf; 89 pthread_mutex_t buf_mutex; 90 pthread_cond_t buf_free_cond; /* some space became available in the 91 buffer */ 92 pthread_cond_t buf_fill_cond; /* the buffer was filled with some data */ 93 pthread_t read_thread; 94 int stop_read_thread; /* request for stopping the read 95 thread */ 96 97 struct stream_metadata { 98 pthread_mutex_t mutex; 99 char *title; /* title of the stream */ 100 char *url; 101 } metadata; 102 103 /* callbacks */ 104 buf_fill_callback_t buf_fill_callback; 105 void *buf_fill_callback_data; 106 }; 107 108 struct io_stream *io_open (const char *file, const int buffered); 109 ssize_t io_read (struct io_stream *s, void *buf, size_t count); 110 ssize_t io_peek (struct io_stream *s, void *buf, size_t count); 111 off_t io_seek (struct io_stream *s, off_t offset, int whence); 112 void io_close (struct io_stream *s); 113 int io_ok (struct io_stream *s); 114 char *io_strerror (struct io_stream *s); 115 off_t io_file_size (const struct io_stream *s); 116 off_t io_tell (struct io_stream *s); 117 int io_eof (struct io_stream *s); 118 void io_init (); 119 void io_cleanup (); 120 void io_abort (struct io_stream *s); 121 char *io_get_mime_type (struct io_stream *s); 122 char *io_get_title (struct io_stream *s); 123 char *io_get_metadata_title (struct io_stream *s); 124 char *io_get_metadata_url (struct io_stream *s); 125 void io_set_metadata_title (struct io_stream *s, const char *title); 126 void io_set_metadata_url (struct io_stream *s, const char *url); 127 void io_prebuffer (struct io_stream *s, const size_t to_fill); 128 void io_set_buf_fill_callback (struct io_stream *s, 129 buf_fill_callback_t callback, void *data_ptr); 130 int io_seekable (const struct io_stream *s); 131 132 #ifdef __cplusplus 133 } 134 #endif 135 136 #endif 137