Removed the extra boolean parameter added to know when to unref the
[platform/core/uifw/at-spi2-atk.git] / atk-adaptor / adaptors / streamablecontent-adaptor.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
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 {
49   BonoboObject parent;
50   GIOChannel *gio;
51 };
52
53 struct _SpiContentStreamClass
54 {
55   BonoboObjectClass parent_class;
56   POA_Accessibility_ContentStream__epv epv;
57 };
58
59 GType spi_content_stream_get_type (void);
60
61 static SpiContentStream *
62 spi_content_stream_new (GIOChannel * gio)
63 {
64   SpiContentStream *new_stream = g_object_new (SPI_CONTENT_STREAM_TYPE, NULL);
65   new_stream->gio = gio;
66   return new_stream;
67 }
68
69 static void
70 spi_content_stream_dispose (GObject * o)
71 {
72   if (SPI_IS_CONTENT_STREAM (o))
73     {
74       SpiContentStream *stream = SPI_CONTENT_STREAM (o);
75       if (stream->gio)
76         g_io_channel_unref (stream->gio);
77     }
78 }
79
80 static CORBA_long
81 impl_content_stream_seek (PortableServer_Servant servant,
82                           const CORBA_long offset,
83                           const Accessibility_ContentStream_SeekType whence,
84                           CORBA_Environment * ev)
85 {
86   SpiContentStream *stream =
87     SPI_CONTENT_STREAM (bonobo_object_from_servant (servant));
88   if (stream && stream->gio)
89     {
90       GError *err;
91       GSeekType seektype = G_SEEK_SET;
92       switch (whence)
93         {
94         case Accessibility_ContentStream_SEEK_CURRENT:
95           seektype = G_SEEK_CUR;
96           break;
97         case Accessibility_ContentStream_SEEK_END:
98           seektype = G_SEEK_END;
99           break;
100         }
101       if (g_io_channel_seek_position (stream->gio, (gint64) offset,
102                                       seektype, &err) == G_IO_STATUS_NORMAL)
103         return offset;
104       else
105         return -1;
106     }
107   else
108     return -1;
109 }
110
111 static CORBA_long
112 impl_content_stream_read (PortableServer_Servant servant,
113                           const CORBA_long count,
114                           Accessibility_ContentStream_iobuf ** buffer,
115                           CORBA_Environment * ev)
116 {
117   SpiContentStream *stream =
118     SPI_CONTENT_STREAM (bonobo_object_from_servant (servant));
119   CORBA_long realcount = 0;
120
121   if (stream && stream->gio)
122     {
123       gchar *gbuf = NULL;
124       GIOStatus status;
125       GError *err = NULL;
126
127       /* read the giochannel and determine the actual bytes read... */
128       if (count != -1)
129         {
130           gbuf = g_malloc (count + 1);
131           status =
132             g_io_channel_read_chars (stream->gio, gbuf, count, &realcount,
133                                      &err);
134         }
135       else
136         status =
137           g_io_channel_read_to_end (stream->gio, &gbuf, &realcount, &err);
138
139       if (status == G_IO_STATUS_NORMAL || status == G_IO_STATUS_EOF)
140         {
141           *buffer = Bonobo_Stream_iobuf__alloc ();
142           CORBA_sequence_set_release (*buffer, TRUE);
143
144           (*buffer)->_buffer =
145             CORBA_sequence_CORBA_octet_allocbuf (realcount);
146           (*buffer)->_length = realcount;
147
148           g_memmove ((*buffer)->_buffer, gbuf, realcount);
149         }
150
151       g_free (gbuf);
152     }
153
154   return realcount;
155 }
156
157 static void
158 impl_content_stream_close (PortableServer_Servant servant,
159                            CORBA_Environment * ev)
160 {
161   GIOStatus status;
162   GError *err;
163   SpiContentStream *stream =
164     SPI_CONTENT_STREAM (bonobo_object_from_servant (servant));
165   if (stream && stream->gio)
166     {
167       status = g_io_channel_shutdown (stream->gio, TRUE, &err);
168       g_io_channel_unref (stream->gio);
169     }
170   if (err)
171     g_free (err);
172 }
173
174 static void
175 spi_content_stream_class_init (SpiContentStreamClass * klass)
176 {
177   POA_Accessibility_ContentStream__epv *epv = &klass->epv;
178   GObjectClass *object_class = (GObjectClass *) klass;
179
180   epv->seek = impl_content_stream_seek;
181   epv->read = impl_content_stream_read;
182   epv->close = impl_content_stream_close;
183
184   object_class->dispose = spi_content_stream_dispose;
185 }
186
187
188 static void
189 spi_content_stream_init (SpiContentStream * stream)
190 {
191 }
192
193
194 BONOBO_TYPE_FUNC_FULL (SpiContentStream,
195                        Accessibility_ContentStream,
196                        BONOBO_TYPE_OBJECT, spi_content_stream)
197      static AtkStreamableContent
198        *get_streamable_from_servant (PortableServer_Servant servant)
199 {
200   SpiBase *object = SPI_BASE (bonobo_object_from_servant (servant));
201   g_return_val_if_fail (object != NULL, NULL);
202   g_return_val_if_fail (ATK_IS_STREAMABLE_CONTENT (object->gobj), NULL);
203   return ATK_STREAMABLE_CONTENT (object->gobj);
204 }
205
206 /*
207  * CORBA Accessibility::StreamableContent::getContentTypes method implementation
208  */
209 static Accessibility_StringSeq *
210 impl_accessibility_streamable_get_content_types (PortableServer_Servant
211                                                  servant,
212                                                  CORBA_Environment * ev)
213 {
214   Accessibility_StringSeq *typelist = Accessibility_StringSeq__alloc ();
215   AtkStreamableContent *streamable = get_streamable_from_servant (servant);
216   int n_types, i;
217
218   typelist->_length = typelist->_maximum = 0;
219
220   g_return_val_if_fail (streamable != NULL, typelist);
221
222   n_types = atk_streamable_content_get_n_mime_types (streamable);
223
224   if (n_types)
225     {
226       typelist->_length = typelist->_maximum = n_types;
227       typelist->_buffer = Accessibility_StringSeq_allocbuf (n_types);
228       for (i = 0; i < n_types; ++i)
229         {
230           const gchar *mimetype =
231             atk_streamable_content_get_mime_type (streamable, i);
232           typelist->_buffer[i] = CORBA_string_dup (mimetype ? mimetype : "");
233         }
234     }
235   return typelist;
236 }
237
238 /*
239  * CORBA Accessibility::StreamableContent::getContent method implementation
240  */
241 static Bonobo_Stream
242 impl_accessibility_streamable_get_content (PortableServer_Servant servant,
243                                            const CORBA_char * content_type,
244                                            CORBA_Environment * ev)
245 {
246   Bonobo_Stream stream;
247   AtkStreamableContent *streamable = get_streamable_from_servant (servant);
248   GIOChannel *gio;
249
250   g_return_val_if_fail (streamable != NULL, NULL);
251
252   gio = atk_streamable_content_get_stream (streamable, content_type);
253
254   stream = CORBA_OBJECT_NIL;    /* deprecated, 
255                                  * and it was never implemented,
256                                  * so don't bother fixing this 
257                                  */
258   return stream;
259 }
260
261 /*
262  * CORBA Accessibility::StreamableContent::getStream method implementation
263  */
264 static Accessibility_ContentStream
265 impl_accessibility_streamable_get_stream (PortableServer_Servant servant,
266                                           const CORBA_char * content_type,
267                                           CORBA_Environment * ev)
268 {
269   SpiContentStream *stream;
270   AtkStreamableContent *streamable = get_streamable_from_servant (servant);
271   GIOChannel *gio;
272
273   g_return_val_if_fail (streamable != NULL, NULL);
274
275   gio = atk_streamable_content_get_stream (streamable, content_type);
276
277   stream = spi_content_stream_new (gio);
278
279   return bonobo_object_dup_ref (BONOBO_OBJREF (stream), ev);
280 }
281
282 /*
283  * CORBA Accessibility::StreamableContent::GetURI method implementation
284  */
285 static CORBA_string
286 impl_accessibility_streamable_get_uri (PortableServer_Servant servant,
287                                        const CORBA_char * content_type,
288                                        CORBA_Environment * ev)
289 {
290   gchar *uri;
291   AtkStreamableContent *streamable = get_streamable_from_servant (servant);
292
293   g_return_val_if_fail (streamable != NULL, NULL);
294
295   uri = atk_streamable_content_get_uri (streamable, content_type);
296
297   return (uri != NULL ? CORBA_string_dup (uri) : CORBA_string_dup (""));
298 }
299
300 static void
301 spi_streamable_class_init (SpiStreamableClass * klass)
302 {
303   POA_Accessibility_StreamableContent__epv *epv = &klass->epv;
304   spi_streamable_parent_class = g_type_class_peek_parent (klass);
305
306   epv->getContentTypes = impl_accessibility_streamable_get_content_types;
307   epv->getContent = impl_accessibility_streamable_get_content;
308   epv->getStream = impl_accessibility_streamable_get_stream;
309   epv->GetURI = impl_accessibility_streamable_get_uri;
310 }
311
312 static void
313 spi_streamable_init (SpiStreamable * streamable)
314 {
315 }
316
317
318 SpiStreamable *
319 spi_streamable_interface_new (AtkObject * o)
320 {
321   SpiStreamable *retval = g_object_new (SPI_STREAMABLE_TYPE, NULL);
322
323   spi_base_construct (SPI_BASE (retval), G_OBJECT (o));
324
325   return retval;
326 }
327
328 BONOBO_TYPE_FUNC_FULL (SpiStreamable,
329                        Accessibility_StreamableContent,
330                        PARENT_TYPE, spi_streamable)