1 /*
2 * Copyright (C) 2000-2018 the xine project
3 * Copyright (C) 2018 Petri Hintukainen <phintuka@users.sourceforge.net>
4 *
5 * This file is part of xine, a free video player.
6 *
7 * xine is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * xine is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 *
21 * input plugin helper functions
22 */
23
24 #ifndef XINE_INPUT_HELPER_H
25 #define XINE_INPUT_HELPER_H
26
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30
31 #include <errno.h>
32 #include <sys/types.h>
33
34 #include <xine/attributes.h>
35 #include <xine/xine_internal.h>
36 #include <xine/xineutils.h>
37
38 /*
39 * mrl array alloc / free helpers
40 */
41
42 void _x_input_free_mrls(xine_mrl_t ***p);
43 xine_mrl_t **_x_input_alloc_mrls(size_t n);
44 xine_mrl_t **_x_input_realloc_mrls(xine_mrl_t ***p, size_t n);
45
46 void _x_input_sort_mrls(xine_mrl_t **mrls, ssize_t cnt /* optional, may be -1 */);
47
48 /*
49 * config helpers
50 */
51
52 void _x_input_register_show_hidden_files(config_values_t *config);
53 int _x_input_get_show_hidden_files(config_values_t *config);
54
55 void _x_input_register_default_servers(config_values_t *config);
56 xine_mrl_t **_x_input_get_default_server_mrls(config_values_t *config, const char *type, int *nFiles);
57
58 /*
59 * default read_block function.
60 * uses read() to fill the block.
61 */
62 buf_element_t *_x_input_default_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo);
63
_x_input_get_capabilities_preview(input_plugin_t * this_gen)64 static inline uint32_t _x_input_get_capabilities_preview (input_plugin_t *this_gen)
65 {
66 (void)this_gen;
67 return INPUT_CAP_PREVIEW;
68 }
69
_x_input_get_capabilities_seekable(input_plugin_t * this_gen)70 static inline uint32_t _x_input_get_capabilities_seekable (input_plugin_t *this_gen)
71 {
72 (void)this_gen;
73 return INPUT_CAP_SEEKABLE;
74 }
75
_x_input_get_capabilities_none(input_plugin_t * this_gen)76 static inline uint32_t _x_input_get_capabilities_none (input_plugin_t *this_gen)
77 {
78 (void)this_gen;
79 return INPUT_CAP_NOCAP;
80 }
81
_x_input_default_get_blocksize(input_plugin_t * this_gen)82 static inline uint32_t _x_input_default_get_blocksize (input_plugin_t *this_gen)
83 {
84 (void)this_gen;
85 return 0;
86 }
87
_x_input_default_get_length(input_plugin_t * this_gen)88 static inline off_t _x_input_default_get_length (input_plugin_t *this_gen)
89 {
90 (void)this_gen;
91 return 0;
92 }
93
_x_input_default_get_optional_data(input_plugin_t * this_gen,void * data,int data_type)94 static inline int _x_input_default_get_optional_data (input_plugin_t *this_gen, void *data, int data_type)
95 {
96 (void)this_gen;
97 (void)data;
98 (void)data_type;
99 return INPUT_OPTIONAL_UNSUPPORTED;
100 }
101
102 /*
103 * translate (offset, origin) to absolute position
104 */
_x_input_translate_seek(off_t offset,int origin,off_t curpos,off_t length)105 static inline off_t _x_input_translate_seek(off_t offset, int origin, off_t curpos, off_t length)
106 {
107 switch (origin) {
108 case SEEK_SET: break;
109 case SEEK_CUR: offset += curpos; break;
110 case SEEK_END: offset = (length <= 0) ? (-1) : (offset + length); break;
111 default: offset = -1; break;
112 }
113
114 if (offset < 0 || (length > 0 && offset > length)) {
115 errno = EINVAL;
116 return (off_t)-1;
117 }
118
119 return offset;
120 }
121
122 /*
123 * seek forward by skipping data
124 */
125 #define MAX_SKIP_BYTES (10*1024*1024) // 10 MB
_x_input_read_skip(input_plugin_t * input,off_t bytes)126 static inline int _x_input_read_skip(input_plugin_t *input, off_t bytes)
127 {
128 char buf[1024];
129 const off_t max = sizeof(buf);
130
131 _x_assert(bytes >= 0);
132
133 if (bytes > MAX_SKIP_BYTES) {
134 /* seeking forward gigabytes would take long time ... */
135 return -1;
136 }
137
138 while (bytes > 0) {
139 off_t got = input->read(input, buf, (bytes > max) ? max : bytes);
140 if (got <= 0)
141 return -1;
142 bytes -= got;
143 }
144
145 _x_assert(bytes == 0);
146 return 0;
147 }
148
149 /*
150 * generic seek function for non-seekable input plugins
151 */
_x_input_seek_preview(input_plugin_t * input,off_t offset,int origin,off_t * curpos,off_t length,off_t preview_size)152 static inline off_t _x_input_seek_preview(input_plugin_t *input, off_t offset, int origin,
153 off_t *curpos, off_t length, off_t preview_size)
154 {
155 offset = _x_input_translate_seek(offset, origin, *curpos, length);
156 if (offset < 0)
157 goto fail;
158
159 /* seek inside preview */
160 if (offset <= preview_size && *curpos <= preview_size) {
161 *curpos = offset;
162 return offset;
163 }
164
165 /* can't seek back */
166 if (offset < *curpos)
167 goto fail;
168
169 if (_x_input_read_skip(input, offset - *curpos) < 0)
170 return -1;
171
172 _x_assert(offset == *curpos);
173 return offset;
174
175 fail:
176 errno = EINVAL;
177 return (off_t)-1;
178 }
179
180 #ifdef __cplusplus
181 }
182 #endif
183
184 #endif /* XINE_INPUT_HELPER_H */
185