1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * gsf-input-bonobo.c: bonobo based input
5 * Copyright (C) 2002-2003 Jon K Hellan (hellan@acm.org)
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of version 2.1 of the GNU Lesser General Public
9 * License as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
22 #include <gsf-config.h>
23 #include <gsf-gnome/gsf-input-bonobo.h>
24 #include <gsf/gsf-input-impl.h>
25 #include <gsf/gsf-impl-utils.h>
26 #include <gsf-gnome/gsf-shared-bonobo-stream.h>
27 #include <bonobo/bonobo-persist-stream.h>
28 #include <bonobo/bonobo-exception.h>
31 /* FIXME: Should make CORBA environment available to caller somehow. */
32 struct _GsfInputBonobo {
34 GsfSharedBonoboStream *shared;
41 GsfInputClass input_class;
42 } GsfInputBonoboClass;
45 gib_synch_shared_ptr (GsfInputBonobo *binput)
50 if (binput->shared == NULL)
52 if (binput->pos == (gsf_off_t) binput->shared->pos)
55 CORBA_exception_init (&ev);
56 new_pos = (CORBA_long) binput->pos;
57 Bonobo_Stream_seek (binput->shared->stream, new_pos,
58 Bonobo_Stream_SeekSet, &ev);
59 if (BONOBO_EX (&ev)) {
60 g_warning ("%s", bonobo_exception_get_text (&ev));
61 CORBA_exception_free (&ev);
64 binput->shared->pos = new_pos;
70 * gsf_input_bonobo_new :
71 * @stream : Bonobo stream
72 * @err : optionally %NULL.
74 * Returns: a new input object or %NULL.
77 gsf_input_bonobo_new (Bonobo_Stream const stream, GError **err)
79 GsfInputBonobo *input;
80 Bonobo_StorageInfo *info;
86 *err = g_error_new (gsf_input_error_id (), 0,
91 CORBA_exception_init (&ev);
92 /* <ICK!> info->size doesn't work */
93 size = Bonobo_Stream_seek (stream, 0, Bonobo_Stream_SeekEnd, &ev);
94 if (BONOBO_EX (&ev)) {
96 *err = g_error_new (gsf_input_error_id (), 0,
98 "Error seeking to get stream size",
99 bonobo_exception_get_text (&ev));
100 CORBA_exception_free (&ev);
103 Bonobo_Stream_seek (stream, 0, Bonobo_Stream_SeekSet, &ev);
104 if (BONOBO_EX (&ev)) {
106 *err = g_error_new (gsf_input_error_id (), 0,
108 "Error seeking to get stream size",
109 bonobo_exception_get_text (&ev));
110 CORBA_exception_free (&ev);
115 info = Bonobo_Stream_getInfo (stream, 0, &ev);
116 if (BONOBO_EX (&ev)) {
118 *err = g_error_new (gsf_input_error_id (), 0,
120 "Error getting stream info",
121 bonobo_exception_get_text (&ev));
122 CORBA_exception_free (&ev);
126 input = g_object_new (GSF_INPUT_BONOBO_TYPE, NULL);
127 if (G_UNLIKELY (NULL == input)) {
132 input->shared = gsf_shared_bonobo_stream_new (stream);
135 gsf_input_set_size (GSF_INPUT (input), (gsf_off_t) size);
136 gsf_input_set_name (GSF_INPUT (input), info->name);
140 return GSF_INPUT (input);
144 gsf_input_bonobo_finalize (GObject *obj)
146 GObjectClass *parent_class;
147 GsfInputBonobo *input = (GsfInputBonobo *)obj;
150 g_object_unref (G_OBJECT (input->shared));
151 input->shared = NULL;
157 parent_class = g_type_class_peek (GSF_INPUT_TYPE);
158 if (parent_class && parent_class->finalize)
159 parent_class->finalize (obj);
163 gsf_input_bonobo_dup (GsfInput *src_input, GError **err)
165 GsfInputBonobo const *src = (GsfInputBonobo *)src_input;
166 GsfInputBonobo *dst = g_object_new (GSF_INPUT_BONOBO_TYPE, NULL);
167 if (G_UNLIKELY (NULL == dst)) return NULL;
171 dst->shared = src->shared;
172 g_object_ref (G_OBJECT (dst->shared));
174 return GSF_INPUT (dst);
177 static guint8 const *
178 gsf_input_bonobo_read (GsfInput *input, size_t num_bytes,
181 GsfInputBonobo *binput = GSF_INPUT_BONOBO (input);
182 CORBA_unsigned_long num_read;
183 Bonobo_Stream_iobuf *bsibuf;
184 CORBA_Environment ev;
186 g_return_val_if_fail (binput != NULL, NULL);
187 g_return_val_if_fail (binput->shared != NULL, NULL);
188 g_return_val_if_fail (binput->shared->stream != NULL, NULL);
190 if (buffer == NULL) {
191 if (binput->buf_size < num_bytes) {
192 binput->buf_size = num_bytes;
193 g_free (binput->buf);
194 binput->buf = g_new (guint8, binput->buf_size);
196 buffer = binput->buf;
199 if (gib_synch_shared_ptr (binput) != 0)
202 CORBA_exception_init (&ev);
203 Bonobo_Stream_read (binput->shared->stream, (CORBA_long) num_bytes,
205 if (BONOBO_EX (&ev)) {
206 g_warning ("%s", bonobo_exception_get_text (&ev));
209 memcpy (buffer, bsibuf->_buffer, bsibuf->_length);
210 num_read = bsibuf->_length;
213 if ((size_t) num_read == num_bytes) {
216 g_warning ("Only read %ld bytes, asked for %ld",
217 (long)num_read, (long)num_bytes);
223 gsf_input_bonobo_seek (GsfInput *input, gsf_off_t offset, GSeekType whence)
225 GsfInputBonobo *binput = GSF_INPUT_BONOBO (input);
226 Bonobo_Stream_SeekType bwhence;
227 CORBA_long pos, coffset;
228 CORBA_Environment ev;
230 g_return_val_if_fail (binput != NULL, TRUE);
231 g_return_val_if_fail (binput->shared != NULL, TRUE);
232 g_return_val_if_fail (binput->shared->stream != NULL, TRUE);
234 if (whence == G_SEEK_CUR) {
235 if (gib_synch_shared_ptr (binput) != 0)
241 bwhence = Bonobo_Stream_SeekSet;
244 bwhence = Bonobo_Stream_SeekCur;
247 bwhence = Bonobo_Stream_SeekEnd;
255 if ((gsf_off_t) coffset != offset) { /* Check for overflow */
256 g_warning ("offset too large for Bonobo_Stream_seek");
259 CORBA_exception_init (&ev);
260 pos = Bonobo_Stream_seek
261 (binput->shared->stream, coffset, bwhence, &ev);
262 if (BONOBO_EX (&ev)) {
263 g_warning ("%s", bonobo_exception_get_text (&ev));
266 binput->shared->pos = pos;
267 binput->pos = (gsf_off_t) pos;
273 gsf_input_bonobo_init (GObject *obj)
275 GsfInputBonobo *binput = GSF_INPUT_BONOBO (obj);
277 binput->shared = NULL;
279 binput->buf_size = 0;
283 gsf_input_bonobo_class_init (GObjectClass *gobject_class)
285 GsfInputClass *input_class = GSF_INPUT_CLASS (gobject_class);
287 gobject_class->finalize = gsf_input_bonobo_finalize;
288 input_class->Dup = gsf_input_bonobo_dup;
289 input_class->Read = gsf_input_bonobo_read;
290 input_class->Seek = gsf_input_bonobo_seek;
293 GSF_CLASS (GsfInputBonobo, gsf_input_bonobo,
294 gsf_input_bonobo_class_init, gsf_input_bonobo_init, GSF_INPUT_TYPE)