+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.
#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 {
- Bonobo_Stream stream;
+ Accessibility_ContentStream stream;
gchar *mimetype;
};
}
static CORBA_long
-accessible_bonobo_stream_client_seek (const Bonobo_Stream stream,
+accessible_content_stream_client_seek (const Accessibility_ContentStream stream,
CORBA_long offset,
- Bonobo_Stream_SeekType seek_type,
+ Accessibility_ContentStream_SeekType seek_type,
CORBA_Environment *opt_ev)
{
CORBA_Environment *ev, temp_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;
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)
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,
long int offset,
AccessibleStreamableContentSeekType seek_type)
{
- Bonobo_Stream stream;
+ Accessibility_ContentStream stream;
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)
{
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:
- bonobo_seek_type = Bonobo_Stream_SeekEnd;
+ content_seek_type = Accessibility_ContentStream_SEEK_END;
break;
case SPI_STREAM_SEEK_CUR:
default:
- bonobo_seek_type = Bonobo_Stream_SeekCur;
+ content_seek_type = Accessibility_ContentStream_SEEK_CURRENT;
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);
}
}
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)
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)
{
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
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 ();
/**
+ * \n DEPRECATED, use getStream instead.
+ * getContent:
* Retrieve this object's content, in a format appropriate to a
* requested mimetype.
*
*/
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:
*/
void unImplemented ();
void unImplemented2 ();
- void unImplemented3 ();
- void unImplemented4 ();
/** \endcond */
};
+
};
/* 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)
{
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)
{
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