Initialize the gmime for upstream
[platform/upstream/gmime.git] / gmime / gmime-stream-null.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*  GMime
3  *  Copyright (C) 2000-2012 Jeffrey Stedfast
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public License
7  *  as published by the Free Software Foundation; either version 2.1
8  *  of the License, or (at your option) any later version.
9  *
10  *  This library 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 GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free
17  *  Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
18  *  02110-1301, USA.
19  */
20
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27
28 #include "gmime-stream-null.h"
29
30
31 /**
32  * SECTION: gmime-stream-null
33  * @title: GMimeStreamNull
34  * @short_description: A null stream
35  * @see_also: #GMimeStream
36  *
37  * A #GMimeStream which has no real backing storage at all. This
38  * stream is useful for dry-runs and can also be useful for
39  * determining statistics on source data which can be written to
40  * streams but cannot be read as a stream itself (e.g. a #GMimeObject
41  * via g_mime_object_write_to_stream()).
42  **/
43
44
45 static void g_mime_stream_null_class_init (GMimeStreamNullClass *klass);
46 static void g_mime_stream_null_init (GMimeStreamNull *stream, GMimeStreamNullClass *klass);
47 static void g_mime_stream_null_finalize (GObject *object);
48
49 static ssize_t stream_read (GMimeStream *stream, char *buf, size_t len);
50 static ssize_t stream_write (GMimeStream *stream, const char *buf, size_t len);
51 static int stream_flush (GMimeStream *stream);
52 static int stream_close (GMimeStream *stream);
53 static gboolean stream_eos (GMimeStream *stream);
54 static int stream_reset (GMimeStream *stream);
55 static gint64 stream_seek (GMimeStream *stream, gint64 offset, GMimeSeekWhence whence);
56 static gint64 stream_tell (GMimeStream *stream);
57 static gint64 stream_length (GMimeStream *stream);
58 static GMimeStream *stream_substream (GMimeStream *stream, gint64 start, gint64 end);
59
60
61 static GMimeStreamClass *parent_class = NULL;
62
63
64 GType
65 g_mime_stream_null_get_type (void)
66 {
67         static GType type = 0;
68         
69         if (!type) {
70                 static const GTypeInfo info = {
71                         sizeof (GMimeStreamNullClass),
72                         NULL, /* base_class_init */
73                         NULL, /* base_class_finalize */
74                         (GClassInitFunc) g_mime_stream_null_class_init,
75                         NULL, /* class_finalize */
76                         NULL, /* class_data */
77                         sizeof (GMimeStreamNull),
78                         0,    /* n_preallocs */
79                         (GInstanceInitFunc) g_mime_stream_null_init,
80                 };
81                 
82                 type = g_type_register_static (GMIME_TYPE_STREAM, "GMimeStreamNull", &info, 0);
83         }
84         
85         return type;
86 }
87
88
89 static void
90 g_mime_stream_null_class_init (GMimeStreamNullClass *klass)
91 {
92         GMimeStreamClass *stream_class = GMIME_STREAM_CLASS (klass);
93         GObjectClass *object_class = G_OBJECT_CLASS (klass);
94         
95         parent_class = g_type_class_ref (GMIME_TYPE_STREAM);
96         
97         object_class->finalize = g_mime_stream_null_finalize;
98         
99         stream_class->read = stream_read;
100         stream_class->write = stream_write;
101         stream_class->flush = stream_flush;
102         stream_class->close = stream_close;
103         stream_class->eos = stream_eos;
104         stream_class->reset = stream_reset;
105         stream_class->seek = stream_seek;
106         stream_class->tell = stream_tell;
107         stream_class->length = stream_length;
108         stream_class->substream = stream_substream;
109 }
110
111 static void
112 g_mime_stream_null_init (GMimeStreamNull *stream, GMimeStreamNullClass *klass)
113 {
114         stream->written = 0;
115         stream->newlines = 0;
116 }
117
118 static void
119 g_mime_stream_null_finalize (GObject *object)
120 {
121         G_OBJECT_CLASS (parent_class)->finalize (object);
122 }
123
124
125 static ssize_t
126 stream_read (GMimeStream *stream, char *buf, size_t len)
127 {
128         memset (buf, 0, len);
129         
130         stream->position += len;
131         
132         return len;
133 }
134
135 static ssize_t
136 stream_write (GMimeStream *stream, const char *buf, size_t len)
137 {
138         GMimeStreamNull *null = (GMimeStreamNull *) stream;
139         register const char *inptr = buf;
140         const char *inend = buf + len;
141         
142         while (inptr < inend) {
143                 if (*inptr == '\n')
144                         null->newlines++;
145                 inptr++;
146         }
147         
148         null->written += len;
149         stream->position += len;
150         
151         return len;
152 }
153
154 static int
155 stream_flush (GMimeStream *stream)
156 {
157         return 0;
158 }
159
160 static int
161 stream_close (GMimeStream *stream)
162 {
163         return 0;
164 }
165
166 static gboolean
167 stream_eos (GMimeStream *stream)
168 {
169         return TRUE;
170 }
171
172 static int
173 stream_reset (GMimeStream *stream)
174 {
175         GMimeStreamNull *null = (GMimeStreamNull *) stream;
176         
177         null->written = 0;
178         null->newlines = 0;
179         
180         return 0;
181 }
182
183 static gint64
184 stream_seek (GMimeStream *stream, gint64 offset, GMimeSeekWhence whence)
185 {
186         GMimeStreamNull *null = (GMimeStreamNull *) stream;
187         gint64 bound_end;
188         
189         bound_end = stream->bound_end != -1 ? stream->bound_end : null->written;
190         
191         switch (whence) {
192         case GMIME_STREAM_SEEK_SET:
193                 stream->position = MIN (offset + stream->bound_start, bound_end);
194                 break;
195         case GMIME_STREAM_SEEK_END:
196                 stream->position = MAX (offset + bound_end, 0);
197                 break;
198         case GMIME_STREAM_SEEK_CUR:
199                 stream->position += offset;
200                 if (stream->position < stream->bound_start)
201                         stream->position = stream->bound_start;
202                 else if (stream->position > bound_end)
203                         stream->position = bound_end;
204         }
205         
206         return stream->position;
207 }
208
209 static gint64
210 stream_tell (GMimeStream *stream)
211 {
212         return stream->position;
213 }
214
215 static gint64
216 stream_length (GMimeStream *stream)
217 {
218         GMimeStreamNull *null = (GMimeStreamNull *) stream;
219         gint64 bound_end;
220         
221         bound_end = stream->bound_end != -1 ? stream->bound_end : null->written;
222         
223         return bound_end - stream->bound_start;
224 }
225
226 static GMimeStream *
227 stream_substream (GMimeStream *stream, gint64 start, gint64 end)
228 {
229         GMimeStream *null;
230         
231         null = g_object_newv (GMIME_TYPE_STREAM_NULL, 0, NULL);
232         g_mime_stream_construct (null, start, end);
233         
234         return null;
235 }
236
237
238 /**
239  * g_mime_stream_null_new:
240  *
241  * Creates a new #GMimeStreamNull object.
242  *
243  * Returns: a new null stream (similar to /dev/null on Unix).
244  **/
245 GMimeStream *
246 g_mime_stream_null_new (void)
247 {
248         GMimeStream *null;
249         
250         null = g_object_newv (GMIME_TYPE_STREAM_NULL, 0, NULL);
251         g_mime_stream_construct (null, 0, -1);
252         
253         return null;
254 }