500b339d94e9df878e9b7bb99872e0f59e33f0d9
[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 <string.h>
25 #include <libbonobo.h>
26 #include <cspi/spi-private.h>
27
28
29 /* TODO: factor/wrap Bonobo_Stream dependency to cspi/bonobo */
30
31 struct StreamCacheItem {
32   Bonobo_Stream stream;
33   gchar *mimetype;
34 };
35
36 static gboolean
37 streams_equal_func (gconstpointer a, gconstpointer b)
38 {
39   const struct StreamCacheItem *c1 = a, *c2 = b;
40   return CORBA_Object_is_equivalent (c1->stream, c2->stream, cspi_ev ());
41 }
42
43 static void
44 stream_release (gpointer a)
45 {
46   CORBA_Environment ev;
47
48   bonobo_object_release_unref (a, &ev);
49 }
50
51 static void
52 stream_cache_item_free (gpointer a)
53 {
54   struct StreamCacheItem *cache_item = a;
55   CORBA_Environment ev;
56   if (cache_item) {
57     bonobo_object_release_unref (cache_item->stream, &ev);
58     SPI_freeString (cache_item->mimetype);
59     g_free (cache_item);
60   }
61 }
62
63 static GHashTable *streams = NULL;
64
65 GHashTable *
66 get_streams (void) 
67 {
68   if (streams == NULL) {
69     streams = g_hash_table_new_full (g_direct_hash, streams_equal_func, 
70                                      stream_release, stream_cache_item_free);
71   }
72   return streams;
73 }
74
75 /* internal use only, declared in cspi-private.h */
76 void
77 cspi_streams_close_all (void)
78 {
79   if (streams)
80     {
81       g_hash_table_destroy (streams);
82       streams = NULL;
83     }
84 }
85
86 /**
87  * AccessibleStreamableContent_ref:
88  * @obj: a pointer to the #AccessibleStreamableContent implementor on which to
89  *       operate.
90  *
91  * Increment the reference count for an #AccessibleStreamableContent object.
92  *
93  **/
94 void
95 AccessibleStreamableContent_ref (AccessibleStreamableContent *obj)
96 {
97   cspi_object_ref (obj);
98 }
99
100 /**
101  * AccessibleStreamableContent_unref:
102  * @obj: a pointer to the #AccessibleStreamableContent implementor
103  *       on which to operate. 
104  *
105  * Decrement the reference count for an #AccessibleStreamableContent object.
106  *
107  **/
108 void
109 AccessibleStreamableContent_unref (AccessibleStreamableContent *obj)
110 {
111   cspi_object_unref (obj);
112 }
113
114 /**
115  * AccessibleStreamableContent_getContentTypes:
116  * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate.
117  *
118  * Get a list of strings containing the content mimetypes available from an
119  *       #AccessibleStreamableContent implementor.
120  *
121  * Returns: an array of strings, terminated by a NULL string, specifying the
122  *       mimetypes for which the streamed content is available.
123  *
124  **/
125 char **
126 AccessibleStreamableContent_getContentTypes (AccessibleStreamableContent *obj)
127 {
128   Accessibility_StringSeq *mimeseq;
129   char **content_types;
130   int i;
131
132   mimeseq = Accessibility_StreamableContent_getContentTypes (CSPI_OBJREF (obj),
133                                                              cspi_ev ());
134
135   content_types = g_new0 (char *, mimeseq->_length + 1);
136   for (i = 0; i < mimeseq->_length; ++i) {
137     content_types[i] = CORBA_string_dup (mimeseq->_buffer[i]);
138   }
139   content_types [mimeseq->_length] = NULL;
140   CORBA_free (mimeseq);
141
142   return content_types;
143 }
144
145 /**
146  * AccessibleStreamableContent_open:
147  * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate.
148  * @content_type: a string specifying the content type to retrieve (should match one
149  * of the return strings from #AccessibleStreamableContent_getContentTypes ()).
150  *
151  * Open a streaming connection to an AccessibleStreamableContent implementor,
152  *       of a particular content type
153  *
154  * Returns: #TRUE if successful, #FALSE if unsuccessful.
155  *
156  **/
157 SPIBoolean
158 AccessibleStreamableContent_open (AccessibleStreamableContent *obj,
159                                   const char *content_type)
160 {
161   Bonobo_Stream stream;
162   struct StreamCacheItem *cache;
163   stream = Accessibility_StreamableContent_getContent (CSPI_OBJREF (obj),
164                                                        content_type,
165                                                        cspi_ev ());    
166   if (stream != CORBA_OBJECT_NIL) {
167     cache = g_new0 (struct StreamCacheItem, 1);
168     cache->stream = stream;
169     cache->mimetype = CORBA_string_dup (content_type);
170     g_hash_table_replace (get_streams (), stream, cache);
171     return TRUE;
172   }
173   return FALSE;
174 }
175
176 /**
177  * AccessibleStreamableContent_close:
178  * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate.
179  *
180  * Close the current streaming connection to an AccessibleStreamableContent implementor.
181  * This must be called before any subsequent AccessibleStreamableContent_open
182  * calls on the same object.
183  *
184  * Returns: #TRUE if successful, #FALSE if unsuccessful.
185  *
186  **/
187 SPIBoolean
188 AccessibleStreamableContent_close (AccessibleStreamableContent *obj)
189 {
190   if (CSPI_OBJREF (obj) != CORBA_OBJECT_NIL) {
191     if (g_hash_table_remove (get_streams (), CSPI_OBJREF (obj)))
192       return TRUE;
193   }
194   return FALSE;
195 }
196
197 /**
198  * AccessibleStreamableContent_seek:
199  * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate.
200  * @offset: a long int specifying the offset into the stream.
201  * @seek_type: an enum indicating the seek offset type, may be SEEK_SET,
202  *            SEEK_CUR, SEEK_END (as in the lseek() libc command).
203  *
204  * Cause the current streamable content connection (obtained via
205  *     #AccessibleStreamableContent_open()) to seek to a particular offset in the
206  *     stream.
207  *
208  * Returns: #TRUE if successful, #FALSE if unsuccessful.
209  *
210  **/
211 SPIBoolean
212 AccessibleStreamableContent_seek (AccessibleStreamableContent *obj,
213                                   long int offset,
214                                   unsigned int seek_type)
215 {
216   /* currently Bonobo_Stream does not appear to support seek operations */
217   return FALSE;
218 }
219
220 /**
221  * AccessibleStreamableContent_read:
222  * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate.
223  * @buff: a pointer to a buffer into which the resulting bytes read from the stream
224  *        are to be written.
225  * @nbytes: a long integer indicating the number of bytes to read/write.
226  * @read_type: currently unused, specifies behavior of reads for streamed content
227  *        if blocking is not allowed, etc.
228  *
229  * Copy (read) bytes from the currently open streamable content connection
230  *     to a buffer.
231  *
232  * Returns: an integer indicating the number of bytes read, or -1 on error.
233  *
234  **/
235 SPIBoolean
236 AccessibleStreamableContent_read (AccessibleStreamableContent *obj,
237                                   void *buff,
238                                   long int nbytes,
239                                   unsigned int read_type)
240 {
241   Bonobo_Stream stream;
242   struct StreamCacheItem *cached; 
243   cached = g_hash_table_lookup (get_streams (), CSPI_OBJREF (obj));
244   if (cached) {
245     CORBA_long len_read;
246     stream = cached->stream;
247     if (stream != CORBA_OBJECT_NIL) {
248       guint8 *mem;
249       mem = bonobo_stream_client_read (stream, (size_t) nbytes, &len_read, cspi_ev ());
250       if (mem) memcpy (buff, mem, len_read);    
251       if (mem && ((nbytes == -1) || (len_read == nbytes)))
252         return TRUE;
253     }
254   }
255   return FALSE;
256 }
257