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