merge
[libav.git] / libav / avio.c
1 /*
2 * Unbuffered io for ffmpeg system
3 * Copyright (c) 2001 Gerard Lantau
4 *
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.
9 *
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.
14 *
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.
18 */
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <errno.h>
23
24 #include "avformat.h"
25
26 URLProtocol *first_protocol = NULL;
27
28 int register_protocol(URLProtocol *protocol)
29 {
30 URLProtocol **p;
31 p = &first_protocol;
32 while (*p != NULL) p = &(*p)->next;
33 *p = protocol;
34 protocol->next = NULL;
35 return 0;
36 }
37
38 int url_open(URLContext **puc, const char *filename, int flags)
39 {
40 URLContext *uc;
41 URLProtocol *up;
42 const char *p;
43 char proto_str[128], *q;
44 int err;
45
46 p = filename;
47 q = proto_str;
48 while (*p != '\0' && *p != ':') {
49 if ((q - proto_str) < sizeof(proto_str) - 1)
50 *q++ = *p;
51 p++;
52 }
53 if (*p == '\0') {
54 strcpy(proto_str, "file");
55 } else {
56 *q = '\0';
57 }
58
59 up = first_protocol;
60 while (up != NULL) {
61 if (!strcmp(proto_str, up->name))
62 goto found;
63 up = up->next;
64 }
65 return -ENOENT;
66 found:
67 uc = malloc(sizeof(URLContext));
68 if (!uc)
69 return -ENOMEM;
70 uc->prot = up;
71 uc->flags = flags;
72 uc->is_streamed = 0; /* default = not streamed */
73 uc->packet_size = 1; /* default packet size */
74 err = up->url_open(uc, filename, flags);
75 if (err < 0) {
76 free(uc);
77 *puc = NULL;
78 return err;
79 }
80 *puc = uc;
81 return 0;
82 }
83
84 int url_read(URLContext *h, unsigned char *buf, int size)
85 {
86 int ret;
87 if (h->flags & URL_WRONLY)
88 return -EIO;
89 ret = h->prot->url_read(h, buf, size);
90 return ret;
91 }
92
93 int url_write(URLContext *h, unsigned char *buf, int size)
94 {
95 int ret;
96 if (!(h->flags & URL_WRONLY))
97 return -EIO;
98 ret = h->prot->url_write(h, buf, size);
99 return ret;
100 }
101
102 offset_t url_seek(URLContext *h, offset_t pos, int whence)
103 {
104 offset_t ret;
105
106 if (!h->prot->url_seek)
107 return -EPIPE;
108 ret = h->prot->url_seek(h, pos, whence);
109 return ret;
110 }
111
112 int url_getformat(URLContext *h, URLFormat *f)
113 {
114 memset(f, 0, sizeof(*f));
115 if (!h->prot->url_getformat)
116 return -ENODATA;
117 return h->prot->url_getformat(h, f);
118 }
119
120 int url_close(URLContext *h)
121 {
122 int ret;
123
124 ret = h->prot->url_close(h);
125 free(h);
126 return ret;
127 }
128
129 int url_exist(const char *filename)
130 {
131 URLContext *h;
132 if (url_open(&h, filename, URL_RDONLY) < 0)
133 return 0;
134 url_close(h);
135 return 1;
136 }
137
138 offset_t url_filesize(URLContext *h)
139 {
140 offset_t pos, size;
141
142 pos = url_seek(h, 0, SEEK_CUR);
143 size = url_seek(h, 0, SEEK_END);
144 url_seek(h, pos, SEEK_SET);
145 return size;
146 }