A search API for Modest
[modest] / src / modest-mime-part-search-stream.c
1 #define _GNU_SOURCE
2
3 #include <glib.h>
4 #include <string.h>
5
6 #include "modest-mime-part-search-stream.h"
7
8 static GObjectClass *parent_class = NULL;
9
10 static gssize
11 modest_mime_part_search_stream_read (TnyStream *self, char *buffer, gsize n)
12 {
13         ModestMimePartSearchStream *me = (ModestMimePartSearchStream *) self;
14
15         if (strcasestr (buffer, me->search_for) != NULL) {
16                 me->found = TRUE;
17                 return -1;
18         }
19
20         return (gssize) n;
21 }
22
23 static gssize
24 modest_mime_part_search_stream_write (TnyStream *self, const char *buffer, gsize n)
25 {
26         ModestMimePartSearchStream *me = (ModestMimePartSearchStream *) self;
27
28         if (strcasestr (buffer, me->search_for) != NULL) {
29                 me->found = TRUE;
30                 return -1;
31         }
32
33         return (gssize) n;
34 }
35
36 static gint
37 modest_mime_part_search_stream_flush (TnyStream *self)
38 {
39         return 0;
40 }
41
42 static gint
43 modest_mime_part_search_stream_close (TnyStream *self)
44 {
45         return 0;
46 }
47
48 static gboolean
49 modest_mime_part_search_stream_is_eos (TnyStream *self)
50 {
51         return TRUE;
52 }
53
54 static gint
55 modest_mime_part_search_stream_reset (TnyStream *self)
56 {
57         return 0;
58 }
59
60 static gssize
61 modest_mime_part_search_stream_write_to_stream (TnyStream *self, TnyStream *output)
62 {
63         char tmp_buf[4096];
64         ssize_t total = 0;
65         ssize_t nb_read;
66         ssize_t nb_written;
67
68         g_assert (TNY_IS_STREAM (output));
69
70         while (G_LIKELY (!tny_stream_is_eos (self))) 
71         {
72                 nb_read = tny_stream_read (self, tmp_buf, sizeof (tmp_buf));
73                 if (G_UNLIKELY (nb_read < 0))
74                         return -1;
75                 else if (G_LIKELY (nb_read > 0)) {
76                         nb_written = 0;
77         
78                         while (G_LIKELY (nb_written < nb_read))
79                         {
80                                 ssize_t len = tny_stream_write (output, tmp_buf + nb_written,
81                                                                   nb_read - nb_written);
82                                 if (G_UNLIKELY (len < 0))
83                                         return -1;
84                                 nb_written += len;
85                         }
86                         total += nb_written;
87                 }
88         }
89         return total;
90 }
91
92
93 TnyStream* 
94 modest_mime_part_search_stream_new (const char *search_for)
95 {
96         ModestMimePartSearchStream *me = g_object_new (MODEST_TYPE_MIME_PART_SEARCH_STREAM, NULL);
97
98         me->search_for = g_strdup (search_for);
99
100         return TNY_STREAM (me);
101 }
102
103 static void
104 modest_mime_part_search_stream_finalize (GObject *object)
105 {
106         ModestMimePartSearchStream *me = g_object_new (MODEST_TYPE_MIME_PART_SEARCH_STREAM, NULL);
107
108         g_free (me->search_for);
109
110         parent_class->finalize (object);
111 }
112
113 static void
114 modest_mime_part_search_stream_instance_init (GTypeInstance *instance, gpointer g_class)
115 {
116         ModestMimePartSearchStream *me = (ModestMimePartSearchStream *) instance;
117
118         me->found = FALSE;
119 }
120
121 static void
122 tny_stream_init (TnyStreamIface *klass)
123 {
124         klass->read_func = modest_mime_part_search_stream_read;
125         klass->write_func = modest_mime_part_search_stream_write;
126         klass->flush_func = modest_mime_part_search_stream_flush;
127         klass->close_func = modest_mime_part_search_stream_close;
128         klass->is_eos_func = modest_mime_part_search_stream_is_eos;
129         klass->reset_func = modest_mime_part_search_stream_reset;
130         klass->write_to_stream_func = modest_mime_part_search_stream_write_to_stream;
131 }
132
133 static void
134 modest_mime_part_search_stream_class_init (ModestMimePartSearchStreamClass *klass)
135 {
136         GObjectClass *object_class;
137
138         parent_class = g_type_class_peek_parent (klass);
139         object_class = (GObjectClass*) klass;
140         object_class->finalize = modest_mime_part_search_stream_finalize;
141 }
142
143 GType
144 modest_mime_part_search_stream_get_type (void)
145 {
146         static GType type = 0;
147         if (G_UNLIKELY(type == 0))
148         {
149                 static const GTypeInfo info = 
150                 {
151                         sizeof (ModestMimePartSearchStreamClass),
152                         NULL,   /* base_init */
153                         NULL,   /* base_finalize */
154                         (GClassInitFunc) modest_mime_part_search_stream_class_init,   /* class_init */
155                         NULL,   /* class_finalize */
156                         NULL,   /* class_data */
157                         sizeof (ModestMimePartSearchStream),
158                         0,      /* n_preallocs */
159                         modest_mime_part_search_stream_instance_init,    /* instance_init */
160                         NULL
161                 };
162
163
164                 static const GInterfaceInfo tny_stream_info = 
165                 {
166                         (GInterfaceInitFunc) tny_stream_init, /* interface_init */
167                         NULL,         /* interface_finalize */
168                         NULL          /* interface_data */
169                 };
170
171                 type = g_type_register_static (G_TYPE_OBJECT,
172                         "ModestMimePartSearchStream",
173                         &info, 0);
174
175                 g_type_add_interface_static (type, TNY_TYPE_STREAM,
176                         &tny_stream_info);
177
178         }
179         return type;
180 }