Implement RFE #326532: remove BonoboStream usage from
authorbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Fri, 16 Jun 2006 15:05:32 +0000 (15:05 +0000)
committerbillh <billh@e2bd861d-eb25-0410-b326-f6ed22b6b98c>
Fri, 16 Jun 2006 15:05:32 +0000 (15:05 +0000)
at-spi's StreamableContent interface, and add getURI method.

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

ChangeLog
cspi/spi_streamablecontent.c
idl/Accessibility_StreamableContent.idl
libspi/streamablecontent.c

index 59a25c3..818eaf9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,51 @@
+2006-06-16  Bill Haneman <bill.haneman@sun.com>
+
+       RFE #326532:
+       
+       * idl/Accessibility_StreambleContent.idl:
+       Deprecate the Bonobo_Stream-based methods in favor of
+       a self-contained "ContentStream" interface.  This should 
+       allow us to remove BonoboStream dependencies entirely, since
+       there were no non-NIL implementations of the old methods anyway.
+       (ContentStream): New interface.
+       (ContentStream::SeekType): Enum.
+       (ContentStream::seek): New.
+       (ContentStream::read): New.
+       (ContentStream::close): New.
+       (getContent): Deprecate.
+       (getURI): New method, returns a URI pointing to the content, if available.
+       
+       * libspi/streamablecontent.c:
+       (SpiContentStream): Internal object type definition used to
+       implement Accessibility::StreamableContent::ContentStream via
+       AtkStreamableContent's GIOChannel back-end.
+       (spi_content_stream_new, spi_content_stream_dispose): See above;
+       static methods.
+       (impl_content_stream_seek, impl_content_stream_read):
+       (impl_content_stream_close): New, implementations of
+       ContentStream's IDL.
+       (impl_accessibility_streamable_get_stream): Implement the 
+       public method Accessibility::StreamableContent::getStream.
+       (impl_accessibility_streamable_get_uri): Implement the 
+       public method Accessibility::StreamableContent::getURI.
+
+       * cspi/spi_streamablecontent.c:
+       (accessible_bonobo_stream_client_seek): Replaced by
+       (accessible_content_stream_client_seek).
+       (accessible_bonobo_stream_client_read): Replaced by
+       (accessible_content_stream_client_read).
+       (AccessibleStreamableContent_open):
+       (AccessibleStreamableContent_seek):
+       (AccessibleStreamableContent_read):
+       (AccessibleStreamableContent_close): Use the new 'getStream'
+       API instead of the deprecated 'getContent' API, inside the cspi wrappers.
+       
+2006-06-15  Bill Haneman <bill.haneman@sun.com>
+
+       * idl/Accessibility.idl: #include Bonobo_Unknown.idl,
+       remove from other .idl files (except LoginHelper).
+       See bug #313122.
+
 2006-06-14  Bill Haneman <bill.haneman@sun.com>
 
        * */Makefile.am: Add WARN_CFLAGS to INCLUDES.
 2006-06-14  Bill Haneman <bill.haneman@sun.com>
 
        * */Makefile.am: Add WARN_CFLAGS to INCLUDES.
index 2e0c080..8b6b266 100644 (file)
 #include <libbonobo.h>
 #include <cspi/spi-private.h>
 
 #include <libbonobo.h>
 #include <cspi/spi-private.h>
 
-
-/* TODO: factor/wrap Bonobo_Stream dependency to cspi/bonobo */
+#define CORBA_BLOCK_SIZE 65536 /* see libbonobo, dunno where this is officially dictated */
 
 struct StreamCacheItem {
 
 struct StreamCacheItem {
-  Bonobo_Stream stream;
+  Accessibility_ContentStream stream;
   gchar *mimetype;
 };
 
   gchar *mimetype;
 };
 
@@ -62,9 +61,9 @@ get_streams (void)
 }
 
 static CORBA_long
 }
 
 static CORBA_long
-accessible_bonobo_stream_client_seek (const Bonobo_Stream stream,
+accessible_content_stream_client_seek (const Accessibility_ContentStream stream,
                                      CORBA_long offset,
                                      CORBA_long offset,
-                                     Bonobo_Stream_SeekType seek_type,
+                                     Accessibility_ContentStream_SeekType seek_type,
                                      CORBA_Environment  *opt_ev)
 {
        CORBA_Environment  *ev, temp_ev;
                                      CORBA_Environment  *opt_ev)
 {
        CORBA_Environment  *ev, temp_ev;
@@ -76,7 +75,7 @@ accessible_bonobo_stream_client_seek (const Bonobo_Stream stream,
        } else
                ev = opt_ev;
 
        } else
                ev = opt_ev;
 
-       ret_offset = Bonobo_Stream_seek (stream, offset, seek_type, ev);
+       ret_offset = Accessibility_ContentStream_seek (stream, offset, seek_type, ev);
        if (BONOBO_EX (ev))
                ret_offset = -1;
 
        if (BONOBO_EX (ev))
                ret_offset = -1;
 
@@ -86,6 +85,65 @@ accessible_bonobo_stream_client_seek (const Bonobo_Stream stream,
        return ret_offset;
 }
 
        return ret_offset;
 }
 
+static guint8*
+accessible_content_stream_client_read (const Accessibility_ContentStream stream,
+                                      const size_t size,
+                                      CORBA_long *length_read,
+                                      CORBA_Environment  *ev)
+{
+       size_t  pos;
+       guint8 *mem;
+       size_t  length;
+
+       g_return_val_if_fail (ev != NULL, NULL);
+
+       if (length_read)
+               *length_read = size;
+
+       length = size;
+
+       if (length == 0)
+               return NULL;
+
+       mem = g_try_malloc (length);
+       if (!mem) {
+               CORBA_exception_set_system (ev, ex_CORBA_NO_MEMORY,
+                                           CORBA_COMPLETED_NO);
+               return NULL;
+       }
+
+       *length_read = 0;
+
+       for (pos = 0; pos < length;) {
+               Bonobo_Stream_iobuf *buf;
+               CORBA_long           len;
+
+               len = (pos + CORBA_BLOCK_SIZE < length) ?
+                       CORBA_BLOCK_SIZE : length - pos;
+
+               Accessibility_ContentStream_read (stream, len, &buf, ev);
+
+               if (BONOBO_EX (ev) || !buf)
+                       goto io_error;
+
+               if (buf->_length > 0) {
+                       memcpy (mem + pos, buf->_buffer, buf->_length);
+                       pos += buf->_length;
+               } else {
+                       g_warning ("Buffer length %d", buf->_length);
+                       goto io_error;
+               }
+               *length_read += buf->_length;
+
+               CORBA_free (buf);
+       }
+
+       return mem;
+
+ io_error:
+       return NULL;
+}
+
 /* internal use only, declared in cspi-private.h */
 void
 cspi_streams_close_all (void)
 /* internal use only, declared in cspi-private.h */
 void
 cspi_streams_close_all (void)
@@ -205,7 +263,7 @@ SPIBoolean
 AccessibleStreamableContent_open (AccessibleStreamableContent *obj,
                                  const char *content_type)
 {
 AccessibleStreamableContent_open (AccessibleStreamableContent *obj,
                                  const char *content_type)
 {
-  Bonobo_Stream stream;
+  Accessibility_ContentStream stream;
   struct StreamCacheItem *cache;
   stream = Accessibility_StreamableContent_getContent (CSPI_OBJREF (obj),
                                                       content_type,
   struct StreamCacheItem *cache;
   stream = Accessibility_StreamableContent_getContent (CSPI_OBJREF (obj),
                                                       content_type,
@@ -266,10 +324,10 @@ AccessibleStreamableContent_seek (AccessibleStreamableContent *obj,
                                  long int offset,
                                  AccessibleStreamableContentSeekType seek_type)
 {
                                  long int offset,
                                  AccessibleStreamableContentSeekType seek_type)
 {
-  Bonobo_Stream stream;
+  Accessibility_ContentStream stream;
   long int ret_offset = 0;
   struct StreamCacheItem *cached; 
   long int ret_offset = 0;
   struct StreamCacheItem *cached; 
-  Bonobo_Stream_SeekType bonobo_seek_type;
+  Accessibility_ContentStream_SeekType content_seek_type;
 
   cached = g_hash_table_lookup (get_streams (), CSPI_OBJREF (obj));
   if (cached)
 
   cached = g_hash_table_lookup (get_streams (), CSPI_OBJREF (obj));
   if (cached)
@@ -279,19 +337,18 @@ AccessibleStreamableContent_seek (AccessibleStreamableContent *obj,
        {
          switch (seek_type) {
          case SPI_STREAM_SEEK_SET:
        {
          switch (seek_type) {
          case SPI_STREAM_SEEK_SET:
-           bonobo_seek_type = Bonobo_Stream_SeekSet
+           content_seek_type = Accessibility_ContentStream_SEEK_SET
            break;
          case SPI_STREAM_SEEK_END:
            break;
          case SPI_STREAM_SEEK_END:
-           bonobo_seek_type = Bonobo_Stream_SeekEnd
+           content_seek_type = Accessibility_ContentStream_SEEK_END
            break;
          case SPI_STREAM_SEEK_CUR:
          default:
            break;
          case SPI_STREAM_SEEK_CUR:
          default:
-           bonobo_seek_type = Bonobo_Stream_SeekCur
+           content_seek_type = Accessibility_ContentStream_SEEK_CURRENT
            break;
          }
            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 ());
+         ret_offset = accessible_content_stream_client_seek (stream, offset, 
+                                                            content_seek_type, cspi_ev ());
          cspi_return_val_if_ev ("seek", FALSE);
        }
     }
          cspi_return_val_if_ev ("seek", FALSE);
        }
     }
@@ -323,7 +380,7 @@ AccessibleStreamableContent_read (AccessibleStreamableContent *obj,
                                  long int nbytes,
                                  unsigned int read_type)
 {
                                  long int nbytes,
                                  unsigned int read_type)
 {
-  Bonobo_Stream stream;
+  Accessibility_ContentStream stream;
   struct StreamCacheItem *cached; 
   cached = g_hash_table_lookup (get_streams (), CSPI_OBJREF (obj));
   if (cached)
   struct StreamCacheItem *cached; 
   cached = g_hash_table_lookup (get_streams (), CSPI_OBJREF (obj));
   if (cached)
@@ -333,7 +390,7 @@ AccessibleStreamableContent_read (AccessibleStreamableContent *obj,
       if (stream != CORBA_OBJECT_NIL)
        {
           guint8 *mem;
       if (stream != CORBA_OBJECT_NIL)
        {
           guint8 *mem;
-         mem = bonobo_stream_client_read (stream, (size_t) nbytes, &len_read, cspi_ev ());
+         mem = accessible_content_stream_client_read (stream, (size_t) nbytes, &len_read, cspi_ev ());
          cspi_return_val_if_ev ("read", FALSE);
          if (mem)
             {
          cspi_return_val_if_ev ("read", FALSE);
          if (mem)
             {
index c552a63..0f1ac1e 100644 (file)
@@ -27,35 +27,16 @@ module Accessibility {
   typedef sequence<string> StringSeq;
 
   /** 
   typedef sequence<string> StringSeq;
 
   /** 
-   * An interface whereby an object allows its backing content
-   * to be streamed to clients.  Negotiation of content type
-   * is allowed.  Clients may examine the backing data and
-   * transform, convert, or parse the content in order to
-   * present it in an alternate form to end-users.
+   * An interface by which the requested data from a StreamableContent object
+   * may be read by the client.
+   * @note this interface supercedes the use of BonoboStream by previous
+   * versions of StreamableContent.
    *
    *
-   * @note The StreamableContent interface is particularly useful for saving, 
-   * printing, or post-processing entire documents, or for persisting 
-   * alternate views of a document.
-   * If document content itself is being serialized, stored, or converted,
-   * then use of the StreamableContent interface can help address performance
-   * issues.  Unlike most AT-SPI/Accessibility interfaces, this interface
-   * is not strongly tied to the current user-agent view of the
-   * a particular document, but may in some cases give access to the 
-   * underlying model data.
+   * @since AT-SPI 1.7.0 
    */
    */
-  interface StreamableContent {
+  interface ContentStream {
 
 
-      /** 
-       * Specifies the meaning of a seek 'offset'.  Not all SeekTypes are 
-       * supported by all StreamableContent data sources, for instance 
-       * some streams may not support seeking from the beginning or other
-       * types of 'backwards' seeks.
-       */
-      enum SeekType {
-         SEEK_SET, /**< Seek from the start of the stream or data source.*/
-         SEEK_CURRENT, /**< Seek relative to the current position. */
-         SEEK_END /**< Seek from the end of the file, stream, or data source. */
-      };
+      typedef sequence<octet> iobuf;
 
       /** 
        * Indicates that a transmission error has occurred while 
 
       /** 
        * Indicates that a transmission error has occurred while 
@@ -80,12 +61,76 @@ module Accessibility {
          string reason;
       };
 
          string reason;
       };
 
+      /** 
+       * Specifies the meaning of a seek 'offset'.  Not all SeekTypes are 
+       * supported by all StreamableContent data sources, for instance 
+       * some streams may not support seeking from the beginning or other
+       * types of 'backwards' seeks.
+       */
+      enum SeekType {
+         SEEK_SET, /**< Seek from the start of the stream or data source.*/
+         SEEK_CURRENT, /**< Seek relative to the current position. */
+         SEEK_END /**< Seek from the end of the file, stream, or data source. */
+      };
+
+      /** 
+       * Seek to a specified position in the Stream.
+       * @param offset an offset specifying the requested position in the stream,
+       * relative to the SeekType specified in \c whence.
+       * @param whence a SeekType specifying the reference point from which the 
+       * seek offset is calculated.  Some forms of seek are not supported by certain
+       * implementations of Stream, in which case a NotSupported exception will be raised.
+       * @returns the actual resulting offset, if no exception was raised.
+       **/
+      long seek (in long offset, in SeekType whence)
+         raises (NoPermission, IOError, NotSupported);
+      /** 
+       * Request/read a specified amount of data from a Stream.
+       * @returns the number of bytes actually read into the client buffer.
+       **/
+      long read (in long count, out iobuf buffer)  
+         raises (NoPermission, IOError);
+      /** 
+       * close the stream and release associated resources.  
+       * A client should not perform further operations on a 
+       * StreamableContent::Stream object after closing it.
+       **/
+      void close ();
+
+      /** /cond */
+      void unimplemented ();
+      void unimplemented2 ();
+      /** /endcond */
+  };
+
+
+  /** 
+   * An interface whereby an object allows its backing content
+   * to be streamed to clients.  Negotiation of content type
+   * is allowed.  Clients may examine the backing data and
+   * transform, convert, or parse the content in order to
+   * present it in an alternate form to end-users.
+   *
+   * @note The StreamableContent interface is particularly useful for saving, 
+   * printing, or post-processing entire documents, or for persisting 
+   * alternate views of a document.
+   * If document content itself is being serialized, stored, or converted,
+   * then use of the StreamableContent interface can help address performance
+   * issues.  Unlike most AT-SPI/Accessibility interfaces, this interface
+   * is not strongly tied to the current user-agent view of the
+   * a particular document, but may in some cases give access to the 
+   * underlying model data.
+   */
+  interface StreamableContent {
+
       /**
        * getContentTypes:
        * @returns the list of available mimetypes for this object's content.
        */
     StringSeq getContentTypes ();
       /**
       /**
        * getContentTypes:
        * @returns the list of available mimetypes for this object's content.
        */
     StringSeq getContentTypes ();
       /**
+       * \n DEPRECATED, use getStream instead.
+       * getContent:
        * Retrieve this object's content, in a format appropriate to a
        * requested mimetype.
        *
        * Retrieve this object's content, in a format appropriate to a
        * requested mimetype.
        *
@@ -109,6 +154,33 @@ module Accessibility {
        */
     Bonobo::Stream getContent (in string contentType);
 
        */
     Bonobo::Stream getContent (in string contentType);
 
+      /**
+       * Retrieve this object's content, in a format appropriate to a
+       * requested mimetype, as a ::ContentStream instance.
+       *
+       * @note This method supercedes the older getContent method, which
+       * relied on the Bonobo::Stream API.
+       * \c seek may not be supported for all mimetypes or
+       * all implementors.
+       * 
+       * @param contentType a string specifying the desired mimetype for the content stream.
+       * @returns a Stream whose mimetype matches \a contentType,
+       *          if available, or \c NIL.
+       * @since AT-SPI 1.8.0
+       */
+    ContentStream getStream (in string contentType);
+
+      /**
+       * Get a URI pointing to the content of the specified type, if such a URI
+       * can be obtained.  Not all streamable content providers have URI representations.
+       *
+       * @param contentType a string specifying the desired mimetype for the content stream.
+       * If NULL, then a URI for the default content type will be returned, if available.
+       *
+       * @returns a string which constitutes a URI for a stream of the specified
+       * content type, or NULL if no such URI can be obtained.
+       */
+    string getURI (in string contentType);
     /**
      * \cond
      * unImplemented:
     /**
      * \cond
      * unImplemented:
@@ -117,8 +189,7 @@ module Accessibility {
      */
     void unImplemented ();
     void unImplemented2 ();
      */
     void unImplemented ();
     void unImplemented2 ();
-    void unImplemented3 ();
-    void unImplemented4 ();
       /** \endcond */
   };
       /** \endcond */
   };
+
 };
 };
index df66141..51c4579 100644 (file)
 /* A pointer to our parent object class */
 static GObjectClass *spi_streamable_parent_class;
 
 /* A pointer to our parent object class */
 static GObjectClass *spi_streamable_parent_class;
 
+#define SPI_CONTENT_STREAM_TYPE            (spi_content_stream_get_type ())
+#define SPI_CONTENT_STREAM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPI_CONTENT_STREAM_TYPE, SpiContentStream))
+#define SPI_CONTENT_STREAM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), SPI_CONTENT_STREAM_TYPE, SpiContentStreamClass))
+#define SPI_IS_CONTENT_STREAM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPI_CONTENT_STREAM_TYPE))
+#define SPI_IS_CONTENT_STREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPI_CONTENT_STREAM_TYPE))
+
+typedef struct _SpiContentStream SpiContentStream;
+typedef struct _SpiContentStreamClass SpiContentStreamClass;
+
+struct _SpiContentStream {
+  BonoboObject parent;
+  GIOChannel *gio;
+};
+
+struct _SpiContentStreamClass {
+  BonoboObjectClass parent_class;
+  POA_Accessibility_ContentStream__epv epv;
+};
+
+GType        spi_content_stream_get_type (void);
+
+static SpiContentStream*
+spi_content_stream_new (GIOChannel *gio)
+{
+  SpiContentStream *new_stream = g_object_new (SPI_CONTENT_STREAM_TYPE, NULL);
+  new_stream->gio = gio;
+  return new_stream;
+}
+
+static void
+spi_content_stream_dispose (GObject *o)
+{
+    if (SPI_IS_CONTENT_STREAM (o))
+    {
+       SpiContentStream *stream = SPI_CONTENT_STREAM (o);
+       if (stream->gio) g_io_channel_unref (stream->gio);
+    }
+}
+
+static CORBA_long
+impl_content_stream_seek (PortableServer_Servant servant,
+                         const CORBA_long offset, 
+                         const Accessibility_ContentStream_SeekType whence,
+                         CORBA_Environment *ev)
+{
+  SpiContentStream *stream = SPI_CONTENT_STREAM (bonobo_object_from_servant(servant));
+  if (stream && stream->gio)
+  {
+      GError *err;
+      GSeekType seektype = G_SEEK_SET;
+      switch (whence) {
+         case Accessibility_ContentStream_SEEK_CURRENT:
+             seektype = G_SEEK_CUR;
+             break;
+         case Accessibility_ContentStream_SEEK_END:
+             seektype = G_SEEK_END;
+             break;
+      }
+      if (g_io_channel_seek_position (stream->gio, (gint64) offset, 
+                                    seektype, &err) == G_IO_STATUS_NORMAL)
+         return offset;
+      else
+         return -1;
+  }
+  else
+      return -1;
+}
+
+static CORBA_long
+impl_content_stream_read (PortableServer_Servant servant,
+                         const CORBA_long count, 
+                         Accessibility_ContentStream_iobuf** buffer,
+                         CORBA_Environment *ev)
+{
+  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;
+      /* read the giochannel and determine the actual bytes read...*/
+      if (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);
+
+      if (status == G_IO_STATUS_NORMAL || status == G_IO_STATUS_EOF)
+      {
+         *buffer = Bonobo_Stream_iobuf__alloc ();
+         CORBA_sequence_set_release (*buffer, TRUE);
+
+         (*buffer)->_buffer = CORBA_sequence_CORBA_octet_allocbuf (realcount);
+         (*buffer)->_length = realcount;
+      
+         memcpy ((*buffer)->_buffer, gbuf, realcount);  
+      }
+
+      g_free (gbuf);
+  }
+
+  return realcount;
+}
+
+static void
+impl_content_stream_close (PortableServer_Servant servant, 
+                          CORBA_Environment *ev)
+{
+    GIOStatus status;
+    GError *err;
+    SpiContentStream *stream = SPI_CONTENT_STREAM (bonobo_object_from_servant(servant));
+    if (stream && stream->gio) status = g_io_channel_shutdown (stream->gio, TRUE, &err);
+    if (err) g_free (err);
+}
+
+static void
+spi_content_stream_class_init (SpiContentStreamClass *klass)
+{
+  POA_Accessibility_ContentStream__epv *epv = &klass->epv;
+  GObjectClass * object_class = (GObjectClass *) klass;
+
+  epv->seek = impl_content_stream_seek;
+  epv->read = impl_content_stream_read;
+  epv->close = impl_content_stream_close;
+
+  object_class->dispose = spi_content_stream_dispose;
+}
+
+
+static void
+spi_content_stream_init (SpiContentStream *stream)
+{
+}
+
+
+BONOBO_TYPE_FUNC_FULL (SpiContentStream,
+                      Accessibility_ContentStream,
+                      BONOBO_TYPE_OBJECT,
+                      spi_content_stream)
+
 static AtkStreamableContent *
 get_streamable_from_servant (PortableServer_Servant servant)
 {
 static AtkStreamableContent *
 get_streamable_from_servant (PortableServer_Servant servant)
 {
@@ -90,6 +230,45 @@ impl_accessibility_streamable_get_content (PortableServer_Servant servant,
   return stream;
 }
 
   return stream;
 }
 
+/*
+ * CORBA Accessibility::StreamableContent::getStream method implementation
+ */
+static Accessibility_ContentStream
+impl_accessibility_streamable_get_stream (PortableServer_Servant servant,
+                                          const CORBA_char * content_type,
+                                          CORBA_Environment     *ev)
+{
+  SpiContentStream *stream;
+  AtkStreamableContent *streamable = get_streamable_from_servant (servant);
+  GIOChannel *gio;
+
+  g_return_val_if_fail (streamable != NULL, NULL);
+
+  gio = atk_streamable_content_get_stream (streamable, content_type);
+
+  stream = spi_content_stream_new (gio); 
+
+  return bonobo_object_dup_ref (BONOBO_OBJREF (stream), ev);
+}
+
+/*
+ * CORBA Accessibility::StreamableContent::getURI method implementation
+ */
+static CORBA_string
+impl_accessibility_streamable_get_uri (PortableServer_Servant servant,
+                                          const CORBA_char * content_type,
+                                          CORBA_Environment     *ev)
+{
+  gchar *uri;
+  AtkStreamableContent *streamable = get_streamable_from_servant (servant);
+
+  g_return_val_if_fail (streamable != NULL, NULL);
+
+  uri = atk_streamable_content_get_uri (streamable, content_type);
+
+  return (uri != NULL ? CORBA_string_dup (uri) : CORBA_string_dup (""));
+}
+
 static void
 spi_streamable_class_init (SpiStreamableClass *klass)
 {
 static void
 spi_streamable_class_init (SpiStreamableClass *klass)
 {
@@ -98,6 +277,8 @@ spi_streamable_class_init (SpiStreamableClass *klass)
 
         epv->getContentTypes = impl_accessibility_streamable_get_content_types;
         epv->getContent = impl_accessibility_streamable_get_content;
 
         epv->getContentTypes = impl_accessibility_streamable_get_content_types;
         epv->getContent = impl_accessibility_streamable_get_content;
+       epv->getStream = impl_accessibility_streamable_get_stream;
+       epv->getURI = impl_accessibility_streamable_get_uri;
 }
 
 static void
 }
 
 static void