diff options
author | Not Zed <NotZed@Ximian.com> | 2004-11-12 13:54:07 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2004-11-12 13:54:07 +0800 |
commit | d25f16e9ea91dc50cc8477576c6a7def086d34c7 (patch) | |
tree | afd1003f6acc2573c505d25b74d3e1f3c8b1691c /mail/em-vfs-stream.c | |
parent | 8e212824134c1740d05fb36799f78716c5059801 (diff) | |
download | gsoc2013-evolution-d25f16e9ea91dc50cc8477576c6a7def086d34c7.tar.gz gsoc2013-evolution-d25f16e9ea91dc50cc8477576c6a7def086d34c7.tar.zst gsoc2013-evolution-d25f16e9ea91dc50cc8477576c6a7def086d34c7.zip |
** Merge in notzed-messageinfo-branch.
2004-11-12 Not Zed <NotZed@Ximian.com>
** Merge in notzed-messageinfo-branch.
svn path=/trunk/; revision=27899
Diffstat (limited to 'mail/em-vfs-stream.c')
-rw-r--r-- | mail/em-vfs-stream.c | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/mail/em-vfs-stream.c b/mail/em-vfs-stream.c new file mode 100644 index 0000000000..af23862988 --- /dev/null +++ b/mail/em-vfs-stream.c @@ -0,0 +1,323 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Authors: Michael Zucchi <notzed@ximian.com> + * + * Copyright 2004 Ximian, Inc. (www.ximian.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * A GnomeVFS to CamelStream mapper. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string.h> +#include <stdio.h> +#include <errno.h> + +#include <libgnomevfs/gnome-vfs.h> + +#include "em-vfs-stream.h" + +#define LOG_STREAM + +#define d(x) + +#define EMVS_CLASS(x) ((EMVFSStreamClass *)(((CamelObject *)(x))->klass)) + +static CamelStreamClass *parent_class = NULL; + +static void +em_vfs_stream_init (CamelObject *object) +{ + /*EMVFSStream *emvfs = (EMVFSStream *)object;*/ +} + +static void +em_vfs_stream_finalize (CamelObject *object) +{ + EMVFSStream *emvfs = (EMVFSStream *)object; + + if (emvfs->handle) + gnome_vfs_close(emvfs->handle); +} + +static void +emvfs_set_errno(GnomeVFSResult res) +{ + switch(res) { + case GNOME_VFS_OK: + g_warning("em-vfs-stream: calling set_errno with no error"); + break; + case GNOME_VFS_ERROR_NOT_FOUND: + case GNOME_VFS_ERROR_HOST_NOT_FOUND: + case GNOME_VFS_ERROR_INVALID_HOST_NAME: + case GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS: + case GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE: + errno = ENOENT; + break; + case GNOME_VFS_ERROR_GENERIC: + case GNOME_VFS_ERROR_INTERNAL: + case GNOME_VFS_ERROR_IO: + case GNOME_VFS_ERROR_EOF: /* will be caught by read before here anyway */ + case GNOME_VFS_ERROR_SERVICE_OBSOLETE: + case GNOME_VFS_ERROR_PROTOCOL_ERROR: + default: + errno = EIO; + break; + case GNOME_VFS_ERROR_BAD_PARAMETERS: + case GNOME_VFS_ERROR_NOT_SUPPORTED: + case GNOME_VFS_ERROR_INVALID_URI: + case GNOME_VFS_ERROR_NOT_OPEN: + case GNOME_VFS_ERROR_INVALID_OPEN_MODE: + case GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM: + errno = EINVAL; + break; + case GNOME_VFS_ERROR_CORRUPTED_DATA: /* not sure about these */ + case GNOME_VFS_ERROR_WRONG_FORMAT: + case GNOME_VFS_ERROR_BAD_FILE: + errno = EBADF; + break; + case GNOME_VFS_ERROR_TOO_BIG: + errno = E2BIG; + break; + case GNOME_VFS_ERROR_NO_SPACE: + errno = ENOSPC; + break; + case GNOME_VFS_ERROR_READ_ONLY: + case GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM: + errno = EROFS; + break; + case GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES: + errno = EMFILE; + break; + case GNOME_VFS_ERROR_NOT_A_DIRECTORY: + errno = ENOTDIR; + break; + case GNOME_VFS_ERROR_IN_PROGRESS: + errno = EINPROGRESS; + break; + case GNOME_VFS_ERROR_INTERRUPTED: + errno = EINTR; + break; + case GNOME_VFS_ERROR_FILE_EXISTS: + errno = EEXIST; + case GNOME_VFS_ERROR_LOOP: + errno = ELOOP; + break; + case GNOME_VFS_ERROR_ACCESS_DENIED: + case GNOME_VFS_ERROR_NOT_PERMITTED: + case GNOME_VFS_ERROR_LOGIN_FAILED: + errno = EPERM; + break; + case GNOME_VFS_ERROR_IS_DIRECTORY: + case GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY: /* ?? */ + errno = EISDIR; + break; + case GNOME_VFS_ERROR_NO_MEMORY: + errno = ENOMEM; + break; + case GNOME_VFS_ERROR_CANCELLED: + errno = EINTR; + break; + case GNOME_VFS_ERROR_DIRECTORY_BUSY: + errno = EBUSY; + break; + case GNOME_VFS_ERROR_TOO_MANY_LINKS: + errno = EMLINK; + break; + case GNOME_VFS_ERROR_NAME_TOO_LONG: + errno = ENAMETOOLONG; + break; + } +} + +static ssize_t +emvfs_read(CamelStream *stream, char *buffer, size_t n) +{ + EMVFSStream *emvfs = EM_VFS_STREAM (stream); + GnomeVFSFileSize count; + GnomeVFSResult res; + + if (emvfs->handle == NULL) { + errno = EINVAL; + return -1; + } + + /* TODO: handle camel cancellation? */ + + res = gnome_vfs_read(emvfs->handle, buffer, n, &count); + if (res == GNOME_VFS_OK) + return (ssize_t)count; + else if (res == GNOME_VFS_ERROR_EOF) { + stream->eos = TRUE; + return 0; + } + + emvfs_set_errno(res); + + return -1; +} + +static ssize_t +emvfs_write(CamelStream *stream, const char *buffer, size_t n) +{ + EMVFSStream *emvfs = EM_VFS_STREAM (stream); + GnomeVFSFileSize count; + GnomeVFSResult res; + + if (emvfs->handle == NULL) { + errno = EINVAL; + return -1; + } + + res = gnome_vfs_write(emvfs->handle, buffer, n, &count); + if (res == GNOME_VFS_OK) + return (ssize_t)count; + + emvfs_set_errno(res); + + return -1; +} + +static int +emvfs_close(CamelStream *stream) +{ + EMVFSStream *emvfs = EM_VFS_STREAM (stream); + GnomeVFSResult res; + + if (emvfs->handle == NULL) { + errno = EINVAL; + return -1; + } + + res = gnome_vfs_close(emvfs->handle); + emvfs->handle = NULL; + if (res == GNOME_VFS_OK) + return 0; + + emvfs_set_errno(res); + + return -1; +} + +static off_t +emvfs_seek(CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy policy) +{ + EMVFSStream *emvfs = EM_VFS_STREAM (stream); + GnomeVFSSeekPosition vpolicy; + GnomeVFSFileSize pos; + GnomeVFSResult res; + + if (emvfs->handle == NULL) { + errno = EINVAL; + return -1; + } + + switch (policy) { + case CAMEL_STREAM_SET: + default: + vpolicy = GNOME_VFS_SEEK_START; + break; + case CAMEL_STREAM_CUR: + vpolicy = GNOME_VFS_SEEK_CURRENT; + break; + case CAMEL_STREAM_END: + vpolicy = GNOME_VFS_SEEK_END; + break; + } + + if ( (res = gnome_vfs_seek(emvfs->handle, vpolicy, offset)) == GNOME_VFS_OK + && (res = gnome_vfs_tell(emvfs->handle, &pos)) == GNOME_VFS_OK) + return pos; + + emvfs_set_errno(res); + + return -1; +} + +static off_t +emvfs_tell(CamelSeekableStream *stream) +{ + EMVFSStream *emvfs = EM_VFS_STREAM (stream); + GnomeVFSFileSize pos; + GnomeVFSResult res; + + if (emvfs->handle == NULL) { + errno = EINVAL; + return -1; + } + + if ((res = gnome_vfs_tell(emvfs->handle, &pos)) == GNOME_VFS_OK) + return pos; + + emvfs_set_errno(res); + + return -1; +} + +static void +em_vfs_stream_class_init (EMVFSStreamClass *klass) +{ + ((CamelStreamClass *)klass)->read = emvfs_read; + ((CamelStreamClass *)klass)->write = emvfs_write; + ((CamelStreamClass *)klass)->close = emvfs_close; + + ((CamelSeekableStreamClass *)klass)->seek = emvfs_seek; + ((CamelSeekableStreamClass *)klass)->tell = emvfs_tell; + /* set_bounds? */ +} + +CamelType +em_vfs_stream_get_type (void) +{ + static CamelType type = CAMEL_INVALID_TYPE; + + if (type == CAMEL_INVALID_TYPE) { + parent_class = (CamelStreamClass *)camel_seekable_stream_get_type(); + type = camel_type_register ((CamelType)parent_class, + "EMVFSStream", + sizeof (EMVFSStream), + sizeof (EMVFSStreamClass), + (CamelObjectClassInitFunc) em_vfs_stream_class_init, + NULL, + (CamelObjectInitFunc) em_vfs_stream_init, + (CamelObjectFinalizeFunc) em_vfs_stream_finalize); + } + + return type; +} + +/** + * emvfs_stream_new: + * @handle: + * + * Create a new camel stream from a GnomeVFS handle. The camel stream + * will own the handle from now on. + * + * Return value: A CamelStream that will talk to @handle. This function cannot fail. + **/ +EMVFSStream * +emvfs_stream_new(GnomeVFSHandle *handle) +{ + EMVFSStream *emvfs; + + emvfs = (EMVFSStream *)camel_object_new(em_vfs_stream_get_type()); + emvfs->handle = handle; + + return emvfs; +} |