Strip symbols that should not be exported; add "Since" tag to at-spi
[platform/core/uifw/at-spi2-atk.git] / cspi / spi_streamablecontent.c
index 9a2db99..2e0c080 100644 (file)
@@ -1,5 +1,102 @@
+/*
+ * AT-SPI - Assistive Technology Service Provider Interface
+ * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
+ *
+ * Copyright 2001, 2002 Sun Microsystems Inc.,
+ * Copyright 2001, 2002 Ximian, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <libbonobo.h>
 #include <cspi/spi-private.h>
 
+
+/* TODO: factor/wrap Bonobo_Stream dependency to cspi/bonobo */
+
+struct StreamCacheItem {
+  Bonobo_Stream stream;
+  gchar *mimetype;
+};
+
+static gboolean
+streams_equal_func (gconstpointer a, gconstpointer b)
+{
+  const struct StreamCacheItem *c1 = a, *c2 = b;
+  return CORBA_Object_is_equivalent (c1->stream, c2->stream, cspi_ev ());
+}
+
+static void
+stream_cache_item_free (gpointer a)
+{
+  struct StreamCacheItem *cache_item = a;
+
+  cspi_release_unref (cache_item->stream);
+  SPI_freeString (cache_item->mimetype);
+  g_free (cache_item);
+}
+
+static GHashTable *streams = NULL;
+
+static GHashTable *
+get_streams (void) 
+{
+  if (streams == NULL)
+      streams = g_hash_table_new_full (g_direct_hash, streams_equal_func, 
+                                      NULL, stream_cache_item_free);
+  return streams;
+}
+
+static CORBA_long
+accessible_bonobo_stream_client_seek (const Bonobo_Stream stream,
+                                     CORBA_long offset,
+                                     Bonobo_Stream_SeekType seek_type,
+                                     CORBA_Environment  *opt_ev)
+{
+       CORBA_Environment  *ev, temp_ev;
+       CORBA_long ret_offset;
+       
+       if (!opt_ev) {
+               CORBA_exception_init (&temp_ev);
+               ev = &temp_ev;
+       } else
+               ev = opt_ev;
+
+       ret_offset = Bonobo_Stream_seek (stream, offset, seek_type, ev);
+       if (BONOBO_EX (ev))
+               ret_offset = -1;
+
+       if (!opt_ev)
+               CORBA_exception_free (&temp_ev);
+       
+       return ret_offset;
+}
+
+/* internal use only, declared in cspi-private.h */
+void
+cspi_streams_close_all (void)
+{
+  if (streams)
+    {
+      g_hash_table_destroy (streams);
+      streams = NULL;
+    }
+}
+
 /**
  * AccessibleStreamableContent_ref:
  * @obj: a pointer to the #AccessibleStreamableContent implementor on which to
@@ -7,6 +104,7 @@
  *
  * Increment the reference count for an #AccessibleStreamableContent object.
  *
+ * @Since: AT-SPI 1.4
  **/
 void
 AccessibleStreamableContent_ref (AccessibleStreamableContent *obj)
@@ -21,6 +119,7 @@ AccessibleStreamableContent_ref (AccessibleStreamableContent *obj)
  *
  * Decrement the reference count for an #AccessibleStreamableContent object.
  *
+ * @Since: AT-SPI 1.4
  **/
 void
 AccessibleStreamableContent_unref (AccessibleStreamableContent *obj)
@@ -35,19 +134,58 @@ AccessibleStreamableContent_unref (AccessibleStreamableContent *obj)
  * Get a list of strings containing the content mimetypes available from an
  *       #AccessibleStreamableContent implementor.
  *
+ * @Since: AT-SPI 1.4
+ *
  * Returns: an array of strings, terminated by a NULL string, specifying the
  *       mimetypes for which the streamed content is available.
  *
  **/
+
 char **
 AccessibleStreamableContent_getContentTypes (AccessibleStreamableContent *obj)
 {
-  char **content_types = malloc (sizeof (char *));
-  content_types [0] = NULL;
+  Accessibility_StringSeq *mimeseq;
+  char **content_types;
+  int i;
+
+  mimeseq = Accessibility_StreamableContent_getContentTypes (CSPI_OBJREF (obj),
+                                                            cspi_ev ());
+  cspi_return_val_if_ev ("getContentTypes", NULL); 
+
+  content_types = g_new0 (char *, mimeseq->_length + 1);
+  for (i = 0; i < mimeseq->_length; ++i)
+    content_types[i] = CORBA_string_dup (mimeseq->_buffer[i]);
+  content_types [mimeseq->_length] = NULL;
+  CORBA_free (mimeseq);
 
-  /* TODO: connect this to the correct libspi implementation code */
   return content_types;
 }
+/**
+* AccessibleStreamableContent_freeContentTypesList:
+* @obj: the AccessibleStreamableContent implementor on which to operate.
+* @content_types: a list of content types previously returned by 
+*     #AccessibleStreamableContent_getContentTypes.
+*
+* Free the memory associated with a call to #AccessibleStreamableContent_getContentTypes, once 
+* the result has been used.
+*
+* @Since: AT-SPI 1.4
+**/
+void
+AccessibleStreamableContent_freeContentTypesList (AccessibleStreamableContent *obj,
+                                                 char **content_types)
+{
+  if (content_types) 
+    {
+      gint i = 0;
+      while (content_types[i])
+       {
+         g_free (content_types[i]);
+         i++;
+       }
+      g_free (content_types);
+    }
+}
 
 /**
  * AccessibleStreamableContent_open:
@@ -58,6 +196,8 @@ AccessibleStreamableContent_getContentTypes (AccessibleStreamableContent *obj)
  * Open a streaming connection to an AccessibleStreamableContent implementor,
  *       of a particular content type
  *
+ * @Since: AT-SPI 1.4
+ *
  * Returns: #TRUE if successful, #FALSE if unsuccessful.
  *
  **/
@@ -65,7 +205,43 @@ SPIBoolean
 AccessibleStreamableContent_open (AccessibleStreamableContent *obj,
                                  const char *content_type)
 {
-  /* TODO: connect this to the correct libspi implementation code */
+  Bonobo_Stream stream;
+  struct StreamCacheItem *cache;
+  stream = Accessibility_StreamableContent_getContent (CSPI_OBJREF (obj),
+                                                      content_type,
+                                                      cspi_ev ());
+  cspi_return_val_if_ev ("getContent", FALSE); 
+
+  if (stream != CORBA_OBJECT_NIL) {
+    cache = g_new0 (struct StreamCacheItem, 1);
+    cache->stream = stream;
+    cache->mimetype = CORBA_string_dup (content_type);
+    g_hash_table_replace (get_streams (), stream, cache);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/**
+ * AccessibleStreamableContent_close:
+ * @obj: a pointer to the #AccessibleStreamableContent implementor on which to operate.
+ *
+ * Close the current streaming connection to an AccessibleStreamableContent implementor.
+ * This must be called before any subsequent AccessibleStreamableContent_open
+ * calls on the same object.
+ * 
+ * @Since: AT-SPI 1.4
+ *
+ * Returns: #TRUE if successful, #FALSE if unsuccessful.
+ *
+ **/
+SPIBoolean
+AccessibleStreamableContent_close (AccessibleStreamableContent *obj)
+{
+  if (CSPI_OBJREF (obj) != CORBA_OBJECT_NIL) {
+    if (g_hash_table_remove (get_streams (), CSPI_OBJREF (obj)))
+      return TRUE;
+  }
   return FALSE;
 }
 
@@ -80,16 +256,46 @@ AccessibleStreamableContent_open (AccessibleStreamableContent *obj,
  *     #AccessibleStreamableContent_open()) to seek to a particular offset in the
  *     stream.
  *
+ * @Since: AT-SPI 1.4
+ *
  * Returns: #TRUE if successful, #FALSE if unsuccessful.
  *
  **/
-SPIBoolean
+long int
 AccessibleStreamableContent_seek (AccessibleStreamableContent *obj,
                                  long int offset,
-                                 unsigned int seek_type)
+                                 AccessibleStreamableContentSeekType seek_type)
 {
-  /* TODO: connect this to the correct libspi implementation code */
-  return FALSE;
+  Bonobo_Stream stream;
+  long int ret_offset = 0;
+  struct StreamCacheItem *cached; 
+  Bonobo_Stream_SeekType bonobo_seek_type;
+
+  cached = g_hash_table_lookup (get_streams (), CSPI_OBJREF (obj));
+  if (cached)
+    {
+      stream = cached->stream;
+      if (stream != CORBA_OBJECT_NIL)
+       {
+         switch (seek_type) {
+         case SPI_STREAM_SEEK_SET:
+           bonobo_seek_type = Bonobo_Stream_SeekSet; 
+           break;
+         case SPI_STREAM_SEEK_END:
+           bonobo_seek_type = Bonobo_Stream_SeekEnd; 
+           break;
+         case SPI_STREAM_SEEK_CUR:
+         default:
+           bonobo_seek_type = Bonobo_Stream_SeekCur; 
+           break;
+         }
+         /* bonobo-client doesn't wrap seek yet, so we have to. */
+         ret_offset = accessible_bonobo_stream_client_seek (stream, offset, 
+                                                            bonobo_seek_type, cspi_ev ());
+         cspi_return_val_if_ev ("seek", FALSE);
+       }
+    }
+  return ret_offset;
 }
 
 /**
@@ -102,7 +308,11 @@ AccessibleStreamableContent_seek (AccessibleStreamableContent *obj,
  *        if blocking is not allowed, etc.
  *
  * Copy (read) bytes from the currently open streamable content connection
- *     to a buffer.
+ *     to a buffer.  This is a blocking API, in the sense that it does not 
+ *     return until the bytes have been read, or an error condition is 
+ *     detected.
+ *
+ * @Since: AT-SPI 1.4
  *
  * Returns: an integer indicating the number of bytes read, or -1 on error.
  *
@@ -113,7 +323,27 @@ AccessibleStreamableContent_read (AccessibleStreamableContent *obj,
                                  long int nbytes,
                                  unsigned int read_type)
 {
-  /* TODO: connect this to the correct libspi implementation code */
-  return -1;
+  Bonobo_Stream stream;
+  struct StreamCacheItem *cached; 
+  cached = g_hash_table_lookup (get_streams (), CSPI_OBJREF (obj));
+  if (cached)
+    {
+      CORBA_long len_read;
+      stream = cached->stream;
+      if (stream != CORBA_OBJECT_NIL)
+       {
+          guint8 *mem;
+         mem = bonobo_stream_client_read (stream, (size_t) nbytes, &len_read, cspi_ev ());
+         cspi_return_val_if_ev ("read", FALSE);
+         if (mem)
+            {
+              memcpy (buff, mem, len_read);
+             g_free (mem);
+             if ((nbytes == -1) || (len_read == nbytes))
+                return TRUE;
+           }
+       }
+    }
+  return FALSE;
 }