2008-05-16 Mark Doffman <mark.doffman@codethink.co.uk>
[platform/core/uifw/at-spi2-atk.git] / atk-adaptor / streamablecontent.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) *
4  * Copyright 2001, 2002 Sun Microsystems Inc.,
5  * Copyright 2001, 2002 Ximian, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /* streamablecontent.c : implements the StreamableContent interface */
24
25 #include <config.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <libspi/accessible.h>
29 #include <libspi/component.h>
30 #include <libspi/streamablecontent.h>
31
32 /* Our parent Gtk object type */
33 #define PARENT_TYPE SPI_TYPE_BASE
34
35 /* A pointer to our parent object class */
36 static GObjectClass *spi_streamable_parent_class;
37
38 #define SPI_CONTENT_STREAM_TYPE            (spi_content_stream_get_type ())
39 #define SPI_CONTENT_STREAM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_CONTENT_STREAM_TYPE, SpiContentStream))
40 #define SPI_CONTENT_STREAM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), SPI_CONTENT_STREAM_TYPE, SpiContentStreamClass))
41 #define SPI_IS_CONTENT_STREAM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPI_CONTENT_STREAM_TYPE))
42 #define SPI_IS_CONTENT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_CONTENT_STREAM_TYPE))
43
44 typedef struct _SpiContentStream SpiContentStream;
45 typedef struct _SpiContentStreamClass SpiContentStreamClass;
46
47 struct _SpiContentStream {
48   BonoboObject parent;
49   GIOChannel *gio;
50 };
51
52 struct _SpiContentStreamClass {
53   BonoboObjectClass parent_class;
54   POA_Accessibility_ContentStream__epv epv;
55 };
56
57 GType        spi_content_stream_get_type (void);
58
59 static SpiContentStream*
60 spi_content_stream_new (GIOChannel *gio)
61 {
62   SpiContentStream *new_stream = g_object_new (SPI_CONTENT_STREAM_TYPE, NULL);
63   new_stream->gio = gio;
64   return new_stream;
65 }
66
67 static void
68 spi_content_stream_dispose (GObject *o)
69 {
70     if (SPI_IS_CONTENT_STREAM (o))
71     {
72         SpiContentStream *stream = SPI_CONTENT_STREAM (o);
73         if (stream->gio) g_io_channel_unref (stream->gio);
74     }
75 }
76
77 static CORBA_long
78 impl_content_stream_seek (PortableServer_Servant servant,
79                           const CORBA_long offset, 
80                           const Accessibility_ContentStream_SeekType whence,
81                           CORBA_Environment *ev)
82 {
83   SpiContentStream *stream = SPI_CONTENT_STREAM (bonobo_object_from_servant(servant));
84   if (stream && stream->gio)
85   {
86       GError *err;
87       GSeekType seektype = G_SEEK_SET;
88       switch (whence) {
89           case Accessibility_ContentStream_SEEK_CURRENT:
90               seektype = G_SEEK_CUR;
91               break;
92           case Accessibility_ContentStream_SEEK_END:
93               seektype = G_SEEK_END;
94               break;
95       }
96       if (g_io_channel_seek_position (stream->gio, (gint64) offset, 
97                                      seektype, &err) == G_IO_STATUS_NORMAL)
98           return offset;
99       else
100           return -1;
101   }
102   else
103       return -1;
104 }
105
106 static CORBA_long
107 impl_content_stream_read (PortableServer_Servant servant,
108                           const CORBA_long count, 
109                           Accessibility_ContentStream_iobuf** buffer,
110                           CORBA_Environment *ev)
111 {
112   SpiContentStream *stream = SPI_CONTENT_STREAM (bonobo_object_from_servant(servant));
113   CORBA_long realcount = 0;
114
115   if (stream && stream->gio)
116   {
117       gchar *gbuf = NULL;
118       GIOStatus status;
119       GError *err = NULL;
120  
121       /* read the giochannel and determine the actual bytes read...*/
122       if (count != -1) {
123           gbuf = g_malloc (count+1);
124           status = g_io_channel_read_chars (stream->gio, gbuf, count, &realcount, &err);
125       }
126       else
127           status = g_io_channel_read_to_end (stream->gio, &gbuf, &realcount, &err);
128
129       if (status == G_IO_STATUS_NORMAL || status == G_IO_STATUS_EOF)
130       {
131           *buffer = Bonobo_Stream_iobuf__alloc ();
132           CORBA_sequence_set_release (*buffer, TRUE);
133
134           (*buffer)->_buffer = CORBA_sequence_CORBA_octet_allocbuf (realcount);
135           (*buffer)->_length = realcount;
136       
137           g_memmove ((*buffer)->_buffer, gbuf, realcount);  
138       }
139
140       g_free (gbuf);
141   }
142
143   return realcount;
144 }
145
146 static void
147 impl_content_stream_close (PortableServer_Servant servant, 
148                            CORBA_Environment *ev)
149 {
150     GIOStatus status;
151     GError *err;
152     SpiContentStream *stream = SPI_CONTENT_STREAM (bonobo_object_from_servant(servant));
153     if (stream && stream->gio) {
154         status = g_io_channel_shutdown (stream->gio, TRUE, &err);
155         g_io_channel_unref (stream->gio);
156     }
157     if (err) g_free (err);
158 }
159
160 static void
161 spi_content_stream_class_init (SpiContentStreamClass *klass)
162 {
163   POA_Accessibility_ContentStream__epv *epv = &klass->epv;
164   GObjectClass * object_class = (GObjectClass *) klass;
165
166   epv->seek = impl_content_stream_seek;
167   epv->read = impl_content_stream_read;
168   epv->close = impl_content_stream_close;
169
170   object_class->dispose = spi_content_stream_dispose;
171 }
172
173
174 static void
175 spi_content_stream_init (SpiContentStream *stream)
176 {
177 }
178
179
180 BONOBO_TYPE_FUNC_FULL (SpiContentStream,
181                        Accessibility_ContentStream,
182                        BONOBO_TYPE_OBJECT,
183                        spi_content_stream)
184
185 static AtkStreamableContent *
186 get_streamable_from_servant (PortableServer_Servant servant)
187 {
188   SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
189   g_return_val_if_fail (object != NULL, NULL);
190   g_return_val_if_fail (ATK_IS_STREAMABLE_CONTENT(object->gobj), NULL);
191   return ATK_STREAMABLE_CONTENT (object->gobj);
192 }
193
194 /*
195  * CORBA Accessibility::StreamableContent::getContentTypes method implementation
196  */
197 static Accessibility_StringSeq*
198 impl_accessibility_streamable_get_content_types (PortableServer_Servant servant,
199                                                  CORBA_Environment     *ev)
200 {
201   Accessibility_StringSeq *typelist = Accessibility_StringSeq__alloc ();
202   AtkStreamableContent *streamable = get_streamable_from_servant (servant);
203   int n_types, i;
204
205   typelist->_length = typelist->_maximum = 0;
206
207   g_return_val_if_fail (streamable != NULL, typelist);
208
209   n_types = atk_streamable_content_get_n_mime_types (streamable);
210
211   if (n_types)
212   {
213       typelist->_length = typelist->_maximum = n_types;
214       typelist->_buffer = Accessibility_StringSeq_allocbuf (n_types);
215       for (i = 0; i < n_types; ++i) {
216           const gchar *mimetype = atk_streamable_content_get_mime_type (streamable, i);
217           typelist->_buffer[i] = CORBA_string_dup (mimetype ? mimetype : "");
218       }
219   }
220   return typelist;
221 }
222
223 /*
224  * CORBA Accessibility::StreamableContent::getContent method implementation
225  */
226 static Bonobo_Stream
227 impl_accessibility_streamable_get_content (PortableServer_Servant servant,
228                                            const CORBA_char * content_type,
229                                            CORBA_Environment     *ev)
230 {
231   Bonobo_Stream stream;
232   AtkStreamableContent *streamable = get_streamable_from_servant (servant);
233   GIOChannel *gio;
234
235   g_return_val_if_fail (streamable != NULL, NULL);
236
237   gio = atk_streamable_content_get_stream (streamable, content_type);
238
239   stream = CORBA_OBJECT_NIL; /* deprecated, 
240                               * and it was never implemented,
241                               * so don't bother fixing this 
242                               */
243   return stream;
244 }
245
246 /*
247  * CORBA Accessibility::StreamableContent::getStream method implementation
248  */
249 static Accessibility_ContentStream
250 impl_accessibility_streamable_get_stream (PortableServer_Servant servant,
251                                            const CORBA_char * content_type,
252                                            CORBA_Environment     *ev)
253 {
254   SpiContentStream *stream;
255   AtkStreamableContent *streamable = get_streamable_from_servant (servant);
256   GIOChannel *gio;
257
258   g_return_val_if_fail (streamable != NULL, NULL);
259
260   gio = atk_streamable_content_get_stream (streamable, content_type);
261
262   stream = spi_content_stream_new (gio); 
263
264   return bonobo_object_dup_ref (BONOBO_OBJREF (stream), ev);
265 }
266
267 /*
268  * CORBA Accessibility::StreamableContent::getURI method implementation
269  */
270 static CORBA_string
271 impl_accessibility_streamable_get_uri (PortableServer_Servant servant,
272                                            const CORBA_char * content_type,
273                                            CORBA_Environment     *ev)
274 {
275   gchar *uri;
276   AtkStreamableContent *streamable = get_streamable_from_servant (servant);
277
278   g_return_val_if_fail (streamable != NULL, NULL);
279
280   uri = atk_streamable_content_get_uri (streamable, content_type);
281
282   return (uri != NULL ? CORBA_string_dup (uri) : CORBA_string_dup (""));
283 }
284
285 static void
286 spi_streamable_class_init (SpiStreamableClass *klass)
287 {
288         POA_Accessibility_StreamableContent__epv *epv = &klass->epv;
289         spi_streamable_parent_class = g_type_class_peek_parent (klass);
290
291         epv->getContentTypes = impl_accessibility_streamable_get_content_types;
292         epv->getContent = impl_accessibility_streamable_get_content;
293         epv->getStream = impl_accessibility_streamable_get_stream;
294         epv->getURI = impl_accessibility_streamable_get_uri;
295 }
296
297 static void
298 spi_streamable_init (SpiStreamable *streamable)
299 {
300 }
301
302
303 SpiStreamable *
304 spi_streamable_interface_new (AtkObject *o)
305 {
306     SpiStreamable *retval = g_object_new (SPI_STREAMABLE_TYPE, NULL);
307
308     spi_base_construct (SPI_BASE (retval), G_OBJECT(o));
309
310     return retval;
311 }
312
313 BONOBO_TYPE_FUNC_FULL (SpiStreamable,
314                        Accessibility_StreamableContent,
315                        PARENT_TYPE,
316                        spi_streamable)