Extending test-client-custom-summary to try e_book_client_get_contacts_uids()
[platform/upstream/evolution-data-server.git] / camel / camel-stream-vfs.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /* camel-stream-vfs.c : file system based stream */
3
4 /*
5  * Authors: Srinivasa Ragavan <sragavan@novell.com>
6  *
7  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of version 2 of the GNU Lesser General Public
11  * License as published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21  * USA
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <errno.h>
29 #include <string.h>
30
31 #include <gio/gio.h>
32
33 #include "camel-file-utils.h"
34 #include "camel-operation.h"
35 #include "camel-stream-vfs.h"
36
37 G_DEFINE_TYPE (CamelStreamVFS, camel_stream_vfs, CAMEL_TYPE_STREAM)
38
39 static void
40 stream_vfs_dispose (GObject *object)
41 {
42         CamelStreamVFS *stream = CAMEL_STREAM_VFS (object);
43
44         if (stream->stream != NULL) {
45                 g_object_unref (stream->stream);
46                 stream->stream = NULL;
47         }
48
49         /* Chain up to parent's dispose() method. */
50         G_OBJECT_CLASS (camel_stream_vfs_parent_class)->dispose (object);
51 }
52
53 static gssize
54 stream_vfs_read (CamelStream *stream,
55                  gchar *buffer,
56                  gsize n,
57                  GCancellable *cancellable,
58                  GError **error)
59 {
60         CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream);
61         gssize nread;
62         GError *local_error = NULL;
63
64         nread = g_input_stream_read (
65                 G_INPUT_STREAM (stream_vfs->stream),
66                 buffer, n, cancellable, &local_error);
67
68         if (nread == 0 || local_error != NULL)
69                 stream->eos = TRUE;
70
71         if (local_error != NULL)
72                 g_propagate_error (error, local_error);
73
74         return nread;
75 }
76
77 static gssize
78 stream_vfs_write (CamelStream *stream,
79                   const gchar *buffer,
80                   gsize n,
81                   GCancellable *cancellable,
82                   GError **error)
83 {
84         CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream);
85         gboolean success;
86         gsize bytes_written;
87
88         success = g_output_stream_write_all (
89                 G_OUTPUT_STREAM (stream_vfs->stream),
90                 buffer, n, &bytes_written, cancellable, error);
91
92         return success ? bytes_written : -1;
93 }
94
95 static gint
96 stream_vfs_flush (CamelStream *stream,
97                   GCancellable *cancellable,
98                   GError **error)
99 {
100         CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream);
101         gboolean success;
102
103         success = g_output_stream_flush (
104                 G_OUTPUT_STREAM (stream_vfs->stream), cancellable, error);
105
106         return success ? 0 : -1;
107 }
108
109 static gint
110 stream_vfs_close (CamelStream *stream,
111                   GCancellable *cancellable,
112                   GError **error)
113 {
114         CamelStreamVFS *stream_vfs = CAMEL_STREAM_VFS (stream);
115         gboolean success;
116
117         if (G_IS_OUTPUT_STREAM (stream_vfs->stream))
118                 success = g_output_stream_close (
119                         G_OUTPUT_STREAM (stream_vfs->stream),
120                         cancellable, error);
121         else
122                 success = g_input_stream_close (
123                         G_INPUT_STREAM (stream_vfs->stream),
124                         cancellable, error);
125
126         if (success) {
127                 g_object_unref (stream_vfs->stream);
128                 stream_vfs->stream = NULL;
129         }
130
131         return success ? 0 : -1;
132 }
133
134 static void
135 camel_stream_vfs_class_init (CamelStreamVFSClass *class)
136 {
137         GObjectClass *object_class;
138         CamelStreamClass *stream_class;
139
140         object_class = G_OBJECT_CLASS (class);
141         object_class->dispose = stream_vfs_dispose;
142
143         stream_class = CAMEL_STREAM_CLASS (class);
144         stream_class->read = stream_vfs_read;
145         stream_class->write = stream_vfs_write;
146         stream_class->flush = stream_vfs_flush;
147         stream_class->close = stream_vfs_close;
148 }
149
150 static void
151 camel_stream_vfs_init (CamelStreamVFS *stream)
152 {
153         stream->stream = NULL;
154 }
155
156 /**
157  * camel_stream_vfs_new_with_stream:
158  * @stream: a GInputStream or GOutputStream instance
159  *
160  * Creates a new fs stream using the given gio stream @stream as the
161  * backing store. When the stream is destroyed, the file descriptor
162  * will be closed. This will not increase reference counter on the stream.
163  *
164  * Returns: a new #CamelStreamVFS
165  *
166  * Since: 2.24
167  **/
168 CamelStream *
169 camel_stream_vfs_new_with_stream (GObject *stream)
170 {
171         CamelStreamVFS *stream_vfs;
172
173         errno = EINVAL;
174
175         if (!stream)
176                 return NULL;
177
178         g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream) || G_IS_INPUT_STREAM (stream), NULL);
179
180         errno = 0;
181         stream_vfs = g_object_new (CAMEL_TYPE_STREAM_VFS, NULL);
182         stream_vfs->stream = stream;
183
184         return CAMEL_STREAM (stream_vfs);
185 }
186
187 /**
188  * camel_stream_vfs_new_with_uri:
189  * @uri: a file uri
190  * @mode: opening mode for the uri file
191  *
192  * Creates a new #CamelStreamVFS corresponding to the named file and mode.
193  *
194  * Returns: the new stream, or %NULL on error.
195  **/
196 CamelStream *
197 camel_stream_vfs_new_with_uri (const gchar *uri,
198                                CamelStreamVFSOpenMethod mode)
199 {
200         GFile *file;
201         GObject *stream;
202         GError *error = NULL;
203
204         file = g_file_new_for_uri (uri);
205
206         switch (mode) {
207                 case CAMEL_STREAM_VFS_CREATE:
208                         stream = G_OBJECT (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error));
209                         break;
210                 case CAMEL_STREAM_VFS_APPEND:
211                         stream = G_OBJECT (g_file_append_to (file, G_FILE_CREATE_NONE, NULL, &error));
212                         break;
213                 case CAMEL_STREAM_VFS_READ:
214                         stream = G_OBJECT (g_file_read (file, NULL, &error));
215                         break;
216                 default:
217                         errno = EINVAL;
218                         g_return_val_if_reached (NULL);
219         }
220
221         g_object_unref (file);
222
223         if (error) {
224                 errno = error->code;
225                 g_warning ("%s", error->message);
226                 g_error_free (error);
227                 return NULL;
228         }
229
230         return camel_stream_vfs_new_with_stream (stream);
231 }
232
233 /**
234  * camel_stream_vfs_is_writable:
235  * @stream_vfs: a #CamelStreamVFS instance
236  *
237  * Returns: whether is the underlying stream writable or not.
238  *
239  * Since: 2.24
240  **/
241 gboolean
242 camel_stream_vfs_is_writable (CamelStreamVFS *stream_vfs)
243 {
244         g_return_val_if_fail (stream_vfs != NULL, FALSE);
245         g_return_val_if_fail (stream_vfs->stream != NULL, FALSE);
246
247         return G_IS_OUTPUT_STREAM (stream_vfs->stream);
248 }