/src/glib/glib/giochannel.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* GLIB - Library of useful routines for C programming |
2 | | * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald |
3 | | * |
4 | | * giochannel.c: IO Channel abstraction |
5 | | * Copyright 1998 Owen Taylor |
6 | | * |
7 | | * This library is free software; you can redistribute it and/or |
8 | | * modify it under the terms of the GNU Lesser General Public |
9 | | * License as published by the Free Software Foundation; either |
10 | | * version 2.1 of the License, or (at your option) any later version. |
11 | | * |
12 | | * This library is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | | * Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public |
18 | | * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
19 | | */ |
20 | | |
21 | | /* |
22 | | * Modified by the GLib Team and others 1997-2000. See the AUTHORS |
23 | | * file for a list of people on the GLib Team. See the ChangeLog |
24 | | * files for a list of changes. These files are distributed with |
25 | | * GLib at ftp://ftp.gtk.org/pub/gtk/. |
26 | | */ |
27 | | |
28 | | /* |
29 | | * MT safe |
30 | | */ |
31 | | |
32 | | #include "config.h" |
33 | | |
34 | | #include <string.h> |
35 | | #include <errno.h> |
36 | | |
37 | | #include "giochannel.h" |
38 | | |
39 | | #include "gstrfuncs.h" |
40 | | #include "gtestutils.h" |
41 | | #include "glibintl.h" |
42 | | |
43 | | |
44 | | /** |
45 | | * SECTION:iochannels |
46 | | * @title: IO Channels |
47 | | * @short_description: portable support for using files, pipes and sockets |
48 | | * @see_also: g_io_add_watch(), g_io_add_watch_full(), g_source_remove(), |
49 | | * #GMainLoop |
50 | | * |
51 | | * The #GIOChannel data type aims to provide a portable method for |
52 | | * using file descriptors, pipes, and sockets, and integrating them |
53 | | * into the [main event loop][glib-The-Main-Event-Loop]. Currently, |
54 | | * full support is available on UNIX platforms, support for Windows |
55 | | * is only partially complete. |
56 | | * |
57 | | * To create a new #GIOChannel on UNIX systems use |
58 | | * g_io_channel_unix_new(). This works for plain file descriptors, |
59 | | * pipes and sockets. Alternatively, a channel can be created for a |
60 | | * file in a system independent manner using g_io_channel_new_file(). |
61 | | * |
62 | | * Once a #GIOChannel has been created, it can be used in a generic |
63 | | * manner with the functions g_io_channel_read_chars(), |
64 | | * g_io_channel_write_chars(), g_io_channel_seek_position(), and |
65 | | * g_io_channel_shutdown(). |
66 | | * |
67 | | * To add a #GIOChannel to the [main event loop][glib-The-Main-Event-Loop], |
68 | | * use g_io_add_watch() or g_io_add_watch_full(). Here you specify which |
69 | | * events you are interested in on the #GIOChannel, and provide a |
70 | | * function to be called whenever these events occur. |
71 | | * |
72 | | * #GIOChannel instances are created with an initial reference count of 1. |
73 | | * g_io_channel_ref() and g_io_channel_unref() can be used to |
74 | | * increment or decrement the reference count respectively. When the |
75 | | * reference count falls to 0, the #GIOChannel is freed. (Though it |
76 | | * isn't closed automatically, unless it was created using |
77 | | * g_io_channel_new_file().) Using g_io_add_watch() or |
78 | | * g_io_add_watch_full() increments a channel's reference count. |
79 | | * |
80 | | * The new functions g_io_channel_read_chars(), |
81 | | * g_io_channel_read_line(), g_io_channel_read_line_string(), |
82 | | * g_io_channel_read_to_end(), g_io_channel_write_chars(), |
83 | | * g_io_channel_seek_position(), and g_io_channel_flush() should not be |
84 | | * mixed with the deprecated functions g_io_channel_read(), |
85 | | * g_io_channel_write(), and g_io_channel_seek() on the same channel. |
86 | | **/ |
87 | | |
88 | | /** |
89 | | * GIOChannel: |
90 | | * |
91 | | * A data structure representing an IO Channel. The fields should be |
92 | | * considered private and should only be accessed with the following |
93 | | * functions. |
94 | | **/ |
95 | | |
96 | | /** |
97 | | * GIOFuncs: |
98 | | * @io_read: reads raw bytes from the channel. This is called from |
99 | | * various functions such as g_io_channel_read_chars() to |
100 | | * read raw bytes from the channel. Encoding and buffering |
101 | | * issues are dealt with at a higher level. |
102 | | * @io_write: writes raw bytes to the channel. This is called from |
103 | | * various functions such as g_io_channel_write_chars() to |
104 | | * write raw bytes to the channel. Encoding and buffering |
105 | | * issues are dealt with at a higher level. |
106 | | * @io_seek: (optional) seeks the channel. This is called from |
107 | | * g_io_channel_seek() on channels that support it. |
108 | | * @io_close: closes the channel. This is called from |
109 | | * g_io_channel_close() after flushing the buffers. |
110 | | * @io_create_watch: creates a watch on the channel. This call |
111 | | * corresponds directly to g_io_create_watch(). |
112 | | * @io_free: called from g_io_channel_unref() when the channel needs to |
113 | | * be freed. This function must free the memory associated |
114 | | * with the channel, including freeing the #GIOChannel |
115 | | * structure itself. The channel buffers have been flushed |
116 | | * and possibly @io_close has been called by the time this |
117 | | * function is called. |
118 | | * @io_set_flags: sets the #GIOFlags on the channel. This is called |
119 | | * from g_io_channel_set_flags() with all flags except |
120 | | * for %G_IO_FLAG_APPEND and %G_IO_FLAG_NONBLOCK masked |
121 | | * out. |
122 | | * @io_get_flags: gets the #GIOFlags for the channel. This function |
123 | | * need only return the %G_IO_FLAG_APPEND and |
124 | | * %G_IO_FLAG_NONBLOCK flags; g_io_channel_get_flags() |
125 | | * automatically adds the others as appropriate. |
126 | | * |
127 | | * A table of functions used to handle different types of #GIOChannel |
128 | | * in a generic way. |
129 | | **/ |
130 | | |
131 | | /** |
132 | | * GIOStatus: |
133 | | * @G_IO_STATUS_ERROR: An error occurred. |
134 | | * @G_IO_STATUS_NORMAL: Success. |
135 | | * @G_IO_STATUS_EOF: End of file. |
136 | | * @G_IO_STATUS_AGAIN: Resource temporarily unavailable. |
137 | | * |
138 | | * Statuses returned by most of the #GIOFuncs functions. |
139 | | **/ |
140 | | |
141 | | /** |
142 | | * GIOError: |
143 | | * @G_IO_ERROR_NONE: no error |
144 | | * @G_IO_ERROR_AGAIN: an EAGAIN error occurred |
145 | | * @G_IO_ERROR_INVAL: an EINVAL error occurred |
146 | | * @G_IO_ERROR_UNKNOWN: another error occurred |
147 | | * |
148 | | * #GIOError is only used by the deprecated functions |
149 | | * g_io_channel_read(), g_io_channel_write(), and g_io_channel_seek(). |
150 | | **/ |
151 | | |
152 | 0 | #define G_IO_NICE_BUF_SIZE 1024 |
153 | | |
154 | | /* This needs to be as wide as the largest character in any possible encoding */ |
155 | 0 | #define MAX_CHAR_SIZE 10 |
156 | | |
157 | | /* Some simplifying macros, which reduce the need to worry whether the |
158 | | * buffers have been allocated. These also make USE_BUF () an lvalue, |
159 | | * which is used in g_io_channel_read_to_end (). |
160 | | */ |
161 | 0 | #define USE_BUF(channel) ((channel)->encoding ? (channel)->encoded_read_buf \ |
162 | 0 | : (channel)->read_buf) |
163 | 0 | #define BUF_LEN(string) ((string) ? (string)->len : 0) |
164 | | |
165 | | static GIOError g_io_error_get_from_g_error (GIOStatus status, |
166 | | GError *err); |
167 | | static void g_io_channel_purge (GIOChannel *channel); |
168 | | static GIOStatus g_io_channel_fill_buffer (GIOChannel *channel, |
169 | | GError **err); |
170 | | static GIOStatus g_io_channel_read_line_backend (GIOChannel *channel, |
171 | | gsize *length, |
172 | | gsize *terminator_pos, |
173 | | GError **error); |
174 | | |
175 | | /** |
176 | | * g_io_channel_init: |
177 | | * @channel: a #GIOChannel |
178 | | * |
179 | | * Initializes a #GIOChannel struct. |
180 | | * |
181 | | * This is called by each of the above functions when creating a |
182 | | * #GIOChannel, and so is not often needed by the application |
183 | | * programmer (unless you are creating a new type of #GIOChannel). |
184 | | */ |
185 | | void |
186 | | g_io_channel_init (GIOChannel *channel) |
187 | 0 | { |
188 | 0 | channel->ref_count = 1; |
189 | 0 | channel->encoding = g_strdup ("UTF-8"); |
190 | 0 | channel->line_term = NULL; |
191 | 0 | channel->line_term_len = 0; |
192 | 0 | channel->buf_size = G_IO_NICE_BUF_SIZE; |
193 | 0 | channel->read_cd = (GIConv) -1; |
194 | 0 | channel->write_cd = (GIConv) -1; |
195 | 0 | channel->read_buf = NULL; /* Lazy allocate buffers */ |
196 | 0 | channel->encoded_read_buf = NULL; |
197 | 0 | channel->write_buf = NULL; |
198 | 0 | channel->partial_write_buf[0] = '\0'; |
199 | 0 | channel->use_buffer = TRUE; |
200 | 0 | channel->do_encode = FALSE; |
201 | 0 | channel->close_on_unref = FALSE; |
202 | 0 | } |
203 | | |
204 | | /** |
205 | | * g_io_channel_ref: |
206 | | * @channel: a #GIOChannel |
207 | | * |
208 | | * Increments the reference count of a #GIOChannel. |
209 | | * |
210 | | * Returns: the @channel that was passed in (since 2.6) |
211 | | */ |
212 | | GIOChannel * |
213 | | g_io_channel_ref (GIOChannel *channel) |
214 | 0 | { |
215 | 0 | g_return_val_if_fail (channel != NULL, NULL); |
216 | | |
217 | 0 | g_atomic_int_inc (&channel->ref_count); |
218 | |
|
219 | 0 | return channel; |
220 | 0 | } |
221 | | |
222 | | /** |
223 | | * g_io_channel_unref: |
224 | | * @channel: a #GIOChannel |
225 | | * |
226 | | * Decrements the reference count of a #GIOChannel. |
227 | | */ |
228 | | void |
229 | | g_io_channel_unref (GIOChannel *channel) |
230 | 0 | { |
231 | 0 | gboolean is_zero; |
232 | |
|
233 | 0 | g_return_if_fail (channel != NULL); |
234 | | |
235 | 0 | is_zero = g_atomic_int_dec_and_test (&channel->ref_count); |
236 | |
|
237 | 0 | if (G_UNLIKELY (is_zero)) |
238 | 0 | { |
239 | 0 | if (channel->close_on_unref) |
240 | 0 | g_io_channel_shutdown (channel, TRUE, NULL); |
241 | 0 | else |
242 | 0 | g_io_channel_purge (channel); |
243 | 0 | g_free (channel->encoding); |
244 | 0 | if (channel->read_cd != (GIConv) -1) |
245 | 0 | g_iconv_close (channel->read_cd); |
246 | 0 | if (channel->write_cd != (GIConv) -1) |
247 | 0 | g_iconv_close (channel->write_cd); |
248 | 0 | g_free (channel->line_term); |
249 | 0 | if (channel->read_buf) |
250 | 0 | g_string_free (channel->read_buf, TRUE); |
251 | 0 | if (channel->write_buf) |
252 | 0 | g_string_free (channel->write_buf, TRUE); |
253 | 0 | if (channel->encoded_read_buf) |
254 | 0 | g_string_free (channel->encoded_read_buf, TRUE); |
255 | 0 | channel->funcs->io_free (channel); |
256 | 0 | } |
257 | 0 | } |
258 | | |
259 | | static GIOError |
260 | | g_io_error_get_from_g_error (GIOStatus status, |
261 | | GError *err) |
262 | 0 | { |
263 | 0 | switch (status) |
264 | 0 | { |
265 | 0 | case G_IO_STATUS_NORMAL: |
266 | 0 | case G_IO_STATUS_EOF: |
267 | 0 | return G_IO_ERROR_NONE; |
268 | 0 | case G_IO_STATUS_AGAIN: |
269 | 0 | return G_IO_ERROR_AGAIN; |
270 | 0 | case G_IO_STATUS_ERROR: |
271 | 0 | g_return_val_if_fail (err != NULL, G_IO_ERROR_UNKNOWN); |
272 | | |
273 | 0 | if (err->domain != G_IO_CHANNEL_ERROR) |
274 | 0 | return G_IO_ERROR_UNKNOWN; |
275 | 0 | switch (err->code) |
276 | 0 | { |
277 | 0 | case G_IO_CHANNEL_ERROR_INVAL: |
278 | 0 | return G_IO_ERROR_INVAL; |
279 | 0 | default: |
280 | 0 | return G_IO_ERROR_UNKNOWN; |
281 | 0 | } |
282 | 0 | default: |
283 | 0 | g_assert_not_reached (); |
284 | 0 | } |
285 | 0 | } |
286 | | |
287 | | /** |
288 | | * g_io_channel_read: |
289 | | * @channel: a #GIOChannel |
290 | | * @buf: a buffer to read the data into (which should be at least |
291 | | * count bytes long) |
292 | | * @count: the number of bytes to read from the #GIOChannel |
293 | | * @bytes_read: returns the number of bytes actually read |
294 | | * |
295 | | * Reads data from a #GIOChannel. |
296 | | * |
297 | | * Returns: %G_IO_ERROR_NONE if the operation was successful. |
298 | | * |
299 | | * Deprecated:2.2: Use g_io_channel_read_chars() instead. |
300 | | **/ |
301 | | GIOError |
302 | | g_io_channel_read (GIOChannel *channel, |
303 | | gchar *buf, |
304 | | gsize count, |
305 | | gsize *bytes_read) |
306 | 0 | { |
307 | 0 | GError *err = NULL; |
308 | 0 | GIOError error; |
309 | 0 | GIOStatus status; |
310 | |
|
311 | 0 | g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN); |
312 | 0 | g_return_val_if_fail (bytes_read != NULL, G_IO_ERROR_UNKNOWN); |
313 | | |
314 | 0 | if (count == 0) |
315 | 0 | { |
316 | 0 | if (bytes_read) |
317 | 0 | *bytes_read = 0; |
318 | 0 | return G_IO_ERROR_NONE; |
319 | 0 | } |
320 | | |
321 | 0 | g_return_val_if_fail (buf != NULL, G_IO_ERROR_UNKNOWN); |
322 | | |
323 | 0 | status = channel->funcs->io_read (channel, buf, count, bytes_read, &err); |
324 | |
|
325 | 0 | error = g_io_error_get_from_g_error (status, err); |
326 | |
|
327 | 0 | if (err) |
328 | 0 | g_error_free (err); |
329 | |
|
330 | 0 | return error; |
331 | 0 | } |
332 | | |
333 | | /** |
334 | | * g_io_channel_write: |
335 | | * @channel: a #GIOChannel |
336 | | * @buf: the buffer containing the data to write |
337 | | * @count: the number of bytes to write |
338 | | * @bytes_written: the number of bytes actually written |
339 | | * |
340 | | * Writes data to a #GIOChannel. |
341 | | * |
342 | | * Returns: %G_IO_ERROR_NONE if the operation was successful. |
343 | | * |
344 | | * Deprecated:2.2: Use g_io_channel_write_chars() instead. |
345 | | **/ |
346 | | GIOError |
347 | | g_io_channel_write (GIOChannel *channel, |
348 | | const gchar *buf, |
349 | | gsize count, |
350 | | gsize *bytes_written) |
351 | 0 | { |
352 | 0 | GError *err = NULL; |
353 | 0 | GIOError error; |
354 | 0 | GIOStatus status; |
355 | |
|
356 | 0 | g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN); |
357 | 0 | g_return_val_if_fail (bytes_written != NULL, G_IO_ERROR_UNKNOWN); |
358 | | |
359 | 0 | status = channel->funcs->io_write (channel, buf, count, bytes_written, &err); |
360 | |
|
361 | 0 | error = g_io_error_get_from_g_error (status, err); |
362 | |
|
363 | 0 | if (err) |
364 | 0 | g_error_free (err); |
365 | |
|
366 | 0 | return error; |
367 | 0 | } |
368 | | |
369 | | /** |
370 | | * g_io_channel_seek: |
371 | | * @channel: a #GIOChannel |
372 | | * @offset: an offset, in bytes, which is added to the position specified |
373 | | * by @type |
374 | | * @type: the position in the file, which can be %G_SEEK_CUR (the current |
375 | | * position), %G_SEEK_SET (the start of the file), or %G_SEEK_END |
376 | | * (the end of the file) |
377 | | * |
378 | | * Sets the current position in the #GIOChannel, similar to the standard |
379 | | * library function fseek(). |
380 | | * |
381 | | * Returns: %G_IO_ERROR_NONE if the operation was successful. |
382 | | * |
383 | | * Deprecated:2.2: Use g_io_channel_seek_position() instead. |
384 | | **/ |
385 | | GIOError |
386 | | g_io_channel_seek (GIOChannel *channel, |
387 | | gint64 offset, |
388 | | GSeekType type) |
389 | 0 | { |
390 | 0 | GError *err = NULL; |
391 | 0 | GIOError error; |
392 | 0 | GIOStatus status; |
393 | |
|
394 | 0 | g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN); |
395 | 0 | g_return_val_if_fail (channel->is_seekable, G_IO_ERROR_UNKNOWN); |
396 | | |
397 | 0 | switch (type) |
398 | 0 | { |
399 | 0 | case G_SEEK_CUR: |
400 | 0 | case G_SEEK_SET: |
401 | 0 | case G_SEEK_END: |
402 | 0 | break; |
403 | 0 | default: |
404 | 0 | g_warning ("g_io_channel_seek: unknown seek type"); |
405 | 0 | return G_IO_ERROR_UNKNOWN; |
406 | 0 | } |
407 | | |
408 | 0 | status = channel->funcs->io_seek (channel, offset, type, &err); |
409 | |
|
410 | 0 | error = g_io_error_get_from_g_error (status, err); |
411 | |
|
412 | 0 | if (err) |
413 | 0 | g_error_free (err); |
414 | |
|
415 | 0 | return error; |
416 | 0 | } |
417 | | |
418 | | /* The function g_io_channel_new_file() is prototyped in both |
419 | | * giounix.c and giowin32.c, so we stick its documentation here. |
420 | | */ |
421 | | |
422 | | /** |
423 | | * g_io_channel_new_file: |
424 | | * @filename: (type filename): A string containing the name of a file |
425 | | * @mode: One of "r", "w", "a", "r+", "w+", "a+". These have |
426 | | * the same meaning as in fopen() |
427 | | * @error: A location to return an error of type %G_FILE_ERROR |
428 | | * |
429 | | * Open a file @filename as a #GIOChannel using mode @mode. This |
430 | | * channel will be closed when the last reference to it is dropped, |
431 | | * so there is no need to call g_io_channel_close() (though doing |
432 | | * so will not cause problems, as long as no attempt is made to |
433 | | * access the channel after it is closed). |
434 | | * |
435 | | * Returns: A #GIOChannel on success, %NULL on failure. |
436 | | **/ |
437 | | |
438 | | /** |
439 | | * g_io_channel_close: |
440 | | * @channel: A #GIOChannel |
441 | | * |
442 | | * Close an IO channel. Any pending data to be written will be |
443 | | * flushed, ignoring errors. The channel will not be freed until the |
444 | | * last reference is dropped using g_io_channel_unref(). |
445 | | * |
446 | | * Deprecated:2.2: Use g_io_channel_shutdown() instead. |
447 | | **/ |
448 | | void |
449 | | g_io_channel_close (GIOChannel *channel) |
450 | 0 | { |
451 | 0 | GError *err = NULL; |
452 | | |
453 | 0 | g_return_if_fail (channel != NULL); |
454 | | |
455 | 0 | g_io_channel_purge (channel); |
456 | |
|
457 | 0 | channel->funcs->io_close (channel, &err); |
458 | |
|
459 | 0 | if (err) |
460 | 0 | { /* No way to return the error */ |
461 | 0 | g_warning ("Error closing channel: %s", err->message); |
462 | 0 | g_error_free (err); |
463 | 0 | } |
464 | | |
465 | 0 | channel->close_on_unref = FALSE; /* Because we already did */ |
466 | 0 | channel->is_readable = FALSE; |
467 | 0 | channel->is_writeable = FALSE; |
468 | 0 | channel->is_seekable = FALSE; |
469 | 0 | } |
470 | | |
471 | | /** |
472 | | * g_io_channel_shutdown: |
473 | | * @channel: a #GIOChannel |
474 | | * @flush: if %TRUE, flush pending |
475 | | * @err: location to store a #GIOChannelError |
476 | | * |
477 | | * Close an IO channel. Any pending data to be written will be |
478 | | * flushed if @flush is %TRUE. The channel will not be freed until the |
479 | | * last reference is dropped using g_io_channel_unref(). |
480 | | * |
481 | | * Returns: the status of the operation. |
482 | | **/ |
483 | | GIOStatus |
484 | | g_io_channel_shutdown (GIOChannel *channel, |
485 | | gboolean flush, |
486 | | GError **err) |
487 | 0 | { |
488 | 0 | GIOStatus status, result; |
489 | 0 | GError *tmperr = NULL; |
490 | | |
491 | 0 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
492 | 0 | g_return_val_if_fail (err == NULL || *err == NULL, G_IO_STATUS_ERROR); |
493 | | |
494 | 0 | if (channel->write_buf && channel->write_buf->len > 0) |
495 | 0 | { |
496 | 0 | if (flush) |
497 | 0 | { |
498 | 0 | GIOFlags flags; |
499 | | |
500 | | /* Set the channel to blocking, to avoid a busy loop |
501 | | */ |
502 | 0 | flags = g_io_channel_get_flags (channel); |
503 | | /* Ignore any errors here, they're irrelevant */ |
504 | 0 | g_io_channel_set_flags (channel, flags & ~G_IO_FLAG_NONBLOCK, NULL); |
505 | |
|
506 | 0 | result = g_io_channel_flush (channel, &tmperr); |
507 | 0 | } |
508 | 0 | else |
509 | 0 | result = G_IO_STATUS_NORMAL; |
510 | |
|
511 | 0 | g_string_truncate(channel->write_buf, 0); |
512 | 0 | } |
513 | 0 | else |
514 | 0 | result = G_IO_STATUS_NORMAL; |
515 | |
|
516 | 0 | if (channel->partial_write_buf[0] != '\0') |
517 | 0 | { |
518 | 0 | if (flush) |
519 | 0 | g_warning ("Partial character at end of write buffer not flushed."); |
520 | 0 | channel->partial_write_buf[0] = '\0'; |
521 | 0 | } |
522 | |
|
523 | 0 | status = channel->funcs->io_close (channel, err); |
524 | |
|
525 | 0 | channel->close_on_unref = FALSE; /* Because we already did */ |
526 | 0 | channel->is_readable = FALSE; |
527 | 0 | channel->is_writeable = FALSE; |
528 | 0 | channel->is_seekable = FALSE; |
529 | |
|
530 | 0 | if (status != G_IO_STATUS_NORMAL) |
531 | 0 | { |
532 | 0 | g_clear_error (&tmperr); |
533 | 0 | return status; |
534 | 0 | } |
535 | 0 | else if (result != G_IO_STATUS_NORMAL) |
536 | 0 | { |
537 | 0 | g_propagate_error (err, tmperr); |
538 | 0 | return result; |
539 | 0 | } |
540 | 0 | else |
541 | 0 | return G_IO_STATUS_NORMAL; |
542 | 0 | } |
543 | | |
544 | | /* This function is used for the final flush on close or unref */ |
545 | | static void |
546 | | g_io_channel_purge (GIOChannel *channel) |
547 | 0 | { |
548 | 0 | GError *err = NULL; |
549 | 0 | GIOStatus status G_GNUC_UNUSED; |
550 | |
|
551 | 0 | g_return_if_fail (channel != NULL); |
552 | | |
553 | 0 | if (channel->write_buf && channel->write_buf->len > 0) |
554 | 0 | { |
555 | 0 | GIOFlags flags; |
556 | | |
557 | | /* Set the channel to blocking, to avoid a busy loop |
558 | | */ |
559 | 0 | flags = g_io_channel_get_flags (channel); |
560 | 0 | g_io_channel_set_flags (channel, flags & ~G_IO_FLAG_NONBLOCK, NULL); |
561 | |
|
562 | 0 | status = g_io_channel_flush (channel, &err); |
563 | |
|
564 | 0 | if (err) |
565 | 0 | { /* No way to return the error */ |
566 | 0 | g_warning ("Error flushing string: %s", err->message); |
567 | 0 | g_error_free (err); |
568 | 0 | } |
569 | 0 | } |
570 | | |
571 | | /* Flush these in case anyone tries to close without unrefing */ |
572 | |
|
573 | 0 | if (channel->read_buf) |
574 | 0 | g_string_truncate (channel->read_buf, 0); |
575 | 0 | if (channel->write_buf) |
576 | 0 | g_string_truncate (channel->write_buf, 0); |
577 | 0 | if (channel->encoding) |
578 | 0 | { |
579 | 0 | if (channel->encoded_read_buf) |
580 | 0 | g_string_truncate (channel->encoded_read_buf, 0); |
581 | |
|
582 | 0 | if (channel->partial_write_buf[0] != '\0') |
583 | 0 | { |
584 | 0 | g_warning ("Partial character at end of write buffer not flushed."); |
585 | 0 | channel->partial_write_buf[0] = '\0'; |
586 | 0 | } |
587 | 0 | } |
588 | 0 | } |
589 | | |
590 | | /** |
591 | | * g_io_create_watch: |
592 | | * @channel: a #GIOChannel to watch |
593 | | * @condition: conditions to watch for |
594 | | * |
595 | | * Creates a #GSource that's dispatched when @condition is met for the |
596 | | * given @channel. For example, if condition is #G_IO_IN, the source will |
597 | | * be dispatched when there's data available for reading. |
598 | | * |
599 | | * The callback function invoked by the #GSource should be added with |
600 | | * g_source_set_callback(), but it has type #GIOFunc (not #GSourceFunc). |
601 | | * |
602 | | * g_io_add_watch() is a simpler interface to this same functionality, for |
603 | | * the case where you want to add the source to the default main loop context |
604 | | * at the default priority. |
605 | | * |
606 | | * On Windows, polling a #GSource created to watch a channel for a socket |
607 | | * puts the socket in non-blocking mode. This is a side-effect of the |
608 | | * implementation and unavoidable. |
609 | | * |
610 | | * Returns: a new #GSource |
611 | | */ |
612 | | GSource * |
613 | | g_io_create_watch (GIOChannel *channel, |
614 | | GIOCondition condition) |
615 | 0 | { |
616 | 0 | g_return_val_if_fail (channel != NULL, NULL); |
617 | | |
618 | 0 | return channel->funcs->io_create_watch (channel, condition); |
619 | 0 | } |
620 | | |
621 | | /** |
622 | | * g_io_add_watch_full: (rename-to g_io_add_watch) |
623 | | * @channel: a #GIOChannel |
624 | | * @priority: the priority of the #GIOChannel source |
625 | | * @condition: the condition to watch for |
626 | | * @func: the function to call when the condition is satisfied |
627 | | * @user_data: user data to pass to @func |
628 | | * @notify: the function to call when the source is removed |
629 | | * |
630 | | * Adds the #GIOChannel into the default main loop context |
631 | | * with the given priority. |
632 | | * |
633 | | * This internally creates a main loop source using g_io_create_watch() |
634 | | * and attaches it to the main loop context with g_source_attach(). |
635 | | * You can do these steps manually if you need greater control. |
636 | | * |
637 | | * Returns: the event source id |
638 | | */ |
639 | | guint |
640 | | g_io_add_watch_full (GIOChannel *channel, |
641 | | gint priority, |
642 | | GIOCondition condition, |
643 | | GIOFunc func, |
644 | | gpointer user_data, |
645 | | GDestroyNotify notify) |
646 | 0 | { |
647 | 0 | GSource *source; |
648 | 0 | guint id; |
649 | | |
650 | 0 | g_return_val_if_fail (channel != NULL, 0); |
651 | | |
652 | 0 | source = g_io_create_watch (channel, condition); |
653 | |
|
654 | 0 | if (priority != G_PRIORITY_DEFAULT) |
655 | 0 | g_source_set_priority (source, priority); |
656 | 0 | g_source_set_callback (source, (GSourceFunc)func, user_data, notify); |
657 | |
|
658 | 0 | id = g_source_attach (source, NULL); |
659 | 0 | g_source_unref (source); |
660 | |
|
661 | 0 | return id; |
662 | 0 | } |
663 | | |
664 | | /** |
665 | | * g_io_add_watch: |
666 | | * @channel: a #GIOChannel |
667 | | * @condition: the condition to watch for |
668 | | * @func: the function to call when the condition is satisfied |
669 | | * @user_data: user data to pass to @func |
670 | | * |
671 | | * Adds the #GIOChannel into the default main loop context |
672 | | * with the default priority. |
673 | | * |
674 | | * Returns: the event source id |
675 | | */ |
676 | | /** |
677 | | * GIOFunc: |
678 | | * @source: the #GIOChannel event source |
679 | | * @condition: the condition which has been satisfied |
680 | | * @data: user data set in g_io_add_watch() or g_io_add_watch_full() |
681 | | * |
682 | | * Specifies the type of function passed to g_io_add_watch() or |
683 | | * g_io_add_watch_full(), which is called when the requested condition |
684 | | * on a #GIOChannel is satisfied. |
685 | | * |
686 | | * Returns: the function should return %FALSE if the event source |
687 | | * should be removed |
688 | | **/ |
689 | | /** |
690 | | * GIOCondition: |
691 | | * @G_IO_IN: There is data to read. |
692 | | * @G_IO_OUT: Data can be written (without blocking). |
693 | | * @G_IO_PRI: There is urgent data to read. |
694 | | * @G_IO_ERR: Error condition. |
695 | | * @G_IO_HUP: Hung up (the connection has been broken, usually for |
696 | | * pipes and sockets). |
697 | | * @G_IO_NVAL: Invalid request. The file descriptor is not open. |
698 | | * |
699 | | * A bitwise combination representing a condition to watch for on an |
700 | | * event source. |
701 | | **/ |
702 | | guint |
703 | | g_io_add_watch (GIOChannel *channel, |
704 | | GIOCondition condition, |
705 | | GIOFunc func, |
706 | | gpointer user_data) |
707 | 0 | { |
708 | 0 | return g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, condition, func, user_data, NULL); |
709 | 0 | } |
710 | | |
711 | | /** |
712 | | * g_io_channel_get_buffer_condition: |
713 | | * @channel: A #GIOChannel |
714 | | * |
715 | | * This function returns a #GIOCondition depending on whether there |
716 | | * is data to be read/space to write data in the internal buffers in |
717 | | * the #GIOChannel. Only the flags %G_IO_IN and %G_IO_OUT may be set. |
718 | | * |
719 | | * Returns: A #GIOCondition |
720 | | **/ |
721 | | GIOCondition |
722 | | g_io_channel_get_buffer_condition (GIOChannel *channel) |
723 | 0 | { |
724 | 0 | GIOCondition condition = 0; |
725 | |
|
726 | 0 | if (channel->encoding) |
727 | 0 | { |
728 | 0 | if (channel->encoded_read_buf && (channel->encoded_read_buf->len > 0)) |
729 | 0 | condition |= G_IO_IN; /* Only return if we have full characters */ |
730 | 0 | } |
731 | 0 | else |
732 | 0 | { |
733 | 0 | if (channel->read_buf && (channel->read_buf->len > 0)) |
734 | 0 | condition |= G_IO_IN; |
735 | 0 | } |
736 | |
|
737 | 0 | if (channel->write_buf && (channel->write_buf->len < channel->buf_size)) |
738 | 0 | condition |= G_IO_OUT; |
739 | |
|
740 | 0 | return condition; |
741 | 0 | } |
742 | | |
743 | | /** |
744 | | * g_io_channel_error_from_errno: |
745 | | * @en: an `errno` error number, e.g. `EINVAL` |
746 | | * |
747 | | * Converts an `errno` error number to a #GIOChannelError. |
748 | | * |
749 | | * Returns: a #GIOChannelError error number, e.g. |
750 | | * %G_IO_CHANNEL_ERROR_INVAL. |
751 | | **/ |
752 | | GIOChannelError |
753 | | g_io_channel_error_from_errno (gint en) |
754 | 0 | { |
755 | 0 | #ifdef EAGAIN |
756 | 0 | g_return_val_if_fail (en != EAGAIN, G_IO_CHANNEL_ERROR_FAILED); |
757 | 0 | #endif |
758 | | |
759 | 0 | switch (en) |
760 | 0 | { |
761 | 0 | #ifdef EBADF |
762 | 0 | case EBADF: |
763 | 0 | g_warning ("Invalid file descriptor."); |
764 | 0 | return G_IO_CHANNEL_ERROR_FAILED; |
765 | 0 | #endif |
766 | | |
767 | 0 | #ifdef EFAULT |
768 | 0 | case EFAULT: |
769 | 0 | g_warning ("Buffer outside valid address space."); |
770 | 0 | return G_IO_CHANNEL_ERROR_FAILED; |
771 | 0 | #endif |
772 | | |
773 | 0 | #ifdef EFBIG |
774 | 0 | case EFBIG: |
775 | 0 | return G_IO_CHANNEL_ERROR_FBIG; |
776 | 0 | #endif |
777 | | |
778 | 0 | #ifdef EINTR |
779 | | /* In general, we should catch EINTR before we get here, |
780 | | * but close() is allowed to return EINTR by POSIX, so |
781 | | * we need to catch it here; EINTR from close() is |
782 | | * unrecoverable, because it's undefined whether |
783 | | * the fd was actually closed or not, so we just return |
784 | | * a generic error code. |
785 | | */ |
786 | 0 | case EINTR: |
787 | 0 | return G_IO_CHANNEL_ERROR_FAILED; |
788 | 0 | #endif |
789 | | |
790 | 0 | #ifdef EINVAL |
791 | 0 | case EINVAL: |
792 | 0 | return G_IO_CHANNEL_ERROR_INVAL; |
793 | 0 | #endif |
794 | | |
795 | 0 | #ifdef EIO |
796 | 0 | case EIO: |
797 | 0 | return G_IO_CHANNEL_ERROR_IO; |
798 | 0 | #endif |
799 | | |
800 | 0 | #ifdef EISDIR |
801 | 0 | case EISDIR: |
802 | 0 | return G_IO_CHANNEL_ERROR_ISDIR; |
803 | 0 | #endif |
804 | | |
805 | 0 | #ifdef ENOSPC |
806 | 0 | case ENOSPC: |
807 | 0 | return G_IO_CHANNEL_ERROR_NOSPC; |
808 | 0 | #endif |
809 | | |
810 | 0 | #ifdef ENXIO |
811 | 0 | case ENXIO: |
812 | 0 | return G_IO_CHANNEL_ERROR_NXIO; |
813 | 0 | #endif |
814 | | |
815 | 0 | #ifdef EOVERFLOW |
816 | 0 | #if EOVERFLOW != EFBIG |
817 | 0 | case EOVERFLOW: |
818 | 0 | return G_IO_CHANNEL_ERROR_OVERFLOW; |
819 | 0 | #endif |
820 | 0 | #endif |
821 | | |
822 | 0 | #ifdef EPIPE |
823 | 0 | case EPIPE: |
824 | 0 | return G_IO_CHANNEL_ERROR_PIPE; |
825 | 0 | #endif |
826 | | |
827 | 0 | default: |
828 | 0 | return G_IO_CHANNEL_ERROR_FAILED; |
829 | 0 | } |
830 | 0 | } |
831 | | |
832 | | /** |
833 | | * g_io_channel_set_buffer_size: |
834 | | * @channel: a #GIOChannel |
835 | | * @size: the size of the buffer, or 0 to let GLib pick a good size |
836 | | * |
837 | | * Sets the buffer size. |
838 | | **/ |
839 | | void |
840 | | g_io_channel_set_buffer_size (GIOChannel *channel, |
841 | | gsize size) |
842 | 0 | { |
843 | 0 | g_return_if_fail (channel != NULL); |
844 | | |
845 | 0 | if (size == 0) |
846 | 0 | size = G_IO_NICE_BUF_SIZE; |
847 | |
|
848 | 0 | if (size < MAX_CHAR_SIZE) |
849 | 0 | size = MAX_CHAR_SIZE; |
850 | |
|
851 | 0 | channel->buf_size = size; |
852 | 0 | } |
853 | | |
854 | | /** |
855 | | * g_io_channel_get_buffer_size: |
856 | | * @channel: a #GIOChannel |
857 | | * |
858 | | * Gets the buffer size. |
859 | | * |
860 | | * Returns: the size of the buffer. |
861 | | **/ |
862 | | gsize |
863 | | g_io_channel_get_buffer_size (GIOChannel *channel) |
864 | 0 | { |
865 | 0 | g_return_val_if_fail (channel != NULL, 0); |
866 | | |
867 | 0 | return channel->buf_size; |
868 | 0 | } |
869 | | |
870 | | /** |
871 | | * g_io_channel_set_line_term: |
872 | | * @channel: a #GIOChannel |
873 | | * @line_term: (nullable): The line termination string. Use %NULL for |
874 | | * autodetect. Autodetection breaks on "\n", "\r\n", "\r", "\0", |
875 | | * and the Unicode paragraph separator. Autodetection should not be |
876 | | * used for anything other than file-based channels. |
877 | | * @length: The length of the termination string. If -1 is passed, the |
878 | | * string is assumed to be nul-terminated. This option allows |
879 | | * termination strings with embedded nuls. |
880 | | * |
881 | | * This sets the string that #GIOChannel uses to determine |
882 | | * where in the file a line break occurs. |
883 | | **/ |
884 | | void |
885 | | g_io_channel_set_line_term (GIOChannel *channel, |
886 | | const gchar *line_term, |
887 | | gint length) |
888 | 0 | { |
889 | 0 | guint length_unsigned; |
890 | |
|
891 | 0 | g_return_if_fail (channel != NULL); |
892 | 0 | g_return_if_fail (line_term == NULL || length != 0); /* Disallow "" */ |
893 | | |
894 | 0 | if (line_term == NULL) |
895 | 0 | length_unsigned = 0; |
896 | 0 | else if (length >= 0) |
897 | 0 | length_unsigned = (guint) length; |
898 | 0 | else |
899 | 0 | { |
900 | | /* FIXME: We’re constrained by line_term_len being a guint here */ |
901 | 0 | gsize length_size = strlen (line_term); |
902 | 0 | g_return_if_fail (length_size <= G_MAXUINT); |
903 | 0 | length_unsigned = (guint) length_size; |
904 | 0 | } |
905 | | |
906 | 0 | g_free (channel->line_term); |
907 | 0 | channel->line_term = line_term ? g_memdup2 (line_term, length_unsigned) : NULL; |
908 | 0 | channel->line_term_len = length_unsigned; |
909 | 0 | } |
910 | | |
911 | | /** |
912 | | * g_io_channel_get_line_term: |
913 | | * @channel: a #GIOChannel |
914 | | * @length: a location to return the length of the line terminator |
915 | | * |
916 | | * This returns the string that #GIOChannel uses to determine |
917 | | * where in the file a line break occurs. A value of %NULL |
918 | | * indicates autodetection. |
919 | | * |
920 | | * Returns: The line termination string. This value |
921 | | * is owned by GLib and must not be freed. |
922 | | **/ |
923 | | const gchar * |
924 | | g_io_channel_get_line_term (GIOChannel *channel, |
925 | | gint *length) |
926 | 0 | { |
927 | 0 | g_return_val_if_fail (channel != NULL, NULL); |
928 | | |
929 | 0 | if (length) |
930 | 0 | *length = channel->line_term_len; |
931 | |
|
932 | 0 | return channel->line_term; |
933 | 0 | } |
934 | | |
935 | | /** |
936 | | * g_io_channel_set_flags: |
937 | | * @channel: a #GIOChannel |
938 | | * @flags: the flags to set on the IO channel |
939 | | * @error: A location to return an error of type #GIOChannelError |
940 | | * |
941 | | * Sets the (writeable) flags in @channel to (@flags & %G_IO_FLAG_SET_MASK). |
942 | | * |
943 | | * Returns: the status of the operation. |
944 | | **/ |
945 | | /** |
946 | | * GIOFlags: |
947 | | * @G_IO_FLAG_APPEND: turns on append mode, corresponds to %O_APPEND |
948 | | * (see the documentation of the UNIX open() syscall) |
949 | | * @G_IO_FLAG_NONBLOCK: turns on nonblocking mode, corresponds to |
950 | | * %O_NONBLOCK/%O_NDELAY (see the documentation of the UNIX open() |
951 | | * syscall) |
952 | | * @G_IO_FLAG_IS_READABLE: indicates that the io channel is readable. |
953 | | * This flag cannot be changed. |
954 | | * @G_IO_FLAG_IS_WRITABLE: indicates that the io channel is writable. |
955 | | * This flag cannot be changed. |
956 | | * @G_IO_FLAG_IS_WRITEABLE: a misspelled version of @G_IO_FLAG_IS_WRITABLE |
957 | | * that existed before the spelling was fixed in GLib 2.30. It is kept |
958 | | * here for compatibility reasons. Deprecated since 2.30 |
959 | | * @G_IO_FLAG_IS_SEEKABLE: indicates that the io channel is seekable, |
960 | | * i.e. that g_io_channel_seek_position() can be used on it. |
961 | | * This flag cannot be changed. |
962 | | * @G_IO_FLAG_MASK: the mask that specifies all the valid flags. |
963 | | * @G_IO_FLAG_GET_MASK: the mask of the flags that are returned from |
964 | | * g_io_channel_get_flags() |
965 | | * @G_IO_FLAG_SET_MASK: the mask of the flags that the user can modify |
966 | | * with g_io_channel_set_flags() |
967 | | * |
968 | | * Specifies properties of a #GIOChannel. Some of the flags can only be |
969 | | * read with g_io_channel_get_flags(), but not changed with |
970 | | * g_io_channel_set_flags(). |
971 | | */ |
972 | | GIOStatus |
973 | | g_io_channel_set_flags (GIOChannel *channel, |
974 | | GIOFlags flags, |
975 | | GError **error) |
976 | 0 | { |
977 | 0 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
978 | 0 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
979 | 0 | G_IO_STATUS_ERROR); |
980 | | |
981 | 0 | return (*channel->funcs->io_set_flags) (channel, |
982 | 0 | flags & G_IO_FLAG_SET_MASK, |
983 | 0 | error); |
984 | 0 | } |
985 | | |
986 | | /** |
987 | | * g_io_channel_get_flags: |
988 | | * @channel: a #GIOChannel |
989 | | * |
990 | | * Gets the current flags for a #GIOChannel, including read-only |
991 | | * flags such as %G_IO_FLAG_IS_READABLE. |
992 | | * |
993 | | * The values of the flags %G_IO_FLAG_IS_READABLE and %G_IO_FLAG_IS_WRITABLE |
994 | | * are cached for internal use by the channel when it is created. |
995 | | * If they should change at some later point (e.g. partial shutdown |
996 | | * of a socket with the UNIX shutdown() function), the user |
997 | | * should immediately call g_io_channel_get_flags() to update |
998 | | * the internal values of these flags. |
999 | | * |
1000 | | * Returns: the flags which are set on the channel |
1001 | | **/ |
1002 | | GIOFlags |
1003 | | g_io_channel_get_flags (GIOChannel *channel) |
1004 | 0 | { |
1005 | 0 | GIOFlags flags; |
1006 | |
|
1007 | 0 | g_return_val_if_fail (channel != NULL, 0); |
1008 | | |
1009 | 0 | flags = (* channel->funcs->io_get_flags) (channel); |
1010 | | |
1011 | | /* Cross implementation code */ |
1012 | |
|
1013 | 0 | if (channel->is_seekable) |
1014 | 0 | flags |= G_IO_FLAG_IS_SEEKABLE; |
1015 | 0 | if (channel->is_readable) |
1016 | 0 | flags |= G_IO_FLAG_IS_READABLE; |
1017 | 0 | if (channel->is_writeable) |
1018 | 0 | flags |= G_IO_FLAG_IS_WRITABLE; |
1019 | |
|
1020 | 0 | return flags; |
1021 | 0 | } |
1022 | | |
1023 | | /** |
1024 | | * g_io_channel_set_close_on_unref: |
1025 | | * @channel: a #GIOChannel |
1026 | | * @do_close: Whether to close the channel on the final unref of |
1027 | | * the GIOChannel data structure. |
1028 | | * |
1029 | | * Whether to close the channel on the final unref of the #GIOChannel |
1030 | | * data structure. The default value of this is %TRUE for channels |
1031 | | * created by g_io_channel_new_file (), and %FALSE for all other channels. |
1032 | | * |
1033 | | * Setting this flag to %TRUE for a channel you have already closed |
1034 | | * can cause problems when the final reference to the #GIOChannel is dropped. |
1035 | | **/ |
1036 | | void |
1037 | | g_io_channel_set_close_on_unref (GIOChannel *channel, |
1038 | | gboolean do_close) |
1039 | 0 | { |
1040 | 0 | g_return_if_fail (channel != NULL); |
1041 | | |
1042 | 0 | channel->close_on_unref = do_close; |
1043 | 0 | } |
1044 | | |
1045 | | /** |
1046 | | * g_io_channel_get_close_on_unref: |
1047 | | * @channel: a #GIOChannel. |
1048 | | * |
1049 | | * Returns whether the file/socket/whatever associated with @channel |
1050 | | * will be closed when @channel receives its final unref and is |
1051 | | * destroyed. The default value of this is %TRUE for channels created |
1052 | | * by g_io_channel_new_file (), and %FALSE for all other channels. |
1053 | | * |
1054 | | * Returns: %TRUE if the channel will be closed, %FALSE otherwise. |
1055 | | **/ |
1056 | | gboolean |
1057 | | g_io_channel_get_close_on_unref (GIOChannel *channel) |
1058 | 0 | { |
1059 | 0 | g_return_val_if_fail (channel != NULL, FALSE); |
1060 | | |
1061 | 0 | return channel->close_on_unref; |
1062 | 0 | } |
1063 | | |
1064 | | /** |
1065 | | * g_io_channel_seek_position: |
1066 | | * @channel: a #GIOChannel |
1067 | | * @offset: The offset in bytes from the position specified by @type |
1068 | | * @type: a #GSeekType. The type %G_SEEK_CUR is only allowed in those |
1069 | | * cases where a call to g_io_channel_set_encoding () |
1070 | | * is allowed. See the documentation for |
1071 | | * g_io_channel_set_encoding () for details. |
1072 | | * @error: A location to return an error of type #GIOChannelError |
1073 | | * |
1074 | | * Replacement for g_io_channel_seek() with the new API. |
1075 | | * |
1076 | | * Returns: the status of the operation. |
1077 | | **/ |
1078 | | /** |
1079 | | * GSeekType: |
1080 | | * @G_SEEK_CUR: the current position in the file. |
1081 | | * @G_SEEK_SET: the start of the file. |
1082 | | * @G_SEEK_END: the end of the file. |
1083 | | * |
1084 | | * An enumeration specifying the base position for a |
1085 | | * g_io_channel_seek_position() operation. |
1086 | | **/ |
1087 | | GIOStatus |
1088 | | g_io_channel_seek_position (GIOChannel *channel, |
1089 | | gint64 offset, |
1090 | | GSeekType type, |
1091 | | GError **error) |
1092 | 0 | { |
1093 | 0 | GIOStatus status; |
1094 | | |
1095 | | /* For files, only one of the read and write buffers can contain data. |
1096 | | * For sockets, both can contain data. |
1097 | | */ |
1098 | |
|
1099 | 0 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
1100 | 0 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
1101 | 0 | G_IO_STATUS_ERROR); |
1102 | 0 | g_return_val_if_fail (channel->is_seekable, G_IO_STATUS_ERROR); |
1103 | | |
1104 | 0 | switch (type) |
1105 | 0 | { |
1106 | 0 | case G_SEEK_CUR: /* The user is seeking relative to the head of the buffer */ |
1107 | 0 | if (channel->use_buffer) |
1108 | 0 | { |
1109 | 0 | if (channel->do_encode && channel->encoded_read_buf |
1110 | 0 | && channel->encoded_read_buf->len > 0) |
1111 | 0 | { |
1112 | 0 | g_warning ("Seek type G_SEEK_CUR not allowed for this" |
1113 | 0 | " channel's encoding."); |
1114 | 0 | return G_IO_STATUS_ERROR; |
1115 | 0 | } |
1116 | 0 | if (channel->read_buf) |
1117 | 0 | offset -= channel->read_buf->len; |
1118 | 0 | if (channel->encoded_read_buf) |
1119 | 0 | { |
1120 | 0 | g_assert (channel->encoded_read_buf->len == 0 || !channel->do_encode); |
1121 | | |
1122 | | /* If there's anything here, it's because the encoding is UTF-8, |
1123 | | * so we can just subtract the buffer length, the same as for |
1124 | | * the unencoded data. |
1125 | | */ |
1126 | | |
1127 | 0 | offset -= channel->encoded_read_buf->len; |
1128 | 0 | } |
1129 | 0 | } |
1130 | 0 | break; |
1131 | 0 | case G_SEEK_SET: |
1132 | 0 | case G_SEEK_END: |
1133 | 0 | break; |
1134 | 0 | default: |
1135 | 0 | g_warning ("g_io_channel_seek_position: unknown seek type"); |
1136 | 0 | return G_IO_STATUS_ERROR; |
1137 | 0 | } |
1138 | | |
1139 | 0 | if (channel->use_buffer) |
1140 | 0 | { |
1141 | 0 | status = g_io_channel_flush (channel, error); |
1142 | 0 | if (status != G_IO_STATUS_NORMAL) |
1143 | 0 | return status; |
1144 | 0 | } |
1145 | | |
1146 | 0 | status = channel->funcs->io_seek (channel, offset, type, error); |
1147 | |
|
1148 | 0 | if ((status == G_IO_STATUS_NORMAL) && (channel->use_buffer)) |
1149 | 0 | { |
1150 | 0 | if (channel->read_buf) |
1151 | 0 | g_string_truncate (channel->read_buf, 0); |
1152 | | |
1153 | | /* Conversion state no longer matches position in file */ |
1154 | 0 | if (channel->read_cd != (GIConv) -1) |
1155 | 0 | g_iconv (channel->read_cd, NULL, NULL, NULL, NULL); |
1156 | 0 | if (channel->write_cd != (GIConv) -1) |
1157 | 0 | g_iconv (channel->write_cd, NULL, NULL, NULL, NULL); |
1158 | |
|
1159 | 0 | if (channel->encoded_read_buf) |
1160 | 0 | { |
1161 | 0 | g_assert (channel->encoded_read_buf->len == 0 || !channel->do_encode); |
1162 | 0 | g_string_truncate (channel->encoded_read_buf, 0); |
1163 | 0 | } |
1164 | | |
1165 | 0 | if (channel->partial_write_buf[0] != '\0') |
1166 | 0 | { |
1167 | 0 | g_warning ("Partial character at end of write buffer not flushed."); |
1168 | 0 | channel->partial_write_buf[0] = '\0'; |
1169 | 0 | } |
1170 | 0 | } |
1171 | | |
1172 | 0 | return status; |
1173 | 0 | } |
1174 | | |
1175 | | /** |
1176 | | * g_io_channel_flush: |
1177 | | * @channel: a #GIOChannel |
1178 | | * @error: location to store an error of type #GIOChannelError |
1179 | | * |
1180 | | * Flushes the write buffer for the GIOChannel. |
1181 | | * |
1182 | | * Returns: the status of the operation: One of |
1183 | | * #G_IO_STATUS_NORMAL, #G_IO_STATUS_AGAIN, or |
1184 | | * #G_IO_STATUS_ERROR. |
1185 | | **/ |
1186 | | GIOStatus |
1187 | | g_io_channel_flush (GIOChannel *channel, |
1188 | | GError **error) |
1189 | 0 | { |
1190 | 0 | GIOStatus status; |
1191 | 0 | gsize this_time = 1, bytes_written = 0; |
1192 | |
|
1193 | 0 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
1194 | 0 | g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR); |
1195 | | |
1196 | 0 | if (channel->write_buf == NULL || channel->write_buf->len == 0) |
1197 | 0 | return G_IO_STATUS_NORMAL; |
1198 | | |
1199 | 0 | do |
1200 | 0 | { |
1201 | 0 | g_assert (this_time > 0); |
1202 | | |
1203 | 0 | status = channel->funcs->io_write (channel, |
1204 | 0 | channel->write_buf->str + bytes_written, |
1205 | 0 | channel->write_buf->len - bytes_written, |
1206 | 0 | &this_time, error); |
1207 | 0 | bytes_written += this_time; |
1208 | 0 | } |
1209 | 0 | while ((bytes_written < channel->write_buf->len) |
1210 | 0 | && (status == G_IO_STATUS_NORMAL)); |
1211 | | |
1212 | 0 | g_string_erase (channel->write_buf, 0, bytes_written); |
1213 | |
|
1214 | 0 | return status; |
1215 | 0 | } |
1216 | | |
1217 | | /** |
1218 | | * g_io_channel_set_buffered: |
1219 | | * @channel: a #GIOChannel |
1220 | | * @buffered: whether to set the channel buffered or unbuffered |
1221 | | * |
1222 | | * The buffering state can only be set if the channel's encoding |
1223 | | * is %NULL. For any other encoding, the channel must be buffered. |
1224 | | * |
1225 | | * A buffered channel can only be set unbuffered if the channel's |
1226 | | * internal buffers have been flushed. Newly created channels or |
1227 | | * channels which have returned %G_IO_STATUS_EOF |
1228 | | * not require such a flush. For write-only channels, a call to |
1229 | | * g_io_channel_flush () is sufficient. For all other channels, |
1230 | | * the buffers may be flushed by a call to g_io_channel_seek_position (). |
1231 | | * This includes the possibility of seeking with seek type %G_SEEK_CUR |
1232 | | * and an offset of zero. Note that this means that socket-based |
1233 | | * channels cannot be set unbuffered once they have had data |
1234 | | * read from them. |
1235 | | * |
1236 | | * On unbuffered channels, it is safe to mix read and write |
1237 | | * calls from the new and old APIs, if this is necessary for |
1238 | | * maintaining old code. |
1239 | | * |
1240 | | * The default state of the channel is buffered. |
1241 | | **/ |
1242 | | void |
1243 | | g_io_channel_set_buffered (GIOChannel *channel, |
1244 | | gboolean buffered) |
1245 | 0 | { |
1246 | 0 | g_return_if_fail (channel != NULL); |
1247 | | |
1248 | 0 | if (channel->encoding != NULL) |
1249 | 0 | { |
1250 | 0 | g_warning ("Need to have NULL encoding to set the buffering state of the " |
1251 | 0 | "channel."); |
1252 | 0 | return; |
1253 | 0 | } |
1254 | | |
1255 | 0 | g_return_if_fail (!channel->read_buf || channel->read_buf->len == 0); |
1256 | 0 | g_return_if_fail (!channel->write_buf || channel->write_buf->len == 0); |
1257 | | |
1258 | 0 | channel->use_buffer = buffered; |
1259 | 0 | } |
1260 | | |
1261 | | /** |
1262 | | * g_io_channel_get_buffered: |
1263 | | * @channel: a #GIOChannel |
1264 | | * |
1265 | | * Returns whether @channel is buffered. |
1266 | | * |
1267 | | * Return Value: %TRUE if the @channel is buffered. |
1268 | | **/ |
1269 | | gboolean |
1270 | | g_io_channel_get_buffered (GIOChannel *channel) |
1271 | 0 | { |
1272 | 0 | g_return_val_if_fail (channel != NULL, FALSE); |
1273 | | |
1274 | 0 | return channel->use_buffer; |
1275 | 0 | } |
1276 | | |
1277 | | /** |
1278 | | * g_io_channel_set_encoding: |
1279 | | * @channel: a #GIOChannel |
1280 | | * @encoding: (nullable): the encoding type |
1281 | | * @error: location to store an error of type #GConvertError |
1282 | | * |
1283 | | * Sets the encoding for the input/output of the channel. |
1284 | | * The internal encoding is always UTF-8. The default encoding |
1285 | | * for the external file is UTF-8. |
1286 | | * |
1287 | | * The encoding %NULL is safe to use with binary data. |
1288 | | * |
1289 | | * The encoding can only be set if one of the following conditions |
1290 | | * is true: |
1291 | | * |
1292 | | * - The channel was just created, and has not been written to or read from yet. |
1293 | | * |
1294 | | * - The channel is write-only. |
1295 | | * |
1296 | | * - The channel is a file, and the file pointer was just repositioned |
1297 | | * by a call to g_io_channel_seek_position(). (This flushes all the |
1298 | | * internal buffers.) |
1299 | | * |
1300 | | * - The current encoding is %NULL or UTF-8. |
1301 | | * |
1302 | | * - One of the (new API) read functions has just returned %G_IO_STATUS_EOF |
1303 | | * (or, in the case of g_io_channel_read_to_end(), %G_IO_STATUS_NORMAL). |
1304 | | * |
1305 | | * - One of the functions g_io_channel_read_chars() or |
1306 | | * g_io_channel_read_unichar() has returned %G_IO_STATUS_AGAIN or |
1307 | | * %G_IO_STATUS_ERROR. This may be useful in the case of |
1308 | | * %G_CONVERT_ERROR_ILLEGAL_SEQUENCE. |
1309 | | * Returning one of these statuses from g_io_channel_read_line(), |
1310 | | * g_io_channel_read_line_string(), or g_io_channel_read_to_end() |
1311 | | * does not guarantee that the encoding can be changed. |
1312 | | * |
1313 | | * Channels which do not meet one of the above conditions cannot call |
1314 | | * g_io_channel_seek_position() with an offset of %G_SEEK_CUR, and, if |
1315 | | * they are "seekable", cannot call g_io_channel_write_chars() after |
1316 | | * calling one of the API "read" functions. |
1317 | | * |
1318 | | * Return Value: %G_IO_STATUS_NORMAL if the encoding was successfully set |
1319 | | */ |
1320 | | GIOStatus |
1321 | | g_io_channel_set_encoding (GIOChannel *channel, |
1322 | | const gchar *encoding, |
1323 | | GError **error) |
1324 | 0 | { |
1325 | 0 | GIConv read_cd, write_cd; |
1326 | 0 | #ifndef G_DISABLE_ASSERT |
1327 | 0 | gboolean did_encode; |
1328 | 0 | #endif |
1329 | |
|
1330 | 0 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
1331 | 0 | g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR); |
1332 | | |
1333 | | /* Make sure the encoded buffers are empty */ |
1334 | | |
1335 | 0 | g_return_val_if_fail (!channel->do_encode || !channel->encoded_read_buf || |
1336 | 0 | channel->encoded_read_buf->len == 0, G_IO_STATUS_ERROR); |
1337 | | |
1338 | 0 | if (!channel->use_buffer) |
1339 | 0 | { |
1340 | 0 | g_warning ("Need to set the channel buffered before setting the encoding."); |
1341 | 0 | g_warning ("Assuming this is what you meant and acting accordingly."); |
1342 | |
|
1343 | 0 | channel->use_buffer = TRUE; |
1344 | 0 | } |
1345 | |
|
1346 | 0 | if (channel->partial_write_buf[0] != '\0') |
1347 | 0 | { |
1348 | 0 | g_warning ("Partial character at end of write buffer not flushed."); |
1349 | 0 | channel->partial_write_buf[0] = '\0'; |
1350 | 0 | } |
1351 | |
|
1352 | 0 | #ifndef G_DISABLE_ASSERT |
1353 | 0 | did_encode = channel->do_encode; |
1354 | 0 | #endif |
1355 | |
|
1356 | 0 | if (!encoding || strcmp (encoding, "UTF8") == 0 || strcmp (encoding, "UTF-8") == 0) |
1357 | 0 | { |
1358 | 0 | channel->do_encode = FALSE; |
1359 | 0 | read_cd = write_cd = (GIConv) -1; |
1360 | 0 | } |
1361 | 0 | else |
1362 | 0 | { |
1363 | 0 | gint err = 0; |
1364 | 0 | const gchar *from_enc = NULL, *to_enc = NULL; |
1365 | |
|
1366 | 0 | if (channel->is_readable) |
1367 | 0 | { |
1368 | 0 | read_cd = g_iconv_open ("UTF-8", encoding); |
1369 | |
|
1370 | 0 | if (read_cd == (GIConv) -1) |
1371 | 0 | { |
1372 | 0 | err = errno; |
1373 | 0 | from_enc = encoding; |
1374 | 0 | to_enc = "UTF-8"; |
1375 | 0 | } |
1376 | 0 | } |
1377 | 0 | else |
1378 | 0 | read_cd = (GIConv) -1; |
1379 | |
|
1380 | 0 | if (channel->is_writeable && err == 0) |
1381 | 0 | { |
1382 | 0 | write_cd = g_iconv_open (encoding, "UTF-8"); |
1383 | |
|
1384 | 0 | if (write_cd == (GIConv) -1) |
1385 | 0 | { |
1386 | 0 | err = errno; |
1387 | 0 | from_enc = "UTF-8"; |
1388 | 0 | to_enc = encoding; |
1389 | 0 | } |
1390 | 0 | } |
1391 | 0 | else |
1392 | 0 | write_cd = (GIConv) -1; |
1393 | |
|
1394 | 0 | if (err != 0) |
1395 | 0 | { |
1396 | 0 | g_assert (from_enc); |
1397 | 0 | g_assert (to_enc); |
1398 | | |
1399 | 0 | if (err == EINVAL) |
1400 | 0 | g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION, |
1401 | 0 | _("Conversion from character set “%s” to “%s” is not supported"), |
1402 | 0 | from_enc, to_enc); |
1403 | 0 | else |
1404 | 0 | g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, |
1405 | 0 | _("Could not open converter from “%s” to “%s”: %s"), |
1406 | 0 | from_enc, to_enc, g_strerror (err)); |
1407 | |
|
1408 | 0 | if (read_cd != (GIConv) -1) |
1409 | 0 | g_iconv_close (read_cd); |
1410 | 0 | if (write_cd != (GIConv) -1) |
1411 | 0 | g_iconv_close (write_cd); |
1412 | |
|
1413 | 0 | return G_IO_STATUS_ERROR; |
1414 | 0 | } |
1415 | | |
1416 | 0 | channel->do_encode = TRUE; |
1417 | 0 | } |
1418 | | |
1419 | | /* The encoding is ok, so set the fields in channel */ |
1420 | | |
1421 | 0 | if (channel->read_cd != (GIConv) -1) |
1422 | 0 | g_iconv_close (channel->read_cd); |
1423 | 0 | if (channel->write_cd != (GIConv) -1) |
1424 | 0 | g_iconv_close (channel->write_cd); |
1425 | |
|
1426 | 0 | if (channel->encoded_read_buf && channel->encoded_read_buf->len > 0) |
1427 | 0 | { |
1428 | 0 | g_assert (!did_encode); /* Encoding UTF-8, NULL doesn't use encoded_read_buf */ |
1429 | | |
1430 | | /* This is just validated UTF-8, so we can copy it back into read_buf |
1431 | | * so it can be encoded in whatever the new encoding is. |
1432 | | */ |
1433 | | |
1434 | 0 | g_string_prepend_len (channel->read_buf, channel->encoded_read_buf->str, |
1435 | 0 | channel->encoded_read_buf->len); |
1436 | 0 | g_string_truncate (channel->encoded_read_buf, 0); |
1437 | 0 | } |
1438 | | |
1439 | 0 | channel->read_cd = read_cd; |
1440 | 0 | channel->write_cd = write_cd; |
1441 | |
|
1442 | 0 | g_free (channel->encoding); |
1443 | 0 | channel->encoding = g_strdup (encoding); |
1444 | |
|
1445 | 0 | return G_IO_STATUS_NORMAL; |
1446 | 0 | } |
1447 | | |
1448 | | /** |
1449 | | * g_io_channel_get_encoding: |
1450 | | * @channel: a #GIOChannel |
1451 | | * |
1452 | | * Gets the encoding for the input/output of the channel. |
1453 | | * The internal encoding is always UTF-8. The encoding %NULL |
1454 | | * makes the channel safe for binary data. |
1455 | | * |
1456 | | * Returns: A string containing the encoding, this string is |
1457 | | * owned by GLib and must not be freed. |
1458 | | **/ |
1459 | | const gchar * |
1460 | | g_io_channel_get_encoding (GIOChannel *channel) |
1461 | 0 | { |
1462 | 0 | g_return_val_if_fail (channel != NULL, NULL); |
1463 | | |
1464 | 0 | return channel->encoding; |
1465 | 0 | } |
1466 | | |
1467 | | static GIOStatus |
1468 | | g_io_channel_fill_buffer (GIOChannel *channel, |
1469 | | GError **err) |
1470 | 0 | { |
1471 | 0 | gsize read_size, cur_len, oldlen; |
1472 | 0 | GIOStatus status; |
1473 | |
|
1474 | 0 | if (channel->is_seekable && channel->write_buf && channel->write_buf->len > 0) |
1475 | 0 | { |
1476 | 0 | status = g_io_channel_flush (channel, err); |
1477 | 0 | if (status != G_IO_STATUS_NORMAL) |
1478 | 0 | return status; |
1479 | 0 | } |
1480 | 0 | if (channel->is_seekable && channel->partial_write_buf[0] != '\0') |
1481 | 0 | { |
1482 | 0 | g_warning ("Partial character at end of write buffer not flushed."); |
1483 | 0 | channel->partial_write_buf[0] = '\0'; |
1484 | 0 | } |
1485 | |
|
1486 | 0 | if (!channel->read_buf) |
1487 | 0 | channel->read_buf = g_string_sized_new (channel->buf_size); |
1488 | |
|
1489 | 0 | cur_len = channel->read_buf->len; |
1490 | |
|
1491 | 0 | g_string_set_size (channel->read_buf, channel->read_buf->len + channel->buf_size); |
1492 | |
|
1493 | 0 | status = channel->funcs->io_read (channel, channel->read_buf->str + cur_len, |
1494 | 0 | channel->buf_size, &read_size, err); |
1495 | |
|
1496 | 0 | g_assert ((status == G_IO_STATUS_NORMAL) || (read_size == 0)); |
1497 | | |
1498 | 0 | g_string_truncate (channel->read_buf, read_size + cur_len); |
1499 | |
|
1500 | 0 | if ((status != G_IO_STATUS_NORMAL) && |
1501 | 0 | ((status != G_IO_STATUS_EOF) || (channel->read_buf->len == 0))) |
1502 | 0 | return status; |
1503 | | |
1504 | 0 | g_assert (channel->read_buf->len > 0); |
1505 | | |
1506 | 0 | if (channel->encoded_read_buf) |
1507 | 0 | oldlen = channel->encoded_read_buf->len; |
1508 | 0 | else |
1509 | 0 | { |
1510 | 0 | oldlen = 0; |
1511 | 0 | if (channel->encoding) |
1512 | 0 | channel->encoded_read_buf = g_string_sized_new (channel->buf_size); |
1513 | 0 | } |
1514 | |
|
1515 | 0 | if (channel->do_encode) |
1516 | 0 | { |
1517 | 0 | gsize errnum, inbytes_left, outbytes_left; |
1518 | 0 | gchar *inbuf, *outbuf; |
1519 | 0 | int errval; |
1520 | |
|
1521 | 0 | g_assert (channel->encoded_read_buf); |
1522 | | |
1523 | 0 | reencode: |
1524 | |
|
1525 | 0 | inbytes_left = channel->read_buf->len; |
1526 | 0 | outbytes_left = MAX (channel->read_buf->len, |
1527 | 0 | channel->encoded_read_buf->allocated_len |
1528 | 0 | - channel->encoded_read_buf->len - 1); /* 1 for NULL */ |
1529 | 0 | outbytes_left = MAX (outbytes_left, 6); |
1530 | |
|
1531 | 0 | inbuf = channel->read_buf->str; |
1532 | 0 | g_string_set_size (channel->encoded_read_buf, |
1533 | 0 | channel->encoded_read_buf->len + outbytes_left); |
1534 | 0 | outbuf = channel->encoded_read_buf->str + channel->encoded_read_buf->len |
1535 | 0 | - outbytes_left; |
1536 | |
|
1537 | 0 | errnum = g_iconv (channel->read_cd, &inbuf, &inbytes_left, |
1538 | 0 | &outbuf, &outbytes_left); |
1539 | 0 | errval = errno; |
1540 | |
|
1541 | 0 | g_assert (inbuf + inbytes_left == channel->read_buf->str |
1542 | 0 | + channel->read_buf->len); |
1543 | 0 | g_assert (outbuf + outbytes_left == channel->encoded_read_buf->str |
1544 | 0 | + channel->encoded_read_buf->len); |
1545 | | |
1546 | 0 | g_string_erase (channel->read_buf, 0, |
1547 | 0 | channel->read_buf->len - inbytes_left); |
1548 | 0 | g_string_truncate (channel->encoded_read_buf, |
1549 | 0 | channel->encoded_read_buf->len - outbytes_left); |
1550 | |
|
1551 | 0 | if (errnum == (gsize) -1) |
1552 | 0 | { |
1553 | 0 | switch (errval) |
1554 | 0 | { |
1555 | 0 | case EINVAL: |
1556 | 0 | if ((oldlen == channel->encoded_read_buf->len) |
1557 | 0 | && (status == G_IO_STATUS_EOF)) |
1558 | 0 | status = G_IO_STATUS_EOF; |
1559 | 0 | else |
1560 | 0 | status = G_IO_STATUS_NORMAL; |
1561 | 0 | break; |
1562 | 0 | case E2BIG: |
1563 | | /* Buffer size at least 6, wrote at least on character */ |
1564 | 0 | g_assert (inbuf != channel->read_buf->str); |
1565 | 0 | goto reencode; |
1566 | 0 | case EILSEQ: |
1567 | 0 | if (oldlen < channel->encoded_read_buf->len) |
1568 | 0 | status = G_IO_STATUS_NORMAL; |
1569 | 0 | else |
1570 | 0 | { |
1571 | 0 | g_set_error_literal (err, G_CONVERT_ERROR, |
1572 | 0 | G_CONVERT_ERROR_ILLEGAL_SEQUENCE, |
1573 | 0 | _("Invalid byte sequence in conversion input")); |
1574 | 0 | return G_IO_STATUS_ERROR; |
1575 | 0 | } |
1576 | 0 | break; |
1577 | 0 | default: |
1578 | 0 | g_assert (errval != EBADF); /* The converter should be open */ |
1579 | 0 | g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, |
1580 | 0 | _("Error during conversion: %s"), g_strerror (errval)); |
1581 | 0 | return G_IO_STATUS_ERROR; |
1582 | 0 | } |
1583 | 0 | } |
1584 | 0 | g_assert ((status != G_IO_STATUS_NORMAL) |
1585 | 0 | || (channel->encoded_read_buf->len > 0)); |
1586 | 0 | } |
1587 | 0 | else if (channel->encoding) /* UTF-8 */ |
1588 | 0 | { |
1589 | 0 | gchar *nextchar, *lastchar; |
1590 | |
|
1591 | 0 | g_assert (channel->encoded_read_buf); |
1592 | | |
1593 | 0 | nextchar = channel->read_buf->str; |
1594 | 0 | lastchar = channel->read_buf->str + channel->read_buf->len; |
1595 | |
|
1596 | 0 | while (nextchar < lastchar) |
1597 | 0 | { |
1598 | 0 | gunichar val_char; |
1599 | |
|
1600 | 0 | val_char = g_utf8_get_char_validated (nextchar, lastchar - nextchar); |
1601 | |
|
1602 | 0 | switch (val_char) |
1603 | 0 | { |
1604 | 0 | case -2: |
1605 | | /* stop, leave partial character in buffer */ |
1606 | 0 | lastchar = nextchar; |
1607 | 0 | break; |
1608 | 0 | case -1: |
1609 | 0 | if (oldlen < channel->encoded_read_buf->len) |
1610 | 0 | status = G_IO_STATUS_NORMAL; |
1611 | 0 | else |
1612 | 0 | { |
1613 | 0 | g_set_error_literal (err, G_CONVERT_ERROR, |
1614 | 0 | G_CONVERT_ERROR_ILLEGAL_SEQUENCE, |
1615 | 0 | _("Invalid byte sequence in conversion input")); |
1616 | 0 | status = G_IO_STATUS_ERROR; |
1617 | 0 | } |
1618 | 0 | lastchar = nextchar; |
1619 | 0 | break; |
1620 | 0 | default: |
1621 | 0 | nextchar = g_utf8_next_char (nextchar); |
1622 | 0 | break; |
1623 | 0 | } |
1624 | 0 | } |
1625 | | |
1626 | 0 | if (lastchar > channel->read_buf->str) |
1627 | 0 | { |
1628 | 0 | gint copy_len = lastchar - channel->read_buf->str; |
1629 | |
|
1630 | 0 | g_string_append_len (channel->encoded_read_buf, channel->read_buf->str, |
1631 | 0 | copy_len); |
1632 | 0 | g_string_erase (channel->read_buf, 0, copy_len); |
1633 | 0 | } |
1634 | 0 | } |
1635 | | |
1636 | 0 | return status; |
1637 | 0 | } |
1638 | | |
1639 | | /** |
1640 | | * g_io_channel_read_line: |
1641 | | * @channel: a #GIOChannel |
1642 | | * @str_return: (out): The line read from the #GIOChannel, including the |
1643 | | * line terminator. This data should be freed with g_free() |
1644 | | * when no longer needed. This is a nul-terminated string. |
1645 | | * If a @length of zero is returned, this will be %NULL instead. |
1646 | | * @length: (out) (optional): location to store length of the read data, or %NULL |
1647 | | * @terminator_pos: (out) (optional): location to store position of line terminator, or %NULL |
1648 | | * @error: A location to return an error of type #GConvertError |
1649 | | * or #GIOChannelError |
1650 | | * |
1651 | | * Reads a line, including the terminating character(s), |
1652 | | * from a #GIOChannel into a newly-allocated string. |
1653 | | * @str_return will contain allocated memory if the return |
1654 | | * is %G_IO_STATUS_NORMAL. |
1655 | | * |
1656 | | * Returns: the status of the operation. |
1657 | | **/ |
1658 | | GIOStatus |
1659 | | g_io_channel_read_line (GIOChannel *channel, |
1660 | | gchar **str_return, |
1661 | | gsize *length, |
1662 | | gsize *terminator_pos, |
1663 | | GError **error) |
1664 | 0 | { |
1665 | 0 | GIOStatus status; |
1666 | 0 | gsize got_length; |
1667 | | |
1668 | 0 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
1669 | 0 | g_return_val_if_fail (str_return != NULL, G_IO_STATUS_ERROR); |
1670 | 0 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
1671 | 0 | G_IO_STATUS_ERROR); |
1672 | 0 | g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); |
1673 | | |
1674 | 0 | status = g_io_channel_read_line_backend (channel, &got_length, terminator_pos, error); |
1675 | |
|
1676 | 0 | if (length && status != G_IO_STATUS_ERROR) |
1677 | 0 | *length = got_length; |
1678 | |
|
1679 | 0 | if (status == G_IO_STATUS_NORMAL) |
1680 | 0 | { |
1681 | 0 | gchar *line; |
1682 | | |
1683 | | /* Copy the read bytes (including any embedded nuls) and nul-terminate. |
1684 | | * `USE_BUF (channel)->str` is guaranteed to be nul-terminated as it’s a |
1685 | | * #GString, so it’s safe to call g_memdup2() with +1 length to allocate |
1686 | | * a nul-terminator. */ |
1687 | 0 | g_assert (USE_BUF (channel)); |
1688 | 0 | line = g_memdup2 (USE_BUF (channel)->str, got_length + 1); |
1689 | 0 | line[got_length] = '\0'; |
1690 | 0 | *str_return = g_steal_pointer (&line); |
1691 | 0 | g_string_erase (USE_BUF (channel), 0, got_length); |
1692 | 0 | } |
1693 | 0 | else |
1694 | 0 | *str_return = NULL; |
1695 | | |
1696 | 0 | return status; |
1697 | 0 | } |
1698 | | |
1699 | | /** |
1700 | | * g_io_channel_read_line_string: |
1701 | | * @channel: a #GIOChannel |
1702 | | * @buffer: a #GString into which the line will be written. |
1703 | | * If @buffer already contains data, the old data will |
1704 | | * be overwritten. |
1705 | | * @terminator_pos: (nullable): location to store position of line terminator, or %NULL |
1706 | | * @error: a location to store an error of type #GConvertError |
1707 | | * or #GIOChannelError |
1708 | | * |
1709 | | * Reads a line from a #GIOChannel, using a #GString as a buffer. |
1710 | | * |
1711 | | * Returns: the status of the operation. |
1712 | | **/ |
1713 | | GIOStatus |
1714 | | g_io_channel_read_line_string (GIOChannel *channel, |
1715 | | GString *buffer, |
1716 | | gsize *terminator_pos, |
1717 | | GError **error) |
1718 | 0 | { |
1719 | 0 | gsize length; |
1720 | 0 | GIOStatus status; |
1721 | |
|
1722 | 0 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
1723 | 0 | g_return_val_if_fail (buffer != NULL, G_IO_STATUS_ERROR); |
1724 | 0 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
1725 | 0 | G_IO_STATUS_ERROR); |
1726 | 0 | g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); |
1727 | | |
1728 | 0 | if (buffer->len > 0) |
1729 | 0 | g_string_truncate (buffer, 0); /* clear out the buffer */ |
1730 | |
|
1731 | 0 | status = g_io_channel_read_line_backend (channel, &length, terminator_pos, error); |
1732 | |
|
1733 | 0 | if (status == G_IO_STATUS_NORMAL) |
1734 | 0 | { |
1735 | 0 | g_assert (USE_BUF (channel)); |
1736 | 0 | g_string_append_len (buffer, USE_BUF (channel)->str, length); |
1737 | 0 | g_string_erase (USE_BUF (channel), 0, length); |
1738 | 0 | } |
1739 | | |
1740 | 0 | return status; |
1741 | 0 | } |
1742 | | |
1743 | | |
1744 | | static GIOStatus |
1745 | | g_io_channel_read_line_backend (GIOChannel *channel, |
1746 | | gsize *length, |
1747 | | gsize *terminator_pos, |
1748 | | GError **error) |
1749 | 0 | { |
1750 | 0 | GIOStatus status; |
1751 | 0 | gsize checked_to, line_term_len, line_length, got_term_len; |
1752 | 0 | gboolean first_time = TRUE; |
1753 | |
|
1754 | 0 | if (!channel->use_buffer) |
1755 | 0 | { |
1756 | | /* Can't do a raw read in read_line */ |
1757 | 0 | g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, |
1758 | 0 | _("Can’t do a raw read in g_io_channel_read_line_string")); |
1759 | 0 | return G_IO_STATUS_ERROR; |
1760 | 0 | } |
1761 | | |
1762 | 0 | status = G_IO_STATUS_NORMAL; |
1763 | |
|
1764 | 0 | if (channel->line_term) |
1765 | 0 | line_term_len = channel->line_term_len; |
1766 | 0 | else |
1767 | 0 | line_term_len = 3; |
1768 | | /* This value used for setting checked_to, it's the longest of the four |
1769 | | * we autodetect for. |
1770 | | */ |
1771 | |
|
1772 | 0 | checked_to = 0; |
1773 | |
|
1774 | 0 | while (TRUE) |
1775 | 0 | { |
1776 | 0 | gchar *nextchar, *lastchar; |
1777 | 0 | GString *use_buf; |
1778 | |
|
1779 | 0 | if (!first_time || (BUF_LEN (USE_BUF (channel)) == 0)) |
1780 | 0 | { |
1781 | 0 | read_again: |
1782 | 0 | status = g_io_channel_fill_buffer (channel, error); |
1783 | 0 | switch (status) |
1784 | 0 | { |
1785 | 0 | case G_IO_STATUS_NORMAL: |
1786 | 0 | if (BUF_LEN (USE_BUF (channel)) == 0) |
1787 | | /* Can happen when using conversion and only read |
1788 | | * part of a character |
1789 | | */ |
1790 | 0 | { |
1791 | 0 | first_time = FALSE; |
1792 | 0 | continue; |
1793 | 0 | } |
1794 | 0 | break; |
1795 | 0 | case G_IO_STATUS_EOF: |
1796 | 0 | if (BUF_LEN (USE_BUF (channel)) == 0) |
1797 | 0 | { |
1798 | 0 | if (length) |
1799 | 0 | *length = 0; |
1800 | |
|
1801 | 0 | if (channel->encoding && channel->read_buf->len != 0) |
1802 | 0 | { |
1803 | 0 | g_set_error_literal (error, G_CONVERT_ERROR, |
1804 | 0 | G_CONVERT_ERROR_PARTIAL_INPUT, |
1805 | 0 | _("Leftover unconverted data in " |
1806 | 0 | "read buffer")); |
1807 | 0 | return G_IO_STATUS_ERROR; |
1808 | 0 | } |
1809 | 0 | else |
1810 | 0 | return G_IO_STATUS_EOF; |
1811 | 0 | } |
1812 | 0 | break; |
1813 | 0 | default: |
1814 | 0 | if (length) |
1815 | 0 | *length = 0; |
1816 | 0 | return status; |
1817 | 0 | } |
1818 | 0 | } |
1819 | | |
1820 | 0 | g_assert (BUF_LEN (USE_BUF (channel)) != 0); |
1821 | | |
1822 | 0 | use_buf = USE_BUF (channel); /* The buffer has been created by this point */ |
1823 | |
|
1824 | 0 | first_time = FALSE; |
1825 | |
|
1826 | 0 | lastchar = use_buf->str + use_buf->len; |
1827 | |
|
1828 | 0 | for (nextchar = use_buf->str + checked_to; nextchar < lastchar; |
1829 | 0 | channel->encoding ? nextchar = g_utf8_next_char (nextchar) : nextchar++) |
1830 | 0 | { |
1831 | 0 | if (channel->line_term) |
1832 | 0 | { |
1833 | 0 | if (memcmp (channel->line_term, nextchar, line_term_len) == 0) |
1834 | 0 | { |
1835 | 0 | line_length = nextchar - use_buf->str; |
1836 | 0 | got_term_len = line_term_len; |
1837 | 0 | goto done; |
1838 | 0 | } |
1839 | 0 | } |
1840 | 0 | else /* auto detect */ |
1841 | 0 | { |
1842 | 0 | switch (*nextchar) |
1843 | 0 | { |
1844 | 0 | case '\n': /* unix */ |
1845 | 0 | line_length = nextchar - use_buf->str; |
1846 | 0 | got_term_len = 1; |
1847 | 0 | goto done; |
1848 | 0 | case '\r': /* Warning: do not use with sockets */ |
1849 | 0 | line_length = nextchar - use_buf->str; |
1850 | 0 | if ((nextchar == lastchar - 1) && (status != G_IO_STATUS_EOF) |
1851 | 0 | && (lastchar == use_buf->str + use_buf->len)) |
1852 | 0 | goto read_again; /* Try to read more data */ |
1853 | 0 | if ((nextchar < lastchar - 1) && (*(nextchar + 1) == '\n')) /* dos */ |
1854 | 0 | got_term_len = 2; |
1855 | 0 | else /* mac */ |
1856 | 0 | got_term_len = 1; |
1857 | 0 | goto done; |
1858 | 0 | case '\xe2': /* Unicode paragraph separator */ |
1859 | 0 | if (strncmp ("\xe2\x80\xa9", nextchar, 3) == 0) |
1860 | 0 | { |
1861 | 0 | line_length = nextchar - use_buf->str; |
1862 | 0 | got_term_len = 3; |
1863 | 0 | goto done; |
1864 | 0 | } |
1865 | 0 | break; |
1866 | 0 | case '\0': /* Embedded null in input */ |
1867 | 0 | line_length = nextchar - use_buf->str; |
1868 | 0 | got_term_len = 1; |
1869 | 0 | goto done; |
1870 | 0 | default: /* no match */ |
1871 | 0 | break; |
1872 | 0 | } |
1873 | 0 | } |
1874 | 0 | } |
1875 | | |
1876 | | /* If encoding != NULL, valid UTF-8, didn't overshoot */ |
1877 | 0 | g_assert (nextchar == lastchar); |
1878 | | |
1879 | | /* Check for EOF */ |
1880 | | |
1881 | 0 | if (status == G_IO_STATUS_EOF) |
1882 | 0 | { |
1883 | 0 | if (channel->encoding && channel->read_buf->len > 0) |
1884 | 0 | { |
1885 | 0 | g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, |
1886 | 0 | _("Channel terminates in a partial character")); |
1887 | 0 | return G_IO_STATUS_ERROR; |
1888 | 0 | } |
1889 | 0 | line_length = use_buf->len; |
1890 | 0 | got_term_len = 0; |
1891 | 0 | break; |
1892 | 0 | } |
1893 | | |
1894 | 0 | if (use_buf->len > line_term_len - 1) |
1895 | 0 | checked_to = use_buf->len - (line_term_len - 1); |
1896 | 0 | else |
1897 | 0 | checked_to = 0; |
1898 | 0 | } |
1899 | | |
1900 | 0 | done: |
1901 | |
|
1902 | 0 | if (terminator_pos) |
1903 | 0 | *terminator_pos = line_length; |
1904 | |
|
1905 | 0 | if (length) |
1906 | 0 | *length = line_length + got_term_len; |
1907 | |
|
1908 | 0 | return G_IO_STATUS_NORMAL; |
1909 | 0 | } |
1910 | | |
1911 | | /** |
1912 | | * g_io_channel_read_to_end: |
1913 | | * @channel: a #GIOChannel |
1914 | | * @str_return: (out) (array length=length) (element-type guint8): Location to |
1915 | | * store a pointer to a string holding the remaining data in the |
1916 | | * #GIOChannel. This data should be freed with g_free() when no |
1917 | | * longer needed. This data is terminated by an extra nul |
1918 | | * character, but there may be other nuls in the intervening data. |
1919 | | * @length: (out): location to store length of the data |
1920 | | * @error: location to return an error of type #GConvertError |
1921 | | * or #GIOChannelError |
1922 | | * |
1923 | | * Reads all the remaining data from the file. |
1924 | | * |
1925 | | * Returns: %G_IO_STATUS_NORMAL on success. |
1926 | | * This function never returns %G_IO_STATUS_EOF. |
1927 | | **/ |
1928 | | GIOStatus |
1929 | | g_io_channel_read_to_end (GIOChannel *channel, |
1930 | | gchar **str_return, |
1931 | | gsize *length, |
1932 | | GError **error) |
1933 | 0 | { |
1934 | 0 | GIOStatus status; |
1935 | | |
1936 | 0 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
1937 | 0 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
1938 | 0 | G_IO_STATUS_ERROR); |
1939 | 0 | g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); |
1940 | | |
1941 | 0 | if (str_return) |
1942 | 0 | *str_return = NULL; |
1943 | 0 | if (length) |
1944 | 0 | *length = 0; |
1945 | |
|
1946 | 0 | if (!channel->use_buffer) |
1947 | 0 | { |
1948 | 0 | g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, |
1949 | 0 | _("Can’t do a raw read in g_io_channel_read_to_end")); |
1950 | 0 | return G_IO_STATUS_ERROR; |
1951 | 0 | } |
1952 | | |
1953 | 0 | do |
1954 | 0 | status = g_io_channel_fill_buffer (channel, error); |
1955 | 0 | while (status == G_IO_STATUS_NORMAL); |
1956 | |
|
1957 | 0 | if (status != G_IO_STATUS_EOF) |
1958 | 0 | return status; |
1959 | | |
1960 | 0 | if (channel->encoding && channel->read_buf->len > 0) |
1961 | 0 | { |
1962 | 0 | g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, |
1963 | 0 | _("Channel terminates in a partial character")); |
1964 | 0 | return G_IO_STATUS_ERROR; |
1965 | 0 | } |
1966 | | |
1967 | 0 | if (USE_BUF (channel) == NULL) |
1968 | 0 | { |
1969 | | /* length is already set to zero */ |
1970 | 0 | if (str_return) |
1971 | 0 | *str_return = g_strdup (""); |
1972 | 0 | } |
1973 | 0 | else |
1974 | 0 | { |
1975 | 0 | if (length) |
1976 | 0 | *length = USE_BUF (channel)->len; |
1977 | |
|
1978 | 0 | if (str_return) |
1979 | 0 | *str_return = g_string_free (USE_BUF (channel), FALSE); |
1980 | 0 | else |
1981 | 0 | g_string_free (USE_BUF (channel), TRUE); |
1982 | |
|
1983 | 0 | if (channel->encoding) |
1984 | 0 | channel->encoded_read_buf = NULL; |
1985 | 0 | else |
1986 | 0 | channel->read_buf = NULL; |
1987 | 0 | } |
1988 | |
|
1989 | 0 | return G_IO_STATUS_NORMAL; |
1990 | 0 | } |
1991 | | |
1992 | | /** |
1993 | | * g_io_channel_read_chars: |
1994 | | * @channel: a #GIOChannel |
1995 | | * @buf: (out caller-allocates) (array length=count) (element-type guint8): |
1996 | | * a buffer to read data into |
1997 | | * @count: (in): the size of the buffer. Note that the buffer may not be |
1998 | | * completely filled even if there is data in the buffer if the |
1999 | | * remaining data is not a complete character. |
2000 | | * @bytes_read: (out) (optional): The number of bytes read. This may be |
2001 | | * zero even on success if count < 6 and the channel's encoding |
2002 | | * is non-%NULL. This indicates that the next UTF-8 character is |
2003 | | * too wide for the buffer. |
2004 | | * @error: a location to return an error of type #GConvertError |
2005 | | * or #GIOChannelError. |
2006 | | * |
2007 | | * Replacement for g_io_channel_read() with the new API. |
2008 | | * |
2009 | | * Returns: the status of the operation. |
2010 | | */ |
2011 | | GIOStatus |
2012 | | g_io_channel_read_chars (GIOChannel *channel, |
2013 | | gchar *buf, |
2014 | | gsize count, |
2015 | | gsize *bytes_read, |
2016 | | GError **error) |
2017 | 0 | { |
2018 | 0 | GIOStatus status; |
2019 | 0 | gsize got_bytes; |
2020 | |
|
2021 | 0 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
2022 | 0 | g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR); |
2023 | 0 | g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); |
2024 | | |
2025 | 0 | if (count == 0) |
2026 | 0 | { |
2027 | 0 | if (bytes_read) |
2028 | 0 | *bytes_read = 0; |
2029 | 0 | return G_IO_STATUS_NORMAL; |
2030 | 0 | } |
2031 | 0 | g_return_val_if_fail (buf != NULL, G_IO_STATUS_ERROR); |
2032 | | |
2033 | 0 | if (!channel->use_buffer) |
2034 | 0 | { |
2035 | 0 | gsize tmp_bytes; |
2036 | |
|
2037 | 0 | g_assert (!channel->read_buf || channel->read_buf->len == 0); |
2038 | | |
2039 | 0 | status = channel->funcs->io_read (channel, buf, count, &tmp_bytes, error); |
2040 | |
|
2041 | 0 | if (bytes_read) |
2042 | 0 | *bytes_read = tmp_bytes; |
2043 | |
|
2044 | 0 | return status; |
2045 | 0 | } |
2046 | | |
2047 | 0 | status = G_IO_STATUS_NORMAL; |
2048 | |
|
2049 | 0 | while (BUF_LEN (USE_BUF (channel)) < count && status == G_IO_STATUS_NORMAL) |
2050 | 0 | status = g_io_channel_fill_buffer (channel, error); |
2051 | | |
2052 | | /* Only return an error if we have no data */ |
2053 | |
|
2054 | 0 | if (BUF_LEN (USE_BUF (channel)) == 0) |
2055 | 0 | { |
2056 | 0 | g_assert (status != G_IO_STATUS_NORMAL); |
2057 | | |
2058 | 0 | if (status == G_IO_STATUS_EOF && channel->encoding |
2059 | 0 | && BUF_LEN (channel->read_buf) > 0) |
2060 | 0 | { |
2061 | 0 | g_set_error_literal (error, G_CONVERT_ERROR, |
2062 | 0 | G_CONVERT_ERROR_PARTIAL_INPUT, |
2063 | 0 | _("Leftover unconverted data in read buffer")); |
2064 | 0 | status = G_IO_STATUS_ERROR; |
2065 | 0 | } |
2066 | |
|
2067 | 0 | if (bytes_read) |
2068 | 0 | *bytes_read = 0; |
2069 | |
|
2070 | 0 | return status; |
2071 | 0 | } |
2072 | | |
2073 | 0 | if (status == G_IO_STATUS_ERROR) |
2074 | 0 | g_clear_error (error); |
2075 | |
|
2076 | 0 | got_bytes = MIN (count, BUF_LEN (USE_BUF (channel))); |
2077 | |
|
2078 | 0 | g_assert (got_bytes > 0); |
2079 | | |
2080 | 0 | if (channel->encoding) |
2081 | | /* Don't validate for NULL encoding, binary safe */ |
2082 | 0 | { |
2083 | 0 | gchar *nextchar, *prevchar; |
2084 | |
|
2085 | 0 | g_assert (USE_BUF (channel) == channel->encoded_read_buf); |
2086 | | |
2087 | 0 | nextchar = channel->encoded_read_buf->str; |
2088 | |
|
2089 | 0 | do |
2090 | 0 | { |
2091 | 0 | prevchar = nextchar; |
2092 | 0 | nextchar = g_utf8_next_char (nextchar); |
2093 | 0 | g_assert (nextchar != prevchar); /* Possible for *prevchar of -1 or -2 */ |
2094 | 0 | } |
2095 | 0 | while (nextchar < channel->encoded_read_buf->str + got_bytes); |
2096 | | |
2097 | 0 | if (nextchar > channel->encoded_read_buf->str + got_bytes) |
2098 | 0 | got_bytes = prevchar - channel->encoded_read_buf->str; |
2099 | |
|
2100 | 0 | g_assert (got_bytes > 0 || count < 6); |
2101 | 0 | } |
2102 | | |
2103 | 0 | memcpy (buf, USE_BUF (channel)->str, got_bytes); |
2104 | 0 | g_string_erase (USE_BUF (channel), 0, got_bytes); |
2105 | |
|
2106 | 0 | if (bytes_read) |
2107 | 0 | *bytes_read = got_bytes; |
2108 | |
|
2109 | 0 | return G_IO_STATUS_NORMAL; |
2110 | 0 | } |
2111 | | |
2112 | | /** |
2113 | | * g_io_channel_read_unichar: |
2114 | | * @channel: a #GIOChannel |
2115 | | * @thechar: (out): a location to return a character |
2116 | | * @error: a location to return an error of type #GConvertError |
2117 | | * or #GIOChannelError |
2118 | | * |
2119 | | * Reads a Unicode character from @channel. |
2120 | | * This function cannot be called on a channel with %NULL encoding. |
2121 | | * |
2122 | | * Returns: a #GIOStatus |
2123 | | **/ |
2124 | | GIOStatus |
2125 | | g_io_channel_read_unichar (GIOChannel *channel, |
2126 | | gunichar *thechar, |
2127 | | GError **error) |
2128 | 0 | { |
2129 | 0 | GIOStatus status = G_IO_STATUS_NORMAL; |
2130 | |
|
2131 | 0 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
2132 | 0 | g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR); |
2133 | 0 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
2134 | 0 | G_IO_STATUS_ERROR); |
2135 | 0 | g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); |
2136 | | |
2137 | 0 | while (BUF_LEN (channel->encoded_read_buf) == 0 && status == G_IO_STATUS_NORMAL) |
2138 | 0 | status = g_io_channel_fill_buffer (channel, error); |
2139 | | |
2140 | | /* Only return an error if we have no data */ |
2141 | |
|
2142 | 0 | if (BUF_LEN (USE_BUF (channel)) == 0) |
2143 | 0 | { |
2144 | 0 | g_assert (status != G_IO_STATUS_NORMAL); |
2145 | | |
2146 | 0 | if (status == G_IO_STATUS_EOF && BUF_LEN (channel->read_buf) > 0) |
2147 | 0 | { |
2148 | 0 | g_set_error_literal (error, G_CONVERT_ERROR, |
2149 | 0 | G_CONVERT_ERROR_PARTIAL_INPUT, |
2150 | 0 | _("Leftover unconverted data in read buffer")); |
2151 | 0 | status = G_IO_STATUS_ERROR; |
2152 | 0 | } |
2153 | |
|
2154 | 0 | if (thechar) |
2155 | 0 | *thechar = (gunichar) -1; |
2156 | |
|
2157 | 0 | return status; |
2158 | 0 | } |
2159 | | |
2160 | 0 | if (status == G_IO_STATUS_ERROR) |
2161 | 0 | g_clear_error (error); |
2162 | |
|
2163 | 0 | if (thechar) |
2164 | 0 | *thechar = g_utf8_get_char (channel->encoded_read_buf->str); |
2165 | |
|
2166 | 0 | g_string_erase (channel->encoded_read_buf, 0, |
2167 | 0 | g_utf8_next_char (channel->encoded_read_buf->str) |
2168 | 0 | - channel->encoded_read_buf->str); |
2169 | |
|
2170 | 0 | return G_IO_STATUS_NORMAL; |
2171 | 0 | } |
2172 | | |
2173 | | /** |
2174 | | * g_io_channel_write_chars: |
2175 | | * @channel: a #GIOChannel |
2176 | | * @buf: (array) (element-type guint8): a buffer to write data from |
2177 | | * @count: the size of the buffer. If -1, the buffer |
2178 | | * is taken to be a nul-terminated string. |
2179 | | * @bytes_written: (out): The number of bytes written. This can be nonzero |
2180 | | * even if the return value is not %G_IO_STATUS_NORMAL. |
2181 | | * If the return value is %G_IO_STATUS_NORMAL and the |
2182 | | * channel is blocking, this will always be equal |
2183 | | * to @count if @count >= 0. |
2184 | | * @error: a location to return an error of type #GConvertError |
2185 | | * or #GIOChannelError |
2186 | | * |
2187 | | * Replacement for g_io_channel_write() with the new API. |
2188 | | * |
2189 | | * On seekable channels with encodings other than %NULL or UTF-8, generic |
2190 | | * mixing of reading and writing is not allowed. A call to g_io_channel_write_chars () |
2191 | | * may only be made on a channel from which data has been read in the |
2192 | | * cases described in the documentation for g_io_channel_set_encoding (). |
2193 | | * |
2194 | | * Returns: the status of the operation. |
2195 | | **/ |
2196 | | GIOStatus |
2197 | | g_io_channel_write_chars (GIOChannel *channel, |
2198 | | const gchar *buf, |
2199 | | gssize count, |
2200 | | gsize *bytes_written, |
2201 | | GError **error) |
2202 | 0 | { |
2203 | 0 | gsize count_unsigned; |
2204 | 0 | GIOStatus status; |
2205 | 0 | gssize wrote_bytes = 0; |
2206 | |
|
2207 | 0 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
2208 | 0 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
2209 | 0 | G_IO_STATUS_ERROR); |
2210 | 0 | g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR); |
2211 | | |
2212 | 0 | if ((count < 0) && buf) |
2213 | 0 | count = strlen (buf); |
2214 | 0 | count_unsigned = count; |
2215 | |
|
2216 | 0 | if (count_unsigned == 0) |
2217 | 0 | { |
2218 | 0 | if (bytes_written) |
2219 | 0 | *bytes_written = 0; |
2220 | 0 | return G_IO_STATUS_NORMAL; |
2221 | 0 | } |
2222 | | |
2223 | 0 | g_return_val_if_fail (buf != NULL, G_IO_STATUS_ERROR); |
2224 | 0 | g_return_val_if_fail (count_unsigned > 0, G_IO_STATUS_ERROR); |
2225 | | |
2226 | | /* Raw write case */ |
2227 | | |
2228 | 0 | if (!channel->use_buffer) |
2229 | 0 | { |
2230 | 0 | gsize tmp_bytes; |
2231 | | |
2232 | 0 | g_assert (!channel->write_buf || channel->write_buf->len == 0); |
2233 | 0 | g_assert (channel->partial_write_buf[0] == '\0'); |
2234 | | |
2235 | 0 | status = channel->funcs->io_write (channel, buf, count_unsigned, |
2236 | 0 | &tmp_bytes, error); |
2237 | |
|
2238 | 0 | if (bytes_written) |
2239 | 0 | *bytes_written = tmp_bytes; |
2240 | |
|
2241 | 0 | return status; |
2242 | 0 | } |
2243 | | |
2244 | | /* General case */ |
2245 | | |
2246 | 0 | if (channel->is_seekable && (( BUF_LEN (channel->read_buf) > 0) |
2247 | 0 | || (BUF_LEN (channel->encoded_read_buf) > 0))) |
2248 | 0 | { |
2249 | 0 | if (channel->do_encode && BUF_LEN (channel->encoded_read_buf) > 0) |
2250 | 0 | { |
2251 | 0 | g_warning ("Mixed reading and writing not allowed on encoded files"); |
2252 | 0 | return G_IO_STATUS_ERROR; |
2253 | 0 | } |
2254 | 0 | status = g_io_channel_seek_position (channel, 0, G_SEEK_CUR, error); |
2255 | 0 | if (status != G_IO_STATUS_NORMAL) |
2256 | 0 | { |
2257 | 0 | if (bytes_written) |
2258 | 0 | *bytes_written = 0; |
2259 | 0 | return status; |
2260 | 0 | } |
2261 | 0 | } |
2262 | | |
2263 | 0 | if (!channel->write_buf) |
2264 | 0 | channel->write_buf = g_string_sized_new (channel->buf_size); |
2265 | |
|
2266 | 0 | while (wrote_bytes < count) |
2267 | 0 | { |
2268 | 0 | gsize space_in_buf; |
2269 | | |
2270 | | /* If the buffer is full, try a write immediately. In |
2271 | | * the nonblocking case, this prevents the user from |
2272 | | * writing just a little bit to the buffer every time |
2273 | | * and never receiving an EAGAIN. |
2274 | | */ |
2275 | |
|
2276 | 0 | if (channel->write_buf->len >= channel->buf_size - MAX_CHAR_SIZE) |
2277 | 0 | { |
2278 | 0 | gsize did_write = 0, this_time; |
2279 | |
|
2280 | 0 | do |
2281 | 0 | { |
2282 | 0 | status = channel->funcs->io_write (channel, channel->write_buf->str |
2283 | 0 | + did_write, channel->write_buf->len |
2284 | 0 | - did_write, &this_time, error); |
2285 | 0 | did_write += this_time; |
2286 | 0 | } |
2287 | 0 | while (status == G_IO_STATUS_NORMAL && |
2288 | 0 | did_write < MIN (channel->write_buf->len, MAX_CHAR_SIZE)); |
2289 | |
|
2290 | 0 | g_string_erase (channel->write_buf, 0, did_write); |
2291 | |
|
2292 | 0 | if (status != G_IO_STATUS_NORMAL) |
2293 | 0 | { |
2294 | 0 | if (status == G_IO_STATUS_AGAIN && wrote_bytes > 0) |
2295 | 0 | status = G_IO_STATUS_NORMAL; |
2296 | 0 | if (bytes_written) |
2297 | 0 | *bytes_written = wrote_bytes; |
2298 | 0 | return status; |
2299 | 0 | } |
2300 | 0 | } |
2301 | | |
2302 | 0 | space_in_buf = MAX (channel->buf_size, channel->write_buf->allocated_len - 1) |
2303 | 0 | - channel->write_buf->len; /* 1 for NULL */ |
2304 | | |
2305 | | /* This is only true because g_io_channel_set_buffer_size () |
2306 | | * ensures that channel->buf_size >= MAX_CHAR_SIZE. |
2307 | | */ |
2308 | 0 | g_assert (space_in_buf >= MAX_CHAR_SIZE); |
2309 | | |
2310 | 0 | if (!channel->encoding) |
2311 | 0 | { |
2312 | 0 | gssize write_this = MIN (space_in_buf, count_unsigned - wrote_bytes); |
2313 | |
|
2314 | 0 | g_string_append_len (channel->write_buf, buf, write_this); |
2315 | 0 | buf += write_this; |
2316 | 0 | wrote_bytes += write_this; |
2317 | 0 | } |
2318 | 0 | else |
2319 | 0 | { |
2320 | 0 | const gchar *from_buf; |
2321 | 0 | gsize from_buf_len, from_buf_old_len, left_len; |
2322 | 0 | gsize err; |
2323 | 0 | gint errnum; |
2324 | |
|
2325 | 0 | if (channel->partial_write_buf[0] != '\0') |
2326 | 0 | { |
2327 | 0 | g_assert (wrote_bytes == 0); |
2328 | | |
2329 | 0 | from_buf = channel->partial_write_buf; |
2330 | 0 | from_buf_old_len = strlen (channel->partial_write_buf); |
2331 | 0 | g_assert (from_buf_old_len > 0); |
2332 | 0 | from_buf_len = MIN (6, from_buf_old_len + count_unsigned); |
2333 | |
|
2334 | 0 | memcpy (channel->partial_write_buf + from_buf_old_len, buf, |
2335 | 0 | from_buf_len - from_buf_old_len); |
2336 | 0 | } |
2337 | 0 | else |
2338 | 0 | { |
2339 | 0 | from_buf = buf; |
2340 | 0 | from_buf_len = count_unsigned - wrote_bytes; |
2341 | 0 | from_buf_old_len = 0; |
2342 | 0 | } |
2343 | | |
2344 | 0 | reconvert: |
2345 | |
|
2346 | 0 | if (!channel->do_encode) /* UTF-8 encoding */ |
2347 | 0 | { |
2348 | 0 | const gchar *badchar; |
2349 | 0 | gsize try_len = MIN (from_buf_len, space_in_buf); |
2350 | | |
2351 | | /* UTF-8, just validate, emulate g_iconv */ |
2352 | |
|
2353 | 0 | if (!g_utf8_validate_len (from_buf, try_len, &badchar)) |
2354 | 0 | { |
2355 | 0 | gunichar try_char; |
2356 | 0 | gsize incomplete_len = from_buf + try_len - badchar; |
2357 | |
|
2358 | 0 | left_len = from_buf + from_buf_len - badchar; |
2359 | |
|
2360 | 0 | try_char = g_utf8_get_char_validated (badchar, incomplete_len); |
2361 | |
|
2362 | 0 | switch (try_char) |
2363 | 0 | { |
2364 | 0 | case -2: |
2365 | 0 | g_assert (incomplete_len < 6); |
2366 | 0 | if (try_len == from_buf_len) |
2367 | 0 | { |
2368 | 0 | errnum = EINVAL; |
2369 | 0 | err = (gsize) -1; |
2370 | 0 | } |
2371 | 0 | else |
2372 | 0 | { |
2373 | 0 | errnum = 0; |
2374 | 0 | err = (gsize) 0; |
2375 | 0 | } |
2376 | 0 | break; |
2377 | 0 | case -1: |
2378 | 0 | g_warning ("Invalid UTF-8 passed to g_io_channel_write_chars()."); |
2379 | | /* FIXME bail here? */ |
2380 | 0 | errnum = EILSEQ; |
2381 | 0 | err = (gsize) -1; |
2382 | 0 | break; |
2383 | 0 | default: |
2384 | 0 | g_assert_not_reached (); |
2385 | 0 | err = (gsize) -1; |
2386 | 0 | errnum = 0; /* Don't confuse the compiler */ |
2387 | 0 | } |
2388 | 0 | } |
2389 | 0 | else |
2390 | 0 | { |
2391 | 0 | err = (gsize) 0; |
2392 | 0 | errnum = 0; |
2393 | 0 | left_len = from_buf_len - try_len; |
2394 | 0 | } |
2395 | | |
2396 | 0 | g_string_append_len (channel->write_buf, from_buf, |
2397 | 0 | from_buf_len - left_len); |
2398 | 0 | from_buf += from_buf_len - left_len; |
2399 | 0 | } |
2400 | 0 | else |
2401 | 0 | { |
2402 | 0 | gchar *outbuf; |
2403 | |
|
2404 | 0 | left_len = from_buf_len; |
2405 | 0 | g_string_set_size (channel->write_buf, channel->write_buf->len |
2406 | 0 | + space_in_buf); |
2407 | 0 | outbuf = channel->write_buf->str + channel->write_buf->len |
2408 | 0 | - space_in_buf; |
2409 | 0 | err = g_iconv (channel->write_cd, (gchar **) &from_buf, &left_len, |
2410 | 0 | &outbuf, &space_in_buf); |
2411 | 0 | errnum = errno; |
2412 | 0 | g_string_truncate (channel->write_buf, channel->write_buf->len |
2413 | 0 | - space_in_buf); |
2414 | 0 | } |
2415 | | |
2416 | 0 | if (err == (gsize) -1) |
2417 | 0 | { |
2418 | 0 | switch (errnum) |
2419 | 0 | { |
2420 | 0 | case EINVAL: |
2421 | 0 | g_assert (left_len < 6); |
2422 | | |
2423 | 0 | if (from_buf_old_len == 0) |
2424 | 0 | { |
2425 | | /* Not from partial_write_buf */ |
2426 | |
|
2427 | 0 | memcpy (channel->partial_write_buf, from_buf, left_len); |
2428 | 0 | channel->partial_write_buf[left_len] = '\0'; |
2429 | 0 | if (bytes_written) |
2430 | 0 | *bytes_written = count_unsigned; |
2431 | 0 | return G_IO_STATUS_NORMAL; |
2432 | 0 | } |
2433 | | |
2434 | | /* Working in partial_write_buf */ |
2435 | | |
2436 | 0 | if (left_len == from_buf_len) |
2437 | 0 | { |
2438 | | /* Didn't convert anything, must still have |
2439 | | * less than a full character |
2440 | | */ |
2441 | |
|
2442 | 0 | g_assert (count_unsigned == from_buf_len - from_buf_old_len); |
2443 | | |
2444 | 0 | channel->partial_write_buf[from_buf_len] = '\0'; |
2445 | |
|
2446 | 0 | if (bytes_written) |
2447 | 0 | *bytes_written = count_unsigned; |
2448 | |
|
2449 | 0 | return G_IO_STATUS_NORMAL; |
2450 | 0 | } |
2451 | | |
2452 | 0 | g_assert (from_buf_len - left_len >= from_buf_old_len); |
2453 | | |
2454 | | /* We converted all the old data. This is fine */ |
2455 | | |
2456 | 0 | break; |
2457 | 0 | case E2BIG: |
2458 | 0 | if (from_buf_len == left_len) |
2459 | 0 | { |
2460 | | /* Nothing was written, add enough space for |
2461 | | * at least one character. |
2462 | | */ |
2463 | 0 | space_in_buf += MAX_CHAR_SIZE; |
2464 | 0 | goto reconvert; |
2465 | 0 | } |
2466 | 0 | break; |
2467 | 0 | case EILSEQ: |
2468 | 0 | g_set_error_literal (error, G_CONVERT_ERROR, |
2469 | 0 | G_CONVERT_ERROR_ILLEGAL_SEQUENCE, |
2470 | 0 | _("Invalid byte sequence in conversion input")); |
2471 | 0 | if (from_buf_old_len > 0 && from_buf_len == left_len) |
2472 | 0 | g_warning ("Illegal sequence due to partial character " |
2473 | 0 | "at the end of a previous write."); |
2474 | 0 | else |
2475 | 0 | wrote_bytes += from_buf_len - left_len - from_buf_old_len; |
2476 | 0 | if (bytes_written) |
2477 | 0 | *bytes_written = wrote_bytes; |
2478 | 0 | channel->partial_write_buf[0] = '\0'; |
2479 | 0 | return G_IO_STATUS_ERROR; |
2480 | 0 | default: |
2481 | 0 | g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, |
2482 | 0 | _("Error during conversion: %s"), g_strerror (errnum)); |
2483 | 0 | if (from_buf_len >= left_len + from_buf_old_len) |
2484 | 0 | wrote_bytes += from_buf_len - left_len - from_buf_old_len; |
2485 | 0 | if (bytes_written) |
2486 | 0 | *bytes_written = wrote_bytes; |
2487 | 0 | channel->partial_write_buf[0] = '\0'; |
2488 | 0 | return G_IO_STATUS_ERROR; |
2489 | 0 | } |
2490 | 0 | } |
2491 | | |
2492 | 0 | g_assert (from_buf_len - left_len >= from_buf_old_len); |
2493 | | |
2494 | 0 | wrote_bytes += from_buf_len - left_len - from_buf_old_len; |
2495 | |
|
2496 | 0 | if (from_buf_old_len > 0) |
2497 | 0 | { |
2498 | | /* We were working in partial_write_buf */ |
2499 | |
|
2500 | 0 | buf += from_buf_len - left_len - from_buf_old_len; |
2501 | 0 | channel->partial_write_buf[0] = '\0'; |
2502 | 0 | } |
2503 | 0 | else |
2504 | 0 | buf = from_buf; |
2505 | 0 | } |
2506 | 0 | } |
2507 | | |
2508 | 0 | if (bytes_written) |
2509 | 0 | *bytes_written = count_unsigned; |
2510 | |
|
2511 | 0 | return G_IO_STATUS_NORMAL; |
2512 | 0 | } |
2513 | | |
2514 | | /** |
2515 | | * g_io_channel_write_unichar: |
2516 | | * @channel: a #GIOChannel |
2517 | | * @thechar: a character |
2518 | | * @error: location to return an error of type #GConvertError |
2519 | | * or #GIOChannelError |
2520 | | * |
2521 | | * Writes a Unicode character to @channel. |
2522 | | * This function cannot be called on a channel with %NULL encoding. |
2523 | | * |
2524 | | * Returns: a #GIOStatus |
2525 | | **/ |
2526 | | GIOStatus |
2527 | | g_io_channel_write_unichar (GIOChannel *channel, |
2528 | | gunichar thechar, |
2529 | | GError **error) |
2530 | 0 | { |
2531 | 0 | GIOStatus status; |
2532 | 0 | gchar static_buf[6]; |
2533 | 0 | gsize char_len, wrote_len; |
2534 | |
|
2535 | 0 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
2536 | 0 | g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR); |
2537 | 0 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
2538 | 0 | G_IO_STATUS_ERROR); |
2539 | 0 | g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR); |
2540 | | |
2541 | 0 | char_len = g_unichar_to_utf8 (thechar, static_buf); |
2542 | |
|
2543 | 0 | if (channel->partial_write_buf[0] != '\0') |
2544 | 0 | { |
2545 | 0 | g_warning ("Partial character written before writing unichar."); |
2546 | 0 | channel->partial_write_buf[0] = '\0'; |
2547 | 0 | } |
2548 | |
|
2549 | 0 | status = g_io_channel_write_chars (channel, static_buf, |
2550 | 0 | char_len, &wrote_len, error); |
2551 | | |
2552 | | /* We validate UTF-8, so we can't get a partial write */ |
2553 | |
|
2554 | 0 | g_assert (wrote_len == char_len || status != G_IO_STATUS_NORMAL); |
2555 | | |
2556 | 0 | return status; |
2557 | 0 | } |
2558 | | |
2559 | | /** |
2560 | | * G_IO_CHANNEL_ERROR: |
2561 | | * |
2562 | | * Error domain for #GIOChannel operations. Errors in this domain will |
2563 | | * be from the #GIOChannelError enumeration. See #GError for |
2564 | | * information on error domains. |
2565 | | **/ |
2566 | | /** |
2567 | | * GIOChannelError: |
2568 | | * @G_IO_CHANNEL_ERROR_FBIG: File too large. |
2569 | | * @G_IO_CHANNEL_ERROR_INVAL: Invalid argument. |
2570 | | * @G_IO_CHANNEL_ERROR_IO: IO error. |
2571 | | * @G_IO_CHANNEL_ERROR_ISDIR: File is a directory. |
2572 | | * @G_IO_CHANNEL_ERROR_NOSPC: No space left on device. |
2573 | | * @G_IO_CHANNEL_ERROR_NXIO: No such device or address. |
2574 | | * @G_IO_CHANNEL_ERROR_OVERFLOW: Value too large for defined datatype. |
2575 | | * @G_IO_CHANNEL_ERROR_PIPE: Broken pipe. |
2576 | | * @G_IO_CHANNEL_ERROR_FAILED: Some other error. |
2577 | | * |
2578 | | * Error codes returned by #GIOChannel operations. |
2579 | | **/ |
2580 | | |
2581 | | G_DEFINE_QUARK (g-io-channel-error-quark, g_io_channel_error) |