1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * gnome-stream-vfs.c: Gnome VFS based stream implementation
6 * Michael Meeks <michael@helixcode.com>
8 * Copyright 2001, Ximian, Inc.
12 #include "bonobo-stream-vfs.h"
16 #include <libgnomevfs/gnome-vfs-ops.h>
20 static BonoboObjectClass *bonobo_stream_vfs_parent_class;
23 bonobo_stream_vfs_storageinfo_from_file_info (Bonobo_StorageInfo *si,
26 g_return_if_fail (si != NULL);
27 g_return_if_fail (fi != NULL);
29 si->name = CORBA_string_dup (fi->name);
31 if (fi->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)
36 if (fi->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE &&
37 fi->type == GNOME_VFS_FILE_TYPE_DIRECTORY)
38 si->type = Bonobo_STORAGE_TYPE_DIRECTORY;
40 si->type = Bonobo_STORAGE_TYPE_REGULAR;
42 if (fi->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE &&
44 si->content_type = CORBA_string_dup (fi->mime_type);
46 si->content_type = CORBA_string_dup ("");
49 static Bonobo_StorageInfo *
50 vfs_get_info (PortableServer_Servant stream,
51 const Bonobo_StorageInfoFields mask,
52 CORBA_Environment *ev)
54 BonoboStreamVfs *sfs = BONOBO_STREAM_VFS (
55 bonobo_object (stream));
56 Bonobo_StorageInfo *si;
58 GnomeVFSResult result;
60 if (mask & ~(Bonobo_FIELD_CONTENT_TYPE | Bonobo_FIELD_SIZE |
62 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
63 ex_Bonobo_Storage_NotSupported, NULL);
64 return CORBA_OBJECT_NIL;
67 fi = gnome_vfs_file_info_new ();
68 result = gnome_vfs_get_file_info_from_handle (
70 (mask & Bonobo_FIELD_CONTENT_TYPE) ?
71 GNOME_VFS_FILE_INFO_GET_MIME_TYPE :
72 GNOME_VFS_FILE_INFO_DEFAULT);
74 if (result != GNOME_VFS_OK) {
75 if (result == GNOME_VFS_ERROR_ACCESS_DENIED)
76 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
77 ex_Bonobo_Stream_NoPermission, NULL);
79 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
80 ex_Bonobo_Stream_IOError, NULL);
84 si = Bonobo_StorageInfo__alloc ();
86 bonobo_stream_vfs_storageinfo_from_file_info (si, fi);
88 gnome_vfs_file_info_unref (fi);
94 vfs_set_info (PortableServer_Servant stream,
95 const Bonobo_StorageInfo *info,
96 const Bonobo_StorageInfoFields mask,
97 CORBA_Environment *ev)
99 g_warning ("FIXME: set_info: a curious and not yet implemented API");
100 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
101 ex_Bonobo_Stream_NotSupported, NULL);
105 vfs_write (PortableServer_Servant stream,
106 const Bonobo_Stream_iobuf *buffer,
107 CORBA_Environment *ev)
109 BonoboStreamVfs *sfs = BONOBO_STREAM_VFS (
110 bonobo_object (stream));
111 GnomeVFSResult result;
112 GnomeVFSFileSize bytes_written;
115 result = gnome_vfs_write (sfs->handle, buffer->_buffer,
116 buffer->_length, &bytes_written);
117 } while (bytes_written < 1 && result == GNOME_VFS_ERROR_INTERRUPTED);
119 if (result != GNOME_VFS_OK)
120 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
121 ex_Bonobo_Stream_IOError, NULL);
125 vfs_read (PortableServer_Servant stream,
127 Bonobo_Stream_iobuf **buffer,
128 CORBA_Environment *ev)
130 BonoboStreamVfs *sfs = BONOBO_STREAM_VFS (
131 bonobo_object (stream));
132 GnomeVFSResult result;
133 GnomeVFSFileSize bytes_read;
136 *buffer = Bonobo_Stream_iobuf__alloc ();
137 CORBA_sequence_set_release (*buffer, TRUE);
139 data = CORBA_sequence_CORBA_octet_allocbuf (count);
142 result = gnome_vfs_read (sfs->handle, data,
144 } while (bytes_read < 1 && result == GNOME_VFS_ERROR_INTERRUPTED);
146 if (result == GNOME_VFS_ERROR_EOF) {
147 (*buffer)->_length = 0;
148 (*buffer)->_buffer = NULL;
150 } else if (result != GNOME_VFS_OK) {
152 CORBA_free (*buffer);
154 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
155 ex_Bonobo_Stream_IOError, NULL);
157 (*buffer)->_buffer = data;
158 (*buffer)->_length = bytes_read;
163 vfs_seek (PortableServer_Servant stream,
165 Bonobo_Stream_SeekType whence,
166 CORBA_Environment *ev)
168 BonoboStreamVfs *sfs = BONOBO_STREAM_VFS (
169 bonobo_object (stream));
170 GnomeVFSSeekPosition pos;
171 GnomeVFSResult result;
172 GnomeVFSFileOffset where;
175 case Bonobo_Stream_SeekCur:
176 pos = GNOME_VFS_SEEK_CURRENT;
178 case Bonobo_Stream_SeekEnd:
179 pos = GNOME_VFS_SEEK_END;
181 case Bonobo_Stream_SeekSet:
182 pos = GNOME_VFS_SEEK_START;
185 g_warning ("Seek whence %d unknown; fall back to SEEK_SET",
187 pos = GNOME_VFS_SEEK_START;
191 result = gnome_vfs_seek (sfs->handle, pos, offset);
193 if (result != GNOME_VFS_OK) {
194 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
195 ex_Bonobo_Stream_IOError, NULL);
199 result = gnome_vfs_tell (sfs->handle, &where);
201 if (result != GNOME_VFS_OK) {
202 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
203 ex_Bonobo_Stream_IOError, NULL);
211 vfs_truncate (PortableServer_Servant stream,
212 const CORBA_long new_size,
213 CORBA_Environment *ev)
215 BonoboStreamVfs *sfs = BONOBO_STREAM_VFS (
216 bonobo_object (stream));
217 GnomeVFSResult result;
219 result = gnome_vfs_truncate_handle (sfs->handle, new_size);
220 if (result == GNOME_VFS_OK)
223 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
224 ex_Bonobo_Stream_NoPermission, NULL);
228 vfs_commit (PortableServer_Servant stream,
229 CORBA_Environment *ev)
231 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
232 ex_Bonobo_Stream_NotSupported, NULL);
236 vfs_revert (PortableServer_Servant stream,
237 CORBA_Environment *ev)
239 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
240 ex_Bonobo_Stream_NotSupported, NULL);
244 vfs_destroy (BonoboObject *object)
246 BonoboStreamVfs *sfs = BONOBO_STREAM_VFS (object);
249 if (gnome_vfs_close (sfs->handle) != GNOME_VFS_OK)
250 g_warning ("VFS Close failed");
254 bonobo_stream_vfs_parent_class->destroy (object);
258 bonobo_stream_vfs_class_init (BonoboStreamVfsClass *klass)
260 POA_Bonobo_Stream__epv *epv = &klass->epv;
262 bonobo_stream_vfs_parent_class =
263 g_type_class_peek_parent (klass);
265 epv->getInfo = vfs_get_info;
266 epv->setInfo = vfs_set_info;
267 epv->write = vfs_write;
268 epv->read = vfs_read;
269 epv->seek = vfs_seek;
270 epv->truncate = vfs_truncate;
271 epv->commit = vfs_commit;
272 epv->revert = vfs_revert;
274 ((BonoboObjectClass *)klass)->destroy = vfs_destroy;
278 * bonobo_stream_vfs_get_type:
280 * Returns the GtkType for the BonoboStreamVfs class.
283 bonobo_stream_vfs_get_type (void)
285 static GType type = 0;
289 sizeof (BonoboStreamVfsClass),
290 (GBaseInitFunc) NULL,
291 (GBaseFinalizeFunc) NULL,
292 (GClassInitFunc) bonobo_stream_vfs_class_init,
293 NULL, /* class_finalize */
294 NULL, /* class_data */
295 sizeof (BonoboStreamVfs),
297 (GInstanceInitFunc) NULL
300 type = bonobo_type_unique (
302 POA_Bonobo_Stream__init, NULL,
303 G_STRUCT_OFFSET (BonoboStreamVfsClass, epv),
304 &info, "BonoboStreamVFS");
311 * bonobo_stream_vfs_open:
312 * @path: The path to the file to be opened.
313 * @mode: The mode with which the file should be opened.
315 * Creates a new BonoboStream object for the filename specified by
319 bonobo_stream_vfs_open (const char *path, Bonobo_Storage_OpenMode mode,
320 CORBA_Environment *ev)
322 GnomeVFSResult result;
323 GnomeVFSHandle *handle;
324 GnomeVFSOpenMode vfs_mode = GNOME_VFS_OPEN_NONE;
325 BonoboStreamVfs *stream_vfs;
327 g_return_val_if_fail (path != NULL, NULL);
329 if (mode == Bonobo_Storage_READ)
330 vfs_mode |= GNOME_VFS_OPEN_READ;
332 else if (mode == Bonobo_Storage_WRITE)
333 vfs_mode |= GNOME_VFS_OPEN_WRITE;
336 g_warning ("Unhandled open mode %d", mode);
340 result = gnome_vfs_open (&handle, path, vfs_mode);
341 if (vfs_mode & GNOME_VFS_OPEN_WRITE &&
342 result == GNOME_VFS_ERROR_NOT_FOUND)
343 result = gnome_vfs_create (&handle, path, vfs_mode,
344 FALSE, S_IRUSR | S_IWUSR);
346 if (result != GNOME_VFS_OK)
349 stream_vfs = g_object_new (bonobo_stream_vfs_get_type (), NULL);
353 stream_vfs->handle = handle;