2 * Buffered I/O for ffmpeg system
3 * Copyright (c) 2000,2001 Gerard Lantau
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <netinet/in.h>
24 #include <sys/ioctl.h>
32 #define IO_BUFFER_SIZE 32768
34 int init_put_byte(ByteIOContext *s,
35 unsigned char *buffer,
39 int (*read_packet)(void *opaque, UINT8 *buf, int buf_size),
40 void (*write_packet)(void *opaque, UINT8 *buf, int buf_size),
41 int (*seek)(void *opaque, offset_t offset, int whence))
44 s->buffer_size = buffer_size;
46 s->write_flag = write_flag;
50 s->buf_end = buffer + buffer_size;
52 s->write_packet = write_packet;
53 s->read_packet = read_packet;
64 static void flush_buffer(ByteIOContext *s)
66 if (s->buf_ptr > s->buffer) {
68 s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer);
69 s->pos += s->buf_ptr - s->buffer;
71 s->buf_ptr = s->buffer;
74 void put_byte(ByteIOContext *s, int b)
77 if (s->buf_ptr >= s->buf_end)
81 void put_buffer(ByteIOContext *s, unsigned char *buf, int size)
86 len = (s->buf_end - s->buf_ptr);
89 memcpy(s->buf_ptr, buf, len);
92 if (s->buf_ptr >= s->buf_end)
100 void put_flush_packet(ByteIOContext *s)
106 offset_t url_fseek(ByteIOContext *s, offset_t offset, int whence)
110 if (whence != SEEK_CUR && whence != SEEK_SET)
114 if (whence == SEEK_CUR) {
115 offset1 = s->pos + s->buf_ptr - s->buffer;
120 offset1 = offset - s->pos;
121 if (!s->must_flush &&
122 offset1 >= 0 && offset1 < (s->buf_end - s->buffer)) {
123 /* can do the seek inside the buffer */
124 s->buf_ptr = s->buffer + offset1;
130 s->buf_ptr = s->buffer;
131 s->seek(s->opaque, offset, SEEK_SET);
135 if (whence == SEEK_CUR) {
136 offset1 = s->pos - (s->buf_end - s->buffer) + (s->buf_ptr - s->buffer);
141 offset1 = offset - (s->pos - (s->buf_end - s->buffer));
142 if (offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) {
143 /* can do the seek inside the buffer */
144 s->buf_ptr = s->buffer + offset1;
148 s->buf_ptr = s->buffer;
149 s->buf_end = s->buffer;
151 s->seek(s->opaque, offset, SEEK_SET);
158 void url_fskip(ByteIOContext *s, offset_t offset)
160 url_fseek(s, offset, SEEK_CUR);
163 offset_t url_ftell(ByteIOContext *s)
165 return url_fseek(s, 0, SEEK_CUR);
168 int url_feof(ByteIOContext *s)
170 return s->eof_reached;
173 void put_le32(ByteIOContext *s, unsigned int val)
176 put_byte(s, val >> 8);
177 put_byte(s, val >> 16);
178 put_byte(s, val >> 24);
181 void put_be32(ByteIOContext *s, unsigned int val)
183 put_byte(s, val >> 24);
184 put_byte(s, val >> 16);
185 put_byte(s, val >> 8);
189 void put_le64(ByteIOContext *s, unsigned long long val)
191 put_le32(s, val & 0xffffffff);
192 put_le32(s, val >> 32);
195 void put_be64(ByteIOContext *s, unsigned long long val)
197 put_be32(s, val >> 32);
198 put_be32(s, val & 0xffffffff);
201 void put_le16(ByteIOContext *s, unsigned int val)
204 put_byte(s, val >> 8);
207 void put_be16(ByteIOContext *s, unsigned int val)
209 put_byte(s, val >> 8);
213 void put_tag(ByteIOContext *s, char *tag)
222 static void fill_buffer(ByteIOContext *s)
226 len = s->read_packet(s->opaque, s->buffer, s->buffer_size);
228 s->buf_ptr = s->buffer;
229 s->buf_end = s->buffer + len;
235 int get_byte(ByteIOContext *s)
237 if (s->buf_ptr < s->buf_end) {
238 return *s->buf_ptr++;
241 if (s->buf_ptr < s->buf_end)
242 return *s->buf_ptr++;
248 int get_buffer(ByteIOContext *s, unsigned char *buf, int size)
254 len = s->buf_end - s->buf_ptr;
259 len = s->buf_end - s->buf_ptr;
263 memcpy(buf, s->buf_ptr, len);
272 unsigned int get_le16(ByteIOContext *s)
276 val |= get_byte(s) << 8;
280 unsigned int get_le32(ByteIOContext *s)
284 val |= get_byte(s) << 8;
285 val |= get_byte(s) << 16;
286 val |= get_byte(s) << 24;
290 unsigned long long get_le64(ByteIOContext *s)
293 val = (UINT64)get_le32(s);
294 val |= (UINT64)get_le32(s) << 32;
298 unsigned int get_be16(ByteIOContext *s)
301 val = get_byte(s) << 8;
306 unsigned int get_be32(ByteIOContext *s)
309 val = get_byte(s) << 24;
310 val |= get_byte(s) << 16;
311 val |= get_byte(s) << 8;
316 unsigned long long get_be64(ByteIOContext *s)
319 val = (UINT64)get_be32(s) << 32;
320 val |= (UINT64)get_be32(s);
324 /* link with avio functions */
326 void url_write_packet(void *opaque, UINT8 *buf, int buf_size)
328 URLContext *h = opaque;
329 url_write(h, buf, buf_size);
332 int url_read_packet(void *opaque, UINT8 *buf, int buf_size)
334 URLContext *h = opaque;
335 return url_read(h, buf, buf_size);
338 int url_seek_packet(void *opaque, long long offset, int whence)
340 URLContext *h = opaque;
341 url_seek(h, offset, whence);
345 int url_fdopen(ByteIOContext *s, URLContext *h)
350 buffer_size = (IO_BUFFER_SIZE / h->packet_size) * h->packet_size;
351 buffer = malloc(buffer_size);
355 if (init_put_byte(s, buffer, buffer_size,
356 (h->flags & URL_WRONLY) != 0, h,
357 url_read_packet, url_write_packet, url_seek_packet) < 0) {
361 s->is_streamed = h->is_streamed;
362 s->packet_size = h->packet_size;
366 /* XXX: must be called before any I/O */
367 int url_setbufsize(ByteIOContext *s, int buf_size)
370 buffer = malloc(buf_size);
376 s->buffer_size = buf_size;
381 s->buf_end = buffer + buf_size;
385 int url_fopen(ByteIOContext *s, const char *filename, int flags)
390 err = url_open(&h, filename, flags);
393 err = url_fdopen(s, h);
401 int url_fclose(ByteIOContext *s)
403 URLContext *h = s->opaque;
406 memset(s, 0, sizeof(ByteIOContext));
410 URLContext *url_fileno(ByteIOContext *s)
415 /* buffer handling */
416 int url_open_buf(ByteIOContext *s, UINT8 *buf, int buf_size, int flags)
418 return init_put_byte(s, buf, buf_size,
419 (flags & URL_WRONLY) != 0, NULL, NULL, NULL, NULL);
422 /* return the written or read size */
423 int url_close_buf(ByteIOContext *s)
425 return s->buf_ptr - s->buffer;