2003-07-07 Padraig O'Briain <padraig.obriain@sun.com>
[platform/core/uifw/at-spi2-atk.git] / cspi / spi_streamablecontent.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2001, 2002 Sun Microsystems Inc.,
6  * Copyright 2001, 2002 Ximian, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library 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 GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #include <cspi/spi-private.h>
25
26
27 /* TODO: factor/wrap Bonobo_Stream dependency to cspi/bonobo */
28
29 struct StreamCacheItem {
30   Bonobo_Stream stream;
31   gchar *mimetype;
32 };
33
34 static gboolean
35 streams_equal_func (gconstpointer a, gconstpointer b)
36 {
37   const struct StreamCacheItem *c1 = a, *c2 = b;
38   return CORBA_Object_is_equivalent (c1->stream, c2->stream, cspi_ev ());
39 }
40
41 static void
42 stream_release (gpointer a)
43 {
44   bonobo_object_release_unref (a);
45 }
46
47 static void
48 stream_cache_item_free (gpointer a)
49 {
50   struct StreamCacheItem *cache_item = a;
51   if (cache_item) {
52     bonobo_object_release_unref (cache_item->stream);
53     SPI_freeString (cache_item->mimetype);
54     g_free (cache_item);
55   }
56 }
57
58 static GHashTable *streams = NULL;
59
60 GHashTable *
61 get_streams (void) 
62 {
63   if (streams == NULL) {
64     streams = g_hash_table_new_full (g_direct_hash, streams_equal_func, 
65                                      stream_release, stream_cache_item_free);
66   }
67   return streams;
68 }
69
70 /* internal use only, declared in cspi-private.h */
71 void
72 cspi_streams_close_all (void)
73 {
74   if (streams)
75     {
76       g_hash_table_destroy (streams);
77       streams = NULL;
78     }
79 }
80
81 /**
82  * AccessibleStreamableContent_ref:
83  * @obj: a pointer to the #AccessibleStreamableContent implementor on which to
84  *       operate.
85  *
86  * Increment the reference count for an #AccessibleStreamableContent object.
87  *
88  **/
89 void
90 AccessibleStreamableContent_ref (AccessibleStreamableContent *obj)
91 {
92   cspi_object_ref (obj);
93 }
94
95 /**
96  * AccessibleStreamableContent_unref:
97  * @obj: a pointer to the #AccessibleStreamableContent implementor
98  *       on which to operate. 
99  *
100  * Decrement the reference count for an #AccessibleStreamableContent object.
101  *
102  **/
103 void
104 AccessibleStreamableContent_unref (AccessibleStreamableContent *obj)
105 {
106   cspi_object_unref (obj);
107 }
108
109 /**
110  * AccessibleStreamableContent_getContentTypes:
111  * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate.
112  *
113  * Get a list of strings containing the content mimetypes available from an
114  *       #AccessibleStreamableContent implementor.
115  *
116  * Returns: an array of strings, terminated by a NULL string, specifying the
117  *       mimetypes for which the streamed content is available.
118  *
119  **/
120 char **
121 AccessibleStreamableContent_getContentTypes (AccessibleStreamableContent *obj)
122 {
123   Accessibility_StringSeq *mimeseq;
124   char **content_types;
125   int i;
126
127   mimeseq = Accessibility_StreamableContent_getContentTypes (CSPI_OBJREF (obj),
128                                                              cspi_ev ());
129
130   content_types = g_new0 (char *, mimeseq->_length + 1);
131   for (i = 0; i < mimeseq->_length; ++i) {
132     content_types[i] = CORBA_string_dup (mimeseq->_buffer[i]);
133   }
134   content_types [mimeseq->_length] = NULL;
135   CORBA_free (mimeseq);
136
137   return content_types;
138 }
139
140 /**
141  * AccessibleStreamableContent_open:
142  * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate.
143  * @content_type: a string specifying the content type to retrieve (should match one
144  * of the return strings from #AccessibleStreamableContent_getContentTypes ()).
145  *
146  * Open a streaming connection to an AccessibleStreamableContent implementor,
147  *       of a particular content type
148  *
149  * Returns: #TRUE if successful, #FALSE if unsuccessful.
150  *
151  **/
152 SPIBoolean
153 AccessibleStreamableContent_open (AccessibleStreamableContent *obj,
154                                   const char *content_type)
155 {
156   Bonobo_Stream stream;
157   struct StreamCacheItem *cache;
158   stream = Accessibility_StreamableContent_getContent (CSPI_OBJREF (obj),
159                                                        content_type,
160                                                        cspi_ev ());    
161   if (stream != CORBA_OBJECT_NIL) {
162     cache = g_new0 (struct StreamCacheItem, 1);
163     cache->stream = stream;
164     cache->mimetype = CORBA_string_dup (content_type);
165     g_hash_table_replace (get_streams (), stream, cache);
166     return TRUE;
167   }
168   return FALSE;
169 }
170
171 /**
172  * AccessibleStreamableContent_close:
173  * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate.
174  *
175  * Close the current streaming connection to an AccessibleStreamableContent implementor.
176  * This must be called before any subsequent AccessibleStreamableContent_open
177  * calls on the same object.
178  *
179  * Returns: #TRUE if successful, #FALSE if unsuccessful.
180  *
181  **/
182 SPIBoolean
183 AccessibleStreamableContent_close (AccessibleStreamableContent *obj)
184 {
185   if (CSPI_OBJREF (obj) != CORBA_OBJECT_NIL) {
186     if (g_hash_table_remove (get_streams (), CSPI_OBJREF (obj)))
187       return TRUE;
188   }
189   return FALSE;
190 }
191
192 /**
193  * AccessibleStreamableContent_seek:
194  * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate.
195  * @offset: a long int specifying the offset into the stream.
196  * @seek_type: an enum indicating the seek offset type, may be SEEK_SET,
197  *            SEEK_CUR, SEEK_END (as in the lseek() libc command).
198  *
199  * Cause the current streamable content connection (obtained via
200  *     #AccessibleStreamableContent_open()) to seek to a particular offset in the
201  *     stream.
202  *
203  * Returns: #TRUE if successful, #FALSE if unsuccessful.
204  *
205  **/
206 SPIBoolean
207 AccessibleStreamableContent_seek (AccessibleStreamableContent *obj,
208                                   long int offset,
209                                   unsigned int seek_type)
210 {
211   /* currently Bonobo_Stream does not appear to support seek operations */
212   return FALSE;
213 }
214
215 /**
216  * AccessibleStreamableContent_read:
217  * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate.
218  * @buff: a pointer to a buffer into which the resulting bytes read from the stream
219  *        are to be written.
220  * @nbytes: a long integer indicating the number of bytes to read/write.
221  * @read_type: currently unused, specifies behavior of reads for streamed content
222  *        if blocking is not allowed, etc.
223  *
224  * Copy (read) bytes from the currently open streamable content connection
225  *     to a buffer.
226  *
227  * Returns: an integer indicating the number of bytes read, or -1 on error.
228  *
229  **/
230 SPIBoolean
231 AccessibleStreamableContent_read (AccessibleStreamableContent *obj,
232                                   void *buff,
233                                   long int nbytes,
234                                   unsigned int read_type)
235 {
236   Bonobo_Stream stream;
237   struct StreamCacheItem *cached; 
238   cached = g_hash_table_lookup (get_streams (), CSPI_OBJREF (obj));
239   if (cached) {
240     CORBA_long len_read;
241     stream = cached->stream;
242     if (stream != CORBA_OBJECT_NIL) {
243       guint8 *mem;
244       mem = bonobo_stream_client_read (stream, (size_t) nbytes, &len_read, cspi_ev ());
245       if (mem) memcpy (buff, mem, len_read);    
246       if (mem && ((nbytes == -1) || (len_read == nbytes)))
247         return TRUE;
248     }
249   }
250   return FALSE;
251 }
252