source: trunk/third/bonobo/bonobo/bonobo-stream-client.c @ 16750

Revision 16750, 7.4 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r16749, which included commits to RCS files with non-trunk default branches.
Line 
1/**
2 * gnome-stream-client.c: Helper routines to access a Bonobo_Stream CORBA object
3 *
4 * Authors:
5 *   Nat Friedman    (nat@nat.org)
6 *   Miguel de Icaza (miguel@kernel.org).
7 *   Michael Meekss  (michael@helixcode.com)
8 *
9 * Copyright 1999,2000 Helix Code, Inc.
10 */
11#include <config.h>
12
13#include <bonobo/Bonobo.h>
14#include <bonobo/bonobo-object.h>
15#include <bonobo/bonobo-exception.h>
16#include <bonobo-stream-client.h>
17
18#define CORBA_BLOCK_SIZE 65536
19
20/**
21 * bonobo_stream_client_write:
22 * @stream: A CORBA Object reference to a Bonobo_Stream
23 * @buffer: the buffer to write
24 * @size: number of bytes to write
25 * @ev: a CORBA environment to return status information.
26 *
27 * This is a helper routine to write @size bytes from @buffer to the
28 * @stream.  It will continue to write bytes until a fatal error
29 * occurs. It works around serious problems in ORBit's handling of
30 * sequences, and makes for nicer, saner protocol usage for
31 * transfering huge chunks of data.
32 */
33void
34bonobo_stream_client_write (const Bonobo_Stream stream,
35                            const void *buffer, const size_t size,
36                            CORBA_Environment *ev)
37{
38        Bonobo_Stream_iobuf *buf;
39        size_t               pos;
40        guint8              *mem = (guint8 *)buffer;
41
42        if (size == 0)
43                return;
44
45        g_return_if_fail (ev != NULL);
46       
47        if (buffer == NULL || stream == CORBA_OBJECT_NIL)
48                goto bad_param;
49
50        buf = Bonobo_Stream_iobuf__alloc ();
51        if (!buf)
52                goto alloc_error;
53
54        for (pos = 0; pos < size;) {
55                buf->_buffer = (mem + pos);
56                buf->_length = (pos + CORBA_BLOCK_SIZE < size) ?
57                        CORBA_BLOCK_SIZE : size - pos;
58                buf->_maximum = buf->_length;
59
60                Bonobo_Stream_write (stream, buf, ev);
61                if (BONOBO_EX (ev)) {
62                        CORBA_free (buf);
63                        return;
64                }
65                pos += buf->_length;
66        }
67
68        CORBA_free (buf);
69        return;
70
71 alloc_error:
72        CORBA_exception_set_system (ev, ex_CORBA_NO_MEMORY,
73                                    CORBA_COMPLETED_NO);
74        return;
75
76 bad_param:
77        CORBA_exception_set_system (ev, ex_CORBA_BAD_PARAM,
78                                    CORBA_COMPLETED_NO);
79        return;
80}
81
82/**
83 * bonobo_stream_client_write_string:
84 * @stream: A CORBA object reference to a #Bonobo_Stream.
85 * @str: A string.
86 * @terminate: Whether or not to write the \0 at the end of the
87 * string.
88 * @ev: A pointer to a #CORBA_Environment
89 *
90 * This is a helper routine to write the string in @str to @stream.
91 * If @terminate is TRUE, a NULL character will be written out at the
92 * end of the string.  This function will not return until the entire
93 * string has been written out, unless an exception is raised.  See
94 * also bonobo_stream_client_write(). Continues writing until finished
95 * or a fatal exception occurs.
96 *
97 */
98void
99bonobo_stream_client_write_string (const Bonobo_Stream stream, const char *str,
100                                   gboolean terminate, CORBA_Environment *ev)
101{
102        size_t total_length;
103
104        g_return_if_fail (ev != NULL);
105        g_return_if_fail (str != NULL);
106
107        total_length = strlen (str) + (terminate ? 1 : 0);
108
109        bonobo_stream_client_write (stream, str, total_length, ev);
110}
111
112/**
113 * bonobo_stream_client_printf:
114 * @stream: A CORBA object reference to a #Bonobo_Stream.
115 * @terminate: Whether or not to null-terminate the string when it is
116 * written out to the stream.
117 * @ev: A CORBA_Environment pointer.
118 * @fmt: The printf format string.
119 *
120 * Processes @fmt and the arguments which follow it to produce a
121 * string.  Writes this string out to @stream.  This function will not
122 * return until the entire string is written out, unless an exception
123 * is raised.  See also bonobo_stream_client_write_string() and
124 * bonobo_stream_client_write().
125 */
126void
127bonobo_stream_client_printf (const Bonobo_Stream stream, const gboolean terminate,
128                             CORBA_Environment *ev, const char *fmt, ...)
129{
130        va_list      args;
131        char        *str;
132
133        g_return_if_fail (fmt != NULL);
134
135        va_start (args, fmt);
136        str = g_strdup_vprintf (fmt, args);
137        va_end (args);
138
139        bonobo_stream_client_write_string (stream, str, terminate, ev);
140
141        g_free (str);
142}
143
144/**
145 * bonobo_stream_client_read_string:
146 * @stream: The #Bonobo_Stream from which the string will be read.
147 * @str: The string pointer in which the string will be stored.
148 * @ev: A pointer to a #CORBA_Environment.
149 *
150 * Reads a NULL-terminated string from @stream and stores it in a
151 * newly-allocated string in @str.
152 *
153 * Returns: The number of bytes read, or -1 if an error occurs.
154 * If an exception occurs, @ev will contain the exception.
155 */
156CORBA_long
157bonobo_stream_client_read_string (const Bonobo_Stream stream, char **str,
158                                  CORBA_Environment *ev)
159{
160        Bonobo_Stream_iobuf *buffer;
161        GString             *gstr;
162        gboolean             all;
163
164        gstr = g_string_sized_new (16);
165
166        for (all = FALSE; !all; ) {
167
168                Bonobo_Stream_read (stream, 1,
169                                    &buffer, ev);
170
171                if (BONOBO_EX (ev))
172                        break;
173
174                else if (buffer->_length == 0 ||
175                         buffer->_buffer [0] == '\0')
176                        all = TRUE;
177               
178                else {
179                        g_string_append_c (gstr, buffer->_buffer [0]);
180                        CORBA_free (buffer);
181                }
182        }
183
184        if (BONOBO_EX (ev)) {
185                *str = NULL;
186                g_string_free (gstr, TRUE);
187
188                return -1;
189        } else {
190                CORBA_long l;
191
192                l    = gstr->len;
193                *str = gstr->str;
194                g_string_free (gstr, FALSE);
195
196                return l;
197        }
198}
199
200/**
201 * bonobo_stream_client_get_length:
202 * @stream: The stream.
203 * @ev: Exception environment
204 *
205 *   Does the grunt work to get the length of a stream,
206 * returns -1 if the length is not available. Returns -1
207 * on exception.
208 *
209 * Return value: Length or -1
210 **/
211CORBA_long
212bonobo_stream_client_get_length (const Bonobo_Stream stream,
213                                 CORBA_Environment  *ev)
214{
215        CORBA_long len;
216        Bonobo_StorageInfo *info;
217
218        g_return_val_if_fail (ev != NULL, -1);
219
220        info = Bonobo_Stream_getInfo (stream, Bonobo_FIELD_SIZE, ev);
221
222        if (BONOBO_EX (ev) || !info)
223                return -1;
224
225        len = info->size;
226
227        CORBA_free (info);
228       
229        return len;
230}
231
232/**
233 * bonobo_stream_client_read:
234 * @stream: A CORBA Object reference to a Bonobo_Stream
235 * @size: number of bytes to read or -1 for whole stream.
236 * @length_read: if non NULL will be set to the length read
237 * @ev: a CORBA environment to return status information.
238 *
239 * This is a helper routine to read @size bytes from the @stream into
240 * a freshly g_ allocated buffer which is returned. Whilst this
241 * routine may seem pointless; it reads the stream in small chunks
242 * avoiding possibly massive alloca's inside ORBit's stub/skel code.
243 *
244 * Returns NULL on any sort of failure & 0 size read.
245 */
246guint8 *
247bonobo_stream_client_read (const Bonobo_Stream stream,
248                           const size_t        size,
249                           CORBA_long         *length_read,
250                           CORBA_Environment  *ev)
251{
252        size_t  pos;
253        guint8 *mem;
254        size_t  length;
255
256        g_return_val_if_fail (ev != NULL, NULL);
257
258        if (length_read)
259                *length_read = size;
260
261        length = size;
262
263        if (length == -1) {
264                length = bonobo_stream_client_get_length (stream, ev);
265                if (BONOBO_EX (ev) || length == -1) {
266                        g_warning ("Exception getting length / FIXME: print "
267                                   "stream doesn't support length determination");
268                        return NULL;
269                }
270        }
271
272        *length_read = length;
273
274        if (length == 0)
275                return NULL;
276
277        mem = g_malloc (length);
278        if (!mem) {
279                CORBA_exception_set_system (ev, ex_CORBA_NO_MEMORY,
280                                            CORBA_COMPLETED_NO);
281                return NULL;
282        }
283       
284        for (pos = 0; pos < length;) {
285                Bonobo_Stream_iobuf *buf;
286                CORBA_long           len;
287
288                len = (pos + CORBA_BLOCK_SIZE < length) ?
289                        CORBA_BLOCK_SIZE : length - pos;
290
291                Bonobo_Stream_read (stream, len, &buf, ev);
292
293                if (BONOBO_EX (ev) || !buf)
294                        goto io_error;
295
296                if (buf->_length > 0) {
297                        memcpy (mem + pos, buf->_buffer, buf->_length);
298                        pos += buf->_length;
299                } else {
300                        g_warning ("Buffer length %d", buf->_length);
301                        goto io_error;
302                }
303                CORBA_free (buf);
304        }
305
306        return mem;
307
308 io_error:
309        return NULL;
310}
Note: See TracBrowser for help on using the repository browser.