Fix for bug #345701; makes the Accessibility::StreamableContent
authorbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Thu, 22 Jun 2006 23:02:39 +0000 (23:02 +0000)
committerbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Thu, 22 Jun 2006 23:02:39 +0000 (23:02 +0000)
interface functional, and bridges from AtkStreamableContent where
available.
Tested in conjunction with patch for bug 345702 and an upcoming
enhancement patch for at-poke.

git-svn-id: http://svn.gnome.org/svn/at-spi/trunk@824 e2bd861d-eb25-0410-b326-f6ed22b6b98c

ChangeLog
cspi/spi_streamablecontent.c
idl/Accessibility_StreamableContent.idl
libspi/accessible.c
libspi/libspi.h
libspi/streamablecontent.c
libspi/streamablecontent.h
libspi/value.h

index 818eaf9..5e236ee 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
+2006-06-22  Bill Haneman <bill.haneman@sun.com>
+
+       Bug #345701.
+       
+       * idl/Accessibility_StreamableContent.idl:
+       Fix derivation of StreamableContent and ContentStream.
+
+       * cspi/spi_streamablecontent.c:
+       (accessible_content_stream_client_read):
+       Fix the datatype of the content stream used.
+       Interpret short reads as EOF, and stop trying to 
+       read when we've fulfilled the request.
+       (AccessibleStreamableContent_getContentTypes):
+       Use g_strdup, not CORBA_string_dup, for the strings.
+       (AccessibleStreamableContent_open):
+       Correctly use the new getStream method for opening,
+       not the deprecated getContent method.
+       Use the object reference as the stream hash key.
+       Make note of the 'one stream per client per streamable'
+       limitation in the docs.
+       
+       * libspi/libspi.h:
+       Add streamablecontent.h to the list of #includes.
+
+       * libspi/streamablecontent.c:
+       (impl_content_stream_read): Initialize the GError.
+       Allocate the incoming buffer if reading a fixed length of
+       data.  Use g_memmove instead of memcpy.
+       (impl_accessibility_streamable_get_content_types):
+       Init typelist->_maximum.  Only allocate the buffer if
+       there is a non-zero number of content types available.
+       (BONOBO_TYPE_FUNC_FULL(SpiStreamable): Move to end.
+
+       * libspi/streamablecontent.h:
+       (SPI_STREAMABLE_TYPE): Fix this macro, it was totally broken.
+
+       * libspi/value.h: 
+       (SPI_IS_VALUE): Fix a typo in this macro too.
+       
 2006-06-16  Bill Haneman <bill.haneman@sun.com>
 
        RFE #326532:
index 8b6b266..11fce9c 100644 (file)
@@ -115,7 +115,7 @@ accessible_content_stream_client_read (const Accessibility_ContentStream stream,
        *length_read = 0;
 
        for (pos = 0; pos < length;) {
-               Bonobo_Stream_iobuf *buf;
+               Accessibility_ContentStream_iobuf *buf;
                CORBA_long           len;
 
                len = (pos + CORBA_BLOCK_SIZE < length) ?
@@ -129,6 +129,10 @@ accessible_content_stream_client_read (const Accessibility_ContentStream stream,
                if (buf->_length > 0) {
                        memcpy (mem + pos, buf->_buffer, buf->_length);
                        pos += buf->_length;
+                       *length_read += buf->_length;
+                       /* we assume a short read equals EOF ... is that right? */
+                       if (buf->_length < len || *length_read == size)
+                           return mem;
                } else {
                        g_warning ("Buffer length %d", buf->_length);
                        goto io_error;
@@ -206,16 +210,17 @@ AccessibleStreamableContent_getContentTypes (AccessibleStreamableContent *obj)
   char **content_types;
   int i;
 
+  g_return_val_if_fail (obj != NULL, NULL);
+
   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[i] = g_strdup (mimeseq->_buffer[i]);
   content_types [mimeseq->_length] = NULL;
   CORBA_free (mimeseq);
-
+  
   return content_types;
 }
 /**
@@ -252,7 +257,9 @@ AccessibleStreamableContent_freeContentTypesList (AccessibleStreamableContent *o
  * of the return strings from #AccessibleStreamableContent_getContentTypes ()).
  *
  * Open a streaming connection to an AccessibleStreamableContent implementor,
- *       of a particular content type
+ *       of a particular content type.  Note that a client may only have one
+ *       open stream per streamable interface instance in the current 
+ *       implementation.
  *
  * @Since: AT-SPI 1.4
  *
@@ -265,16 +272,24 @@ AccessibleStreamableContent_open (AccessibleStreamableContent *obj,
 {
   Accessibility_ContentStream stream;
   struct StreamCacheItem *cache;
-  stream = Accessibility_StreamableContent_getContent (CSPI_OBJREF (obj),
-                                                      content_type,
-                                                      cspi_ev ());
+  stream = Accessibility_StreamableContent_getStream (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);
+
+    g_hash_table_replace (get_streams (), CSPI_OBJREF (obj), cache);
+    /* FIXME 
+     * This limits us to one concurrent stream per streamable interface
+     * for a given client.
+     * It might be reasonable for a client to open more than one stream
+     * to content, in different mime-types, at the same time.
+     */
+
     return TRUE;
   }
   return FALSE;
@@ -390,6 +405,7 @@ AccessibleStreamableContent_read (AccessibleStreamableContent *obj,
       if (stream != CORBA_OBJECT_NIL)
        {
           guint8 *mem;
+
          mem = accessible_content_stream_client_read (stream, (size_t) nbytes, &len_read, cspi_ev ());
          cspi_return_val_if_ev ("read", FALSE);
          if (mem)
@@ -401,6 +417,7 @@ AccessibleStreamableContent_read (AccessibleStreamableContent *obj,
            }
        }
     }
+  else g_message ("no matching stream was opened...");
   return FALSE;
 }
 
index 0f1ac1e..c38c647 100644 (file)
@@ -34,7 +34,7 @@ module Accessibility {
    *
    * @since AT-SPI 1.7.0 
    */
-  interface ContentStream {
+  interface ContentStream : Bonobo::Unknown {
 
       typedef sequence<octet> iobuf;
 
@@ -121,7 +121,7 @@ module Accessibility {
    * a particular document, but may in some cases give access to the 
    * underlying model data.
    */
-  interface StreamableContent {
+  interface StreamableContent : Bonobo::Unknown {
 
       /**
        * getContentTypes:
index 9454705..43f701b 100644 (file)
@@ -615,6 +615,12 @@ spi_accessible_construct (GType type, AtkObject *o)
                                     BONOBO_OBJECT (spi_value_interface_new (o)));
       }
 
+    if (ATK_IS_STREAMABLE_CONTENT (o))
+      {
+        bonobo_object_add_interface (bonobo_object (retval),
+                                    BONOBO_OBJECT (spi_streamable_interface_new (o)));
+      }
+
     return retval;
 }
 
index ae47293..6371ff8 100644 (file)
@@ -44,5 +44,6 @@
 #include <libspi/devicelistener.h>
 #include <libspi/keymasks.h>
 #include <libspi/remoteobject.h>
+#include <libspi/streamablecontent.h>
 
 #endif /* LIBSPI_H_ */
index 51c4579..f686db3 100644 (file)
@@ -1,7 +1,6 @@
 /*
  * AT-SPI - Assistive Technology Service Provider Interface
- * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
- *
+ * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap) *
  * Copyright 2001, 2002 Sun Microsystems Inc.,
  * Copyright 2001, 2002 Ximian, Inc.
  *
@@ -111,14 +110,18 @@ impl_content_stream_read (PortableServer_Servant servant,
 {
   SpiContentStream *stream = SPI_CONTENT_STREAM (bonobo_object_from_servant(servant));
   CORBA_long realcount = 0;
+
   if (stream && stream->gio)
   {
       gchar *gbuf = NULL;
       GIOStatus status;
-      GError *err;
+      GError *err = NULL;
       /* read the giochannel and determine the actual bytes read...*/
-      if (count != -1)
-         status = g_io_channel_read_chars (stream->gio, &gbuf, count, &realcount, &err);
+      if (count != -1) {
+         gbuf = g_malloc (count+1);
+         status = g_io_channel_read_chars (stream->gio, gbuf, count, &realcount, &err);
+      }
       else
          status = g_io_channel_read_to_end (stream->gio, &gbuf, &realcount, &err);
 
@@ -130,7 +133,7 @@ impl_content_stream_read (PortableServer_Servant servant,
          (*buffer)->_buffer = CORBA_sequence_CORBA_octet_allocbuf (realcount);
          (*buffer)->_length = realcount;
       
-         memcpy ((*buffer)->_buffer, gbuf, realcount);  
+         g_memmove ((*buffer)->_buffer, gbuf, realcount);  
       }
 
       g_free (gbuf);
@@ -195,17 +198,21 @@ impl_accessibility_streamable_get_content_types (PortableServer_Servant servant,
   AtkStreamableContent *streamable = get_streamable_from_servant (servant);
   int n_types, i;
 
-  typelist->_length = 0;
+  typelist->_length = typelist->_maximum = 0;
+
   g_return_val_if_fail (streamable != NULL, typelist);
 
   n_types = atk_streamable_content_get_n_mime_types (streamable);
-  typelist->_length = n_types;
-  typelist->_buffer = Accessibility_StringSeq_allocbuf (n_types);
-  for (i = 0; i < n_types; ++i) {
-    const gchar *mimetype = atk_streamable_content_get_mime_type (streamable, i);
-    typelist->_buffer[i] = CORBA_string_dup (mimetype ? mimetype : "");
-  }
 
+  if (n_types)
+  {
+      typelist->_length = typelist->_maximum = n_types;
+      typelist->_buffer = Accessibility_StringSeq_allocbuf (n_types);
+      for (i = 0; i < n_types; ++i) {
+         const gchar *mimetype = atk_streamable_content_get_mime_type (streamable, i);
+         typelist->_buffer[i] = CORBA_string_dup (mimetype ? mimetype : "");
+      }
+  }
   return typelist;
 }
 
@@ -225,8 +232,10 @@ impl_accessibility_streamable_get_content (PortableServer_Servant servant,
 
   gio = atk_streamable_content_get_stream (streamable, content_type);
 
-  stream = CORBA_OBJECT_NIL; /* FIXME! */
-
+  stream = CORBA_OBJECT_NIL; /* deprecated, 
+                             * and it was never implemented,
+                             * so don't bother fixing this 
+                             */
   return stream;
 }
 
@@ -286,10 +295,6 @@ spi_streamable_init (SpiStreamable *streamable)
 {
 }
 
-BONOBO_TYPE_FUNC_FULL (SpiStreamable,
-                      Accessibility_StreamableContent,
-                      PARENT_TYPE,
-                      spi_streamable)
 
 SpiStreamable *
 spi_streamable_interface_new (AtkObject *o)
@@ -300,3 +305,8 @@ spi_streamable_interface_new (AtkObject *o)
 
     return retval;
 }
+
+BONOBO_TYPE_FUNC_FULL (SpiStreamable,
+                      Accessibility_StreamableContent,
+                      PARENT_TYPE,
+                      spi_streamable)
index 77a97d6..666652a 100644 (file)
@@ -29,7 +29,7 @@
 
 G_BEGIN_DECLS
 
-#define SPI_STREAMABLE_TYPE        (spi_component_get_type ())
+#define SPI_STREAMABLE_TYPE        (spi_streamable_get_type ())
 #define SPI_STREAMABLE(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), SPI_STREAMABLE_TYPE, SpiStreamable))
 #define SPI_STREAMABLE_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST((k), SPI_STREAMABLE_TYPE, SpiStreamableClass))
 #define SPI_IS_STREAMABLE(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), SPI_STREAMABLE_TYPE))
index c771ef3..94e9378 100644 (file)
@@ -32,7 +32,7 @@ G_BEGIN_DECLS
 #define SPI_VALUE_TYPE            (spi_value_get_type ())
 #define SPI_VALUE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_VALUE_TYPE, SpiValue))
 #define SPI_VALUE_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST((klass), SPI_VALUE_TYPE, SpiValueClass))
-#define SPI_IS_VALUE(obj)         (G_TYPE_CHECK__INSTANCE_TYPE ((obj), SPI_VALUE_TYPE))
+#define SPI_IS_VALUE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPI_VALUE_TYPE))
 #define SPI_IS_VALUE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_VALUE_TYPE))
 
 typedef struct _Value SpiValue;