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
;