1 /* -*- Mode: C; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3 -*- */
2
3 /*
4 * GImageView
5 * Copyright (C) 2001 Takuro Ashie
6 *
7 * This program 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 * This program 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 *
21 * $Id: gimv_io.c,v 1.10 2004/09/21 08:44:32 makeinu Exp $
22 */
23
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27
28 #include "gimv_io.h"
29 #include "gimv_io_file.h"
30
31
32 /****************************************************************************
33 *
34 * Plugin Management
35 *
36 ****************************************************************************/
37 static GList *gimv_io_list = NULL;
38
39
40 static gint
comp_func_priority(GimvIOPlugin * plugin1,GimvIOPlugin * plugin2)41 comp_func_priority (GimvIOPlugin *plugin1,
42 GimvIOPlugin *plugin2)
43 {
44 g_return_val_if_fail (plugin1, 1);
45 g_return_val_if_fail (plugin2, -1);
46
47 return plugin1->priority_hint - plugin2->priority_hint;
48 }
49
50
51 gboolean
gimv_io_plugin_regist(const gchar * plugin_name,const gchar * module_name,gpointer impl,gint size)52 gimv_io_plugin_regist (const gchar *plugin_name,
53 const gchar *module_name,
54 gpointer impl,
55 gint size)
56 {
57 GimvIOPlugin *streamer = impl;
58
59 g_return_val_if_fail (module_name, FALSE);
60 g_return_val_if_fail (streamer, FALSE);
61 g_return_val_if_fail (size > 0, FALSE);
62 g_return_val_if_fail (streamer->id, FALSE);
63 g_return_val_if_fail (streamer->if_version == GIMV_IO_IF_VERSION, FALSE);
64 g_return_val_if_fail (streamer->new_func, FALSE);
65
66 gimv_io_list = g_list_append (gimv_io_list, streamer);
67 gimv_io_list = g_list_sort (gimv_io_list,
68 (GCompareFunc) comp_func_priority);
69
70 return TRUE;
71 }
72
73
74 /****************************************************************************
75 *
76 *
77 *
78 ****************************************************************************/
79 void
gimv_io_init(GimvIO * gio,const gchar * url)80 gimv_io_init (GimvIO *gio, const gchar *url)
81 {
82 g_return_if_fail (gio);
83 /* g_return_if_fail (url); */
84
85 gio->funcs = NULL;
86 gio->url = g_strdup (url);
87 gio->ref_count = 1;
88 }
89
90
91 GimvIO *
gimv_io_new(const gchar * url,const gchar * mode)92 gimv_io_new (const gchar *url, const gchar *mode)
93 {
94 GList *node;
95
96 g_return_val_if_fail (url, NULL);
97
98 for (node = gimv_io_list; node; node = g_list_next (node)) {
99 GimvIOPlugin *plugin = node->data;
100 GimvIO *gio;
101
102 gio = plugin->new_func (url, mode);
103 if (gio) return gio;
104 }
105
106 return gimv_io_file_new (url, mode);
107 }
108
109
110 GimvIO *
gimv_io_ref(GimvIO * gio)111 gimv_io_ref (GimvIO *gio)
112 {
113 g_return_val_if_fail (gio, NULL);
114
115 gio->ref_count++;
116
117 return gio;
118 }
119
120
121 void
gimv_io_unref(GimvIO * gio)122 gimv_io_unref (GimvIO *gio)
123 {
124 g_return_if_fail (gio);
125
126 gio->ref_count--;
127
128 if (gio->ref_count < 1)
129 gimv_io_close (gio);
130 }
131
132
133 GimvIOStatus
gimv_io_read(GimvIO * gio,gchar * buf,guint count,guint * bytes_read)134 gimv_io_read (GimvIO *gio,
135 gchar *buf,
136 guint count,
137 guint *bytes_read)
138 {
139 g_return_val_if_fail (gio, GIMV_IO_STATUS_ERROR);
140 g_return_val_if_fail (bytes_read, GIMV_IO_STATUS_ERROR);
141 g_return_val_if_fail (gio->funcs, GIMV_IO_STATUS_ERROR);
142 g_return_val_if_fail (gio->funcs->read, GIMV_IO_STATUS_ERROR);
143
144 return gio->funcs->read (gio, buf, count, bytes_read);
145 }
146
147
148 GimvIOStatus
gimv_io_write(GimvIO * gio,const gchar * buf,guint count,guint * bytes_written)149 gimv_io_write (GimvIO *gio,
150 const gchar *buf,
151 guint count,
152 guint *bytes_written)
153 {
154 g_return_val_if_fail (gio, GIMV_IO_STATUS_ERROR);
155 g_return_val_if_fail (bytes_written, GIMV_IO_STATUS_ERROR);
156 g_return_val_if_fail (gio->funcs, GIMV_IO_STATUS_ERROR);
157 g_return_val_if_fail (gio->funcs->write, GIMV_IO_STATUS_ERROR);
158
159 return gio->funcs->write (gio, buf, count, bytes_written);
160 }
161
162
163 GimvIOStatus
gimv_io_seek(GimvIO * gio,glong offset,gint whence)164 gimv_io_seek (GimvIO *gio,
165 glong offset,
166 gint whence)
167 {
168 g_return_val_if_fail (gio, GIMV_IO_STATUS_ERROR);
169 g_return_val_if_fail (gio->funcs, GIMV_IO_STATUS_ERROR);
170 g_return_val_if_fail (gio->funcs->seek, GIMV_IO_STATUS_ERROR);
171
172 switch (whence) {
173 case SEEK_CUR:
174 case SEEK_SET:
175 case SEEK_END:
176 break;
177 default:
178 return GIMV_IO_STATUS_ERROR;
179 }
180
181 return gio->funcs->seek (gio, offset, whence);
182 }
183
184
185 GimvIOStatus
gimv_io_tell(GimvIO * gio,glong * offset)186 gimv_io_tell (GimvIO *gio,
187 glong *offset)
188 {
189 g_return_val_if_fail (gio, GIMV_IO_STATUS_ERROR);
190 g_return_val_if_fail (offset, GIMV_IO_STATUS_ERROR);
191 g_return_val_if_fail (gio->funcs, GIMV_IO_STATUS_ERROR);
192 g_return_val_if_fail (gio->funcs->tell, GIMV_IO_STATUS_ERROR);
193
194 return gio->funcs->tell (gio, offset);
195 }
196
197
198 void
gimv_io_close(GimvIO * gio)199 gimv_io_close (GimvIO *gio)
200 {
201 g_return_if_fail (gio);
202 g_return_if_fail (gio->funcs);
203 g_return_if_fail (gio->funcs->close);
204
205 gio->funcs->close (gio);
206
207 g_free (gio->url);
208 g_free (gio);
209 }
210
211
212 gint
gimv_io_getc(GimvIO * gio,GimvIOStatus * status)213 gimv_io_getc (GimvIO *gio, GimvIOStatus *status)
214 {
215 guint bytes_read;
216 guchar c;
217
218 gimv_io_read (gio, &c, 1, &bytes_read);
219
220 if (bytes_read < 1) {
221 if (status)
222 *status = GIMV_IO_STATUS_ERROR;
223 return EOF;
224 } else {
225 if (status)
226 *status = GIMV_IO_STATUS_NORMAL;
227 return (gint) c;
228 }
229 }
230
231
232 GimvIOStatus
gimv_io_fgets(GimvIO * gio,gchar * buf,guint count)233 gimv_io_fgets (GimvIO *gio, gchar *buf, guint count)
234 {
235 guint i;
236 guint bytes_read;
237 guint len = 0;
238
239 g_return_val_if_fail (gio, GIMV_IO_STATUS_ERROR);
240 g_return_val_if_fail (buf, GIMV_IO_STATUS_ERROR);
241
242 for (i = 0; i < count - 2; i++) {
243 gimv_io_read (gio, &buf[i], 1, &bytes_read);
244 if (bytes_read < 1) {
245 buf[i] = '\0';
246 return GIMV_IO_STATUS_ERROR;
247 }
248
249 len = i + 1;
250
251 if (buf[i] == '\n') break;
252 }
253
254 buf[len] = '\0';
255
256 return GIMV_IO_STATUS_NORMAL;
257 }
258