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 #define IO_BUFFER_SIZE 32768
23 int init_put_byte(ByteIOContext
*s
,
24 unsigned char *buffer
,
28 int (*read_packet
)(void *opaque
, UINT8
*buf
, int buf_size
),
29 void (*write_packet
)(void *opaque
, UINT8
*buf
, int buf_size
),
30 int (*seek
)(void *opaque
, offset_t offset
, int whence
))
33 s
->buffer_size
= buffer_size
;
35 s
->write_flag
= write_flag
;
39 s
->buf_end
= buffer
+ buffer_size
;
41 s
->write_packet
= write_packet
;
42 s
->read_packet
= read_packet
;
53 static void flush_buffer(ByteIOContext
*s
)
55 if (s
->buf_ptr
> s
->buffer
) {
57 s
->write_packet(s
->opaque
, s
->buffer
, s
->buf_ptr
- s
->buffer
);
58 s
->pos
+= s
->buf_ptr
- s
->buffer
;
60 s
->buf_ptr
= s
->buffer
;
63 void put_byte(ByteIOContext
*s
, int b
)
66 if (s
->buf_ptr
>= s
->buf_end
)
70 void put_buffer(ByteIOContext
*s
, unsigned char *buf
, int size
)
75 len
= (s
->buf_end
- s
->buf_ptr
);
78 memcpy(s
->buf_ptr
, buf
, len
);
81 if (s
->buf_ptr
>= s
->buf_end
)
89 void put_flush_packet(ByteIOContext
*s
)
95 offset_t
url_fseek(ByteIOContext
*s
, offset_t offset
, int whence
)
99 if (whence
!= SEEK_CUR
&& whence
!= SEEK_SET
)
103 if (whence
== SEEK_CUR
) {
104 offset1
= s
->pos
+ s
->buf_ptr
- s
->buffer
;
109 offset1
= offset
- s
->pos
;
110 if (!s
->must_flush
&&
111 offset1
>= 0 && offset1
< (s
->buf_end
- s
->buffer
)) {
112 /* can do the seek inside the buffer */
113 s
->buf_ptr
= s
->buffer
+ offset1
;
119 s
->buf_ptr
= s
->buffer
;
120 s
->seek(s
->opaque
, offset
, SEEK_SET
);
124 if (whence
== SEEK_CUR
) {
125 offset1
= s
->pos
- (s
->buf_end
- s
->buffer
) + (s
->buf_ptr
- s
->buffer
);
130 offset1
= offset
- (s
->pos
- (s
->buf_end
- s
->buffer
));
131 if (offset1
>= 0 && offset1
<= (s
->buf_end
- s
->buffer
)) {
132 /* can do the seek inside the buffer */
133 s
->buf_ptr
= s
->buffer
+ offset1
;
137 s
->buf_ptr
= s
->buffer
;
138 s
->buf_end
= s
->buffer
;
140 s
->seek(s
->opaque
, offset
, SEEK_SET
);
147 void url_fskip(ByteIOContext
*s
, offset_t offset
)
149 url_fseek(s
, offset
, SEEK_CUR
);
152 offset_t
url_ftell(ByteIOContext
*s
)
154 return url_fseek(s
, 0, SEEK_CUR
);
157 int url_feof(ByteIOContext
*s
)
159 return s
->eof_reached
;
162 void put_le32(ByteIOContext
*s
, unsigned int val
)
165 put_byte(s
, val
>> 8);
166 put_byte(s
, val
>> 16);
167 put_byte(s
, val
>> 24);
170 void put_be32(ByteIOContext
*s
, unsigned int val
)
172 put_byte(s
, val
>> 24);
173 put_byte(s
, val
>> 16);
174 put_byte(s
, val
>> 8);
178 void put_le64(ByteIOContext
*s
, UINT64 val
)
180 put_le32(s
, (UINT32
)(val
& 0xffffffff));
181 put_le32(s
, (UINT32
)(val
>> 32));
184 void put_be64(ByteIOContext
*s
, UINT64 val
)
186 put_be32(s
, (UINT32
)(val
>> 32));
187 put_be32(s
, (UINT32
)(val
& 0xffffffff));
190 void put_le16(ByteIOContext
*s
, unsigned int val
)
193 put_byte(s
, val
>> 8);
196 void put_be16(ByteIOContext
*s
, unsigned int val
)
198 put_byte(s
, val
>> 8);
202 void put_tag(ByteIOContext
*s
, char *tag
)
211 static void fill_buffer(ByteIOContext
*s
)
215 len
= s
->read_packet(s
->opaque
, s
->buffer
, s
->buffer_size
);
217 s
->buf_ptr
= s
->buffer
;
218 s
->buf_end
= s
->buffer
+ len
;
224 int get_byte(ByteIOContext
*s
)
226 if (s
->buf_ptr
< s
->buf_end
) {
227 return *s
->buf_ptr
++;
230 if (s
->buf_ptr
< s
->buf_end
)
231 return *s
->buf_ptr
++;
237 int get_buffer(ByteIOContext
*s
, unsigned char *buf
, int size
)
243 len
= s
->buf_end
- s
->buf_ptr
;
248 len
= s
->buf_end
- s
->buf_ptr
;
252 memcpy(buf
, s
->buf_ptr
, len
);
261 unsigned int get_le16(ByteIOContext
*s
)
265 val
|= get_byte(s
) << 8;
269 unsigned int get_le32(ByteIOContext
*s
)
273 val
|= get_byte(s
) << 8;
274 val
|= get_byte(s
) << 16;
275 val
|= get_byte(s
) << 24;
279 UINT64
get_le64(ByteIOContext
*s
)
282 val
= (UINT64
)get_le32(s
);
283 val
|= (UINT64
)get_le32(s
) << 32;
287 unsigned int get_be16(ByteIOContext
*s
)
290 val
= get_byte(s
) << 8;
295 unsigned int get_be32(ByteIOContext
*s
)
298 val
= get_byte(s
) << 24;
299 val
|= get_byte(s
) << 16;
300 val
|= get_byte(s
) << 8;
305 UINT64
get_be64(ByteIOContext
*s
)
308 val
= (UINT64
)get_be32(s
) << 32;
309 val
|= (UINT64
)get_be32(s
);
313 /* link with avio functions */
315 void url_write_packet(void *opaque
, UINT8
*buf
, int buf_size
)
317 URLContext
*h
= opaque
;
318 url_write(h
, buf
, buf_size
);
321 int url_read_packet(void *opaque
, UINT8
*buf
, int buf_size
)
323 URLContext
*h
= opaque
;
324 return url_read(h
, buf
, buf_size
);
327 int url_seek_packet(void *opaque
, INT64 offset
, int whence
)
329 URLContext
*h
= opaque
;
330 url_seek(h
, offset
, whence
);
334 int url_fdopen(ByteIOContext
*s
, URLContext
*h
)
339 buffer_size
= (IO_BUFFER_SIZE
/ h
->packet_size
) * h
->packet_size
;
340 buffer
= malloc(buffer_size
);
344 if (init_put_byte(s
, buffer
, buffer_size
,
345 (h
->flags
& URL_WRONLY
) != 0, h
,
346 url_read_packet
, url_write_packet
, url_seek_packet
) < 0) {
350 s
->is_streamed
= h
->is_streamed
;
351 s
->packet_size
= h
->packet_size
;
355 /* XXX: must be called before any I/O */
356 int url_setbufsize(ByteIOContext
*s
, int buf_size
)
359 buffer
= malloc(buf_size
);
365 s
->buffer_size
= buf_size
;
370 s
->buf_end
= buffer
+ buf_size
;
374 int url_fopen(ByteIOContext
*s
, const char *filename
, int flags
)
379 err
= url_open(&h
, filename
, flags
);
382 err
= url_fdopen(s
, h
);
390 int url_fclose(ByteIOContext
*s
)
392 URLContext
*h
= s
->opaque
;
395 memset(s
, 0, sizeof(ByteIOContext
));
399 URLContext
*url_fileno(ByteIOContext
*s
)
404 /* buffer handling */
405 int url_open_buf(ByteIOContext
*s
, UINT8
*buf
, int buf_size
, int flags
)
407 return init_put_byte(s
, buf
, buf_size
,
408 (flags
& URL_WRONLY
) != 0, NULL
, NULL
, NULL
, NULL
);
411 /* return the written or read size */
412 int url_close_buf(ByteIOContext
*s
)
414 return s
->buf_ptr
- s
->buffer
;