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 | #define G_IO_NICE_BUF_SIZE 1024 |
153 | |
154 | /* This needs to be as wide as the largest character in any possible encoding */ |
155 | #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 | #define USE_BUF(channel) ((channel)->encoding ? (channel)->encoded_read_buf \ |
162 | : (channel)->read_buf) |
163 | #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 | { |
188 | channel->ref_count = 1; |
189 | channel->encoding = g_strdup (str: "UTF-8" ); |
190 | channel->line_term = NULL; |
191 | channel->line_term_len = 0; |
192 | channel->buf_size = G_IO_NICE_BUF_SIZE; |
193 | channel->read_cd = (GIConv) -1; |
194 | channel->write_cd = (GIConv) -1; |
195 | channel->read_buf = NULL; /* Lazy allocate buffers */ |
196 | channel->encoded_read_buf = NULL; |
197 | channel->write_buf = NULL; |
198 | channel->partial_write_buf[0] = '\0'; |
199 | channel->use_buffer = TRUE; |
200 | channel->do_encode = FALSE; |
201 | channel->close_on_unref = FALSE; |
202 | } |
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 | { |
215 | g_return_val_if_fail (channel != NULL, NULL); |
216 | |
217 | g_atomic_int_inc (&channel->ref_count); |
218 | |
219 | return channel; |
220 | } |
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 | { |
231 | gboolean is_zero; |
232 | |
233 | g_return_if_fail (channel != NULL); |
234 | |
235 | is_zero = g_atomic_int_dec_and_test (&channel->ref_count); |
236 | |
237 | if (G_UNLIKELY (is_zero)) |
238 | { |
239 | if (channel->close_on_unref) |
240 | g_io_channel_shutdown (channel, TRUE, NULL); |
241 | else |
242 | g_io_channel_purge (channel); |
243 | g_free (mem: channel->encoding); |
244 | if (channel->read_cd != (GIConv) -1) |
245 | g_iconv_close (converter: channel->read_cd); |
246 | if (channel->write_cd != (GIConv) -1) |
247 | g_iconv_close (converter: channel->write_cd); |
248 | g_free (mem: channel->line_term); |
249 | if (channel->read_buf) |
250 | g_string_free (string: channel->read_buf, TRUE); |
251 | if (channel->write_buf) |
252 | g_string_free (string: channel->write_buf, TRUE); |
253 | if (channel->encoded_read_buf) |
254 | g_string_free (string: channel->encoded_read_buf, TRUE); |
255 | channel->funcs->io_free (channel); |
256 | } |
257 | } |
258 | |
259 | static GIOError |
260 | g_io_error_get_from_g_error (GIOStatus status, |
261 | GError *err) |
262 | { |
263 | switch (status) |
264 | { |
265 | case G_IO_STATUS_NORMAL: |
266 | case G_IO_STATUS_EOF: |
267 | return G_IO_ERROR_NONE; |
268 | case G_IO_STATUS_AGAIN: |
269 | return G_IO_ERROR_AGAIN; |
270 | case G_IO_STATUS_ERROR: |
271 | g_return_val_if_fail (err != NULL, G_IO_ERROR_UNKNOWN); |
272 | |
273 | if (err->domain != G_IO_CHANNEL_ERROR) |
274 | return G_IO_ERROR_UNKNOWN; |
275 | switch (err->code) |
276 | { |
277 | case G_IO_CHANNEL_ERROR_INVAL: |
278 | return G_IO_ERROR_INVAL; |
279 | default: |
280 | return G_IO_ERROR_UNKNOWN; |
281 | } |
282 | default: |
283 | g_assert_not_reached (); |
284 | } |
285 | } |
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 | { |
307 | GError *err = NULL; |
308 | GIOError error; |
309 | GIOStatus status; |
310 | |
311 | g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN); |
312 | g_return_val_if_fail (bytes_read != NULL, G_IO_ERROR_UNKNOWN); |
313 | |
314 | if (count == 0) |
315 | { |
316 | if (bytes_read) |
317 | *bytes_read = 0; |
318 | return G_IO_ERROR_NONE; |
319 | } |
320 | |
321 | g_return_val_if_fail (buf != NULL, G_IO_ERROR_UNKNOWN); |
322 | |
323 | status = channel->funcs->io_read (channel, buf, count, bytes_read, &err); |
324 | |
325 | error = g_io_error_get_from_g_error (status, err); |
326 | |
327 | if (err) |
328 | g_error_free (error: err); |
329 | |
330 | return error; |
331 | } |
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 | { |
352 | GError *err = NULL; |
353 | GIOError error; |
354 | GIOStatus status; |
355 | |
356 | g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN); |
357 | g_return_val_if_fail (bytes_written != NULL, G_IO_ERROR_UNKNOWN); |
358 | |
359 | status = channel->funcs->io_write (channel, buf, count, bytes_written, &err); |
360 | |
361 | error = g_io_error_get_from_g_error (status, err); |
362 | |
363 | if (err) |
364 | g_error_free (error: err); |
365 | |
366 | return error; |
367 | } |
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 | { |
390 | GError *err = NULL; |
391 | GIOError error; |
392 | GIOStatus status; |
393 | |
394 | g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN); |
395 | g_return_val_if_fail (channel->is_seekable, G_IO_ERROR_UNKNOWN); |
396 | |
397 | switch (type) |
398 | { |
399 | case G_SEEK_CUR: |
400 | case G_SEEK_SET: |
401 | case G_SEEK_END: |
402 | break; |
403 | default: |
404 | g_warning ("g_io_channel_seek: unknown seek type" ); |
405 | return G_IO_ERROR_UNKNOWN; |
406 | } |
407 | |
408 | status = channel->funcs->io_seek (channel, offset, type, &err); |
409 | |
410 | error = g_io_error_get_from_g_error (status, err); |
411 | |
412 | if (err) |
413 | g_error_free (error: err); |
414 | |
415 | return error; |
416 | } |
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 | { |
451 | GError *err = NULL; |
452 | |
453 | g_return_if_fail (channel != NULL); |
454 | |
455 | g_io_channel_purge (channel); |
456 | |
457 | channel->funcs->io_close (channel, &err); |
458 | |
459 | if (err) |
460 | { /* No way to return the error */ |
461 | g_warning ("Error closing channel: %s" , err->message); |
462 | g_error_free (error: err); |
463 | } |
464 | |
465 | channel->close_on_unref = FALSE; /* Because we already did */ |
466 | channel->is_readable = FALSE; |
467 | channel->is_writeable = FALSE; |
468 | channel->is_seekable = FALSE; |
469 | } |
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 | { |
488 | GIOStatus status, result; |
489 | GError *tmperr = NULL; |
490 | |
491 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
492 | g_return_val_if_fail (err == NULL || *err == NULL, G_IO_STATUS_ERROR); |
493 | |
494 | if (channel->write_buf && channel->write_buf->len > 0) |
495 | { |
496 | if (flush) |
497 | { |
498 | GIOFlags flags; |
499 | |
500 | /* Set the channel to blocking, to avoid a busy loop |
501 | */ |
502 | flags = g_io_channel_get_flags (channel); |
503 | /* Ignore any errors here, they're irrelevant */ |
504 | g_io_channel_set_flags (channel, flags: flags & ~G_IO_FLAG_NONBLOCK, NULL); |
505 | |
506 | result = g_io_channel_flush (channel, error: &tmperr); |
507 | } |
508 | else |
509 | result = G_IO_STATUS_NORMAL; |
510 | |
511 | g_string_truncate(string: channel->write_buf, len: 0); |
512 | } |
513 | else |
514 | result = G_IO_STATUS_NORMAL; |
515 | |
516 | if (channel->partial_write_buf[0] != '\0') |
517 | { |
518 | if (flush) |
519 | g_warning ("Partial character at end of write buffer not flushed." ); |
520 | channel->partial_write_buf[0] = '\0'; |
521 | } |
522 | |
523 | status = channel->funcs->io_close (channel, err); |
524 | |
525 | channel->close_on_unref = FALSE; /* Because we already did */ |
526 | channel->is_readable = FALSE; |
527 | channel->is_writeable = FALSE; |
528 | channel->is_seekable = FALSE; |
529 | |
530 | if (status != G_IO_STATUS_NORMAL) |
531 | { |
532 | g_clear_error (err: &tmperr); |
533 | return status; |
534 | } |
535 | else if (result != G_IO_STATUS_NORMAL) |
536 | { |
537 | g_propagate_error (dest: err, src: tmperr); |
538 | return result; |
539 | } |
540 | else |
541 | return G_IO_STATUS_NORMAL; |
542 | } |
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 | { |
548 | GError *err = NULL; |
549 | GIOStatus status G_GNUC_UNUSED; |
550 | |
551 | g_return_if_fail (channel != NULL); |
552 | |
553 | if (channel->write_buf && channel->write_buf->len > 0) |
554 | { |
555 | GIOFlags flags; |
556 | |
557 | /* Set the channel to blocking, to avoid a busy loop |
558 | */ |
559 | flags = g_io_channel_get_flags (channel); |
560 | g_io_channel_set_flags (channel, flags: flags & ~G_IO_FLAG_NONBLOCK, NULL); |
561 | |
562 | status = g_io_channel_flush (channel, error: &err); |
563 | |
564 | if (err) |
565 | { /* No way to return the error */ |
566 | g_warning ("Error flushing string: %s" , err->message); |
567 | g_error_free (error: err); |
568 | } |
569 | } |
570 | |
571 | /* Flush these in case anyone tries to close without unrefing */ |
572 | |
573 | if (channel->read_buf) |
574 | g_string_truncate (string: channel->read_buf, len: 0); |
575 | if (channel->write_buf) |
576 | g_string_truncate (string: channel->write_buf, len: 0); |
577 | if (channel->encoding) |
578 | { |
579 | if (channel->encoded_read_buf) |
580 | g_string_truncate (string: channel->encoded_read_buf, len: 0); |
581 | |
582 | if (channel->partial_write_buf[0] != '\0') |
583 | { |
584 | g_warning ("Partial character at end of write buffer not flushed." ); |
585 | channel->partial_write_buf[0] = '\0'; |
586 | } |
587 | } |
588 | } |
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 | { |
616 | g_return_val_if_fail (channel != NULL, NULL); |
617 | |
618 | return channel->funcs->io_create_watch (channel, condition); |
619 | } |
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 | { |
647 | GSource *source; |
648 | guint id; |
649 | |
650 | g_return_val_if_fail (channel != NULL, 0); |
651 | |
652 | source = g_io_create_watch (channel, condition); |
653 | |
654 | if (priority != G_PRIORITY_DEFAULT) |
655 | g_source_set_priority (source, priority); |
656 | g_source_set_callback (source, func: (GSourceFunc)func, data: user_data, notify); |
657 | |
658 | id = g_source_attach (source, NULL); |
659 | g_source_unref (source); |
660 | |
661 | return id; |
662 | } |
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 | { |
708 | return g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, condition, func, user_data, NULL); |
709 | } |
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 | { |
724 | GIOCondition condition = 0; |
725 | |
726 | if (channel->encoding) |
727 | { |
728 | if (channel->encoded_read_buf && (channel->encoded_read_buf->len > 0)) |
729 | condition |= G_IO_IN; /* Only return if we have full characters */ |
730 | } |
731 | else |
732 | { |
733 | if (channel->read_buf && (channel->read_buf->len > 0)) |
734 | condition |= G_IO_IN; |
735 | } |
736 | |
737 | if (channel->write_buf && (channel->write_buf->len < channel->buf_size)) |
738 | condition |= G_IO_OUT; |
739 | |
740 | return condition; |
741 | } |
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 | { |
755 | #ifdef EAGAIN |
756 | g_return_val_if_fail (en != EAGAIN, G_IO_CHANNEL_ERROR_FAILED); |
757 | #endif |
758 | |
759 | switch (en) |
760 | { |
761 | #ifdef EBADF |
762 | case EBADF: |
763 | g_warning ("Invalid file descriptor." ); |
764 | return G_IO_CHANNEL_ERROR_FAILED; |
765 | #endif |
766 | |
767 | #ifdef EFAULT |
768 | case EFAULT: |
769 | g_warning ("Buffer outside valid address space." ); |
770 | return G_IO_CHANNEL_ERROR_FAILED; |
771 | #endif |
772 | |
773 | #ifdef EFBIG |
774 | case EFBIG: |
775 | return G_IO_CHANNEL_ERROR_FBIG; |
776 | #endif |
777 | |
778 | #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 | case EINTR: |
787 | return G_IO_CHANNEL_ERROR_FAILED; |
788 | #endif |
789 | |
790 | #ifdef EINVAL |
791 | case EINVAL: |
792 | return G_IO_CHANNEL_ERROR_INVAL; |
793 | #endif |
794 | |
795 | #ifdef EIO |
796 | case EIO: |
797 | return G_IO_CHANNEL_ERROR_IO; |
798 | #endif |
799 | |
800 | #ifdef EISDIR |
801 | case EISDIR: |
802 | return G_IO_CHANNEL_ERROR_ISDIR; |
803 | #endif |
804 | |
805 | #ifdef ENOSPC |
806 | case ENOSPC: |
807 | return G_IO_CHANNEL_ERROR_NOSPC; |
808 | #endif |
809 | |
810 | #ifdef ENXIO |
811 | case ENXIO: |
812 | return G_IO_CHANNEL_ERROR_NXIO; |
813 | #endif |
814 | |
815 | #ifdef EOVERFLOW |
816 | #if EOVERFLOW != EFBIG |
817 | case EOVERFLOW: |
818 | return G_IO_CHANNEL_ERROR_OVERFLOW; |
819 | #endif |
820 | #endif |
821 | |
822 | #ifdef EPIPE |
823 | case EPIPE: |
824 | return G_IO_CHANNEL_ERROR_PIPE; |
825 | #endif |
826 | |
827 | default: |
828 | return G_IO_CHANNEL_ERROR_FAILED; |
829 | } |
830 | } |
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 | { |
843 | g_return_if_fail (channel != NULL); |
844 | |
845 | if (size == 0) |
846 | size = G_IO_NICE_BUF_SIZE; |
847 | |
848 | if (size < MAX_CHAR_SIZE) |
849 | size = MAX_CHAR_SIZE; |
850 | |
851 | channel->buf_size = size; |
852 | } |
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 | { |
865 | g_return_val_if_fail (channel != NULL, 0); |
866 | |
867 | return channel->buf_size; |
868 | } |
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 | { |
889 | guint length_unsigned; |
890 | |
891 | g_return_if_fail (channel != NULL); |
892 | g_return_if_fail (line_term == NULL || length != 0); /* Disallow "" */ |
893 | |
894 | if (line_term == NULL) |
895 | length_unsigned = 0; |
896 | else if (length >= 0) |
897 | length_unsigned = (guint) length; |
898 | else |
899 | { |
900 | /* FIXME: We’re constrained by line_term_len being a guint here */ |
901 | gsize length_size = strlen (s: line_term); |
902 | g_return_if_fail (length_size <= G_MAXUINT); |
903 | length_unsigned = (guint) length_size; |
904 | } |
905 | |
906 | g_free (mem: channel->line_term); |
907 | channel->line_term = line_term ? g_memdup2 (mem: line_term, byte_size: length_unsigned) : NULL; |
908 | channel->line_term_len = length_unsigned; |
909 | } |
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 | { |
927 | g_return_val_if_fail (channel != NULL, NULL); |
928 | |
929 | if (length) |
930 | *length = channel->line_term_len; |
931 | |
932 | return channel->line_term; |
933 | } |
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 | { |
977 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
978 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
979 | G_IO_STATUS_ERROR); |
980 | |
981 | return (*channel->funcs->io_set_flags) (channel, |
982 | flags & G_IO_FLAG_SET_MASK, |
983 | error); |
984 | } |
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 | { |
1005 | GIOFlags flags; |
1006 | |
1007 | g_return_val_if_fail (channel != NULL, 0); |
1008 | |
1009 | flags = (* channel->funcs->io_get_flags) (channel); |
1010 | |
1011 | /* Cross implementation code */ |
1012 | |
1013 | if (channel->is_seekable) |
1014 | flags |= G_IO_FLAG_IS_SEEKABLE; |
1015 | if (channel->is_readable) |
1016 | flags |= G_IO_FLAG_IS_READABLE; |
1017 | if (channel->is_writeable) |
1018 | flags |= G_IO_FLAG_IS_WRITABLE; |
1019 | |
1020 | return flags; |
1021 | } |
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 | { |
1040 | g_return_if_fail (channel != NULL); |
1041 | |
1042 | channel->close_on_unref = do_close; |
1043 | } |
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 | { |
1059 | g_return_val_if_fail (channel != NULL, FALSE); |
1060 | |
1061 | return channel->close_on_unref; |
1062 | } |
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 | { |
1093 | 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 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
1100 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
1101 | G_IO_STATUS_ERROR); |
1102 | g_return_val_if_fail (channel->is_seekable, G_IO_STATUS_ERROR); |
1103 | |
1104 | switch (type) |
1105 | { |
1106 | case G_SEEK_CUR: /* The user is seeking relative to the head of the buffer */ |
1107 | if (channel->use_buffer) |
1108 | { |
1109 | if (channel->do_encode && channel->encoded_read_buf |
1110 | && channel->encoded_read_buf->len > 0) |
1111 | { |
1112 | g_warning ("Seek type G_SEEK_CUR not allowed for this" |
1113 | " channel's encoding." ); |
1114 | return G_IO_STATUS_ERROR; |
1115 | } |
1116 | if (channel->read_buf) |
1117 | offset -= channel->read_buf->len; |
1118 | if (channel->encoded_read_buf) |
1119 | { |
1120 | 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 | offset -= channel->encoded_read_buf->len; |
1128 | } |
1129 | } |
1130 | break; |
1131 | case G_SEEK_SET: |
1132 | case G_SEEK_END: |
1133 | break; |
1134 | default: |
1135 | g_warning ("g_io_channel_seek_position: unknown seek type" ); |
1136 | return G_IO_STATUS_ERROR; |
1137 | } |
1138 | |
1139 | if (channel->use_buffer) |
1140 | { |
1141 | status = g_io_channel_flush (channel, error); |
1142 | if (status != G_IO_STATUS_NORMAL) |
1143 | return status; |
1144 | } |
1145 | |
1146 | status = channel->funcs->io_seek (channel, offset, type, error); |
1147 | |
1148 | if ((status == G_IO_STATUS_NORMAL) && (channel->use_buffer)) |
1149 | { |
1150 | if (channel->read_buf) |
1151 | g_string_truncate (string: channel->read_buf, len: 0); |
1152 | |
1153 | /* Conversion state no longer matches position in file */ |
1154 | if (channel->read_cd != (GIConv) -1) |
1155 | g_iconv (converter: channel->read_cd, NULL, NULL, NULL, NULL); |
1156 | if (channel->write_cd != (GIConv) -1) |
1157 | g_iconv (converter: channel->write_cd, NULL, NULL, NULL, NULL); |
1158 | |
1159 | if (channel->encoded_read_buf) |
1160 | { |
1161 | g_assert (channel->encoded_read_buf->len == 0 || !channel->do_encode); |
1162 | g_string_truncate (string: channel->encoded_read_buf, len: 0); |
1163 | } |
1164 | |
1165 | if (channel->partial_write_buf[0] != '\0') |
1166 | { |
1167 | g_warning ("Partial character at end of write buffer not flushed." ); |
1168 | channel->partial_write_buf[0] = '\0'; |
1169 | } |
1170 | } |
1171 | |
1172 | return status; |
1173 | } |
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 | { |
1190 | GIOStatus status; |
1191 | gsize this_time = 1, bytes_written = 0; |
1192 | |
1193 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
1194 | g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR); |
1195 | |
1196 | if (channel->write_buf == NULL || channel->write_buf->len == 0) |
1197 | return G_IO_STATUS_NORMAL; |
1198 | |
1199 | do |
1200 | { |
1201 | g_assert (this_time > 0); |
1202 | |
1203 | status = channel->funcs->io_write (channel, |
1204 | channel->write_buf->str + bytes_written, |
1205 | channel->write_buf->len - bytes_written, |
1206 | &this_time, error); |
1207 | bytes_written += this_time; |
1208 | } |
1209 | while ((bytes_written < channel->write_buf->len) |
1210 | && (status == G_IO_STATUS_NORMAL)); |
1211 | |
1212 | g_string_erase (string: channel->write_buf, pos: 0, len: bytes_written); |
1213 | |
1214 | return status; |
1215 | } |
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 | { |
1246 | g_return_if_fail (channel != NULL); |
1247 | |
1248 | if (channel->encoding != NULL) |
1249 | { |
1250 | g_warning ("Need to have NULL encoding to set the buffering state of the " |
1251 | "channel." ); |
1252 | return; |
1253 | } |
1254 | |
1255 | g_return_if_fail (!channel->read_buf || channel->read_buf->len == 0); |
1256 | g_return_if_fail (!channel->write_buf || channel->write_buf->len == 0); |
1257 | |
1258 | channel->use_buffer = buffered; |
1259 | } |
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 | { |
1272 | g_return_val_if_fail (channel != NULL, FALSE); |
1273 | |
1274 | return channel->use_buffer; |
1275 | } |
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 | { |
1325 | GIConv read_cd, write_cd; |
1326 | #ifndef G_DISABLE_ASSERT |
1327 | gboolean did_encode; |
1328 | #endif |
1329 | |
1330 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
1331 | g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR); |
1332 | |
1333 | /* Make sure the encoded buffers are empty */ |
1334 | |
1335 | g_return_val_if_fail (!channel->do_encode || !channel->encoded_read_buf || |
1336 | channel->encoded_read_buf->len == 0, G_IO_STATUS_ERROR); |
1337 | |
1338 | if (!channel->use_buffer) |
1339 | { |
1340 | g_warning ("Need to set the channel buffered before setting the encoding." ); |
1341 | g_warning ("Assuming this is what you meant and acting accordingly." ); |
1342 | |
1343 | channel->use_buffer = TRUE; |
1344 | } |
1345 | |
1346 | if (channel->partial_write_buf[0] != '\0') |
1347 | { |
1348 | g_warning ("Partial character at end of write buffer not flushed." ); |
1349 | channel->partial_write_buf[0] = '\0'; |
1350 | } |
1351 | |
1352 | #ifndef G_DISABLE_ASSERT |
1353 | did_encode = channel->do_encode; |
1354 | #endif |
1355 | |
1356 | if (!encoding || strcmp (s1: encoding, s2: "UTF8" ) == 0 || strcmp (s1: encoding, s2: "UTF-8" ) == 0) |
1357 | { |
1358 | channel->do_encode = FALSE; |
1359 | read_cd = write_cd = (GIConv) -1; |
1360 | } |
1361 | else |
1362 | { |
1363 | gint err = 0; |
1364 | const gchar *from_enc = NULL, *to_enc = NULL; |
1365 | |
1366 | if (channel->is_readable) |
1367 | { |
1368 | read_cd = g_iconv_open (to_codeset: "UTF-8" , from_codeset: encoding); |
1369 | |
1370 | if (read_cd == (GIConv) -1) |
1371 | { |
1372 | err = errno; |
1373 | from_enc = encoding; |
1374 | to_enc = "UTF-8" ; |
1375 | } |
1376 | } |
1377 | else |
1378 | read_cd = (GIConv) -1; |
1379 | |
1380 | if (channel->is_writeable && err == 0) |
1381 | { |
1382 | write_cd = g_iconv_open (to_codeset: encoding, from_codeset: "UTF-8" ); |
1383 | |
1384 | if (write_cd == (GIConv) -1) |
1385 | { |
1386 | err = errno; |
1387 | from_enc = "UTF-8" ; |
1388 | to_enc = encoding; |
1389 | } |
1390 | } |
1391 | else |
1392 | write_cd = (GIConv) -1; |
1393 | |
1394 | if (err != 0) |
1395 | { |
1396 | g_assert (from_enc); |
1397 | g_assert (to_enc); |
1398 | |
1399 | if (err == EINVAL) |
1400 | g_set_error (err: error, G_CONVERT_ERROR, code: G_CONVERT_ERROR_NO_CONVERSION, |
1401 | _("Conversion from character set “%s” to “%s” is not supported" ), |
1402 | from_enc, to_enc); |
1403 | else |
1404 | g_set_error (err: error, G_CONVERT_ERROR, code: G_CONVERT_ERROR_FAILED, |
1405 | _("Could not open converter from “%s” to “%s”: %s" ), |
1406 | from_enc, to_enc, g_strerror (errnum: err)); |
1407 | |
1408 | if (read_cd != (GIConv) -1) |
1409 | g_iconv_close (converter: read_cd); |
1410 | if (write_cd != (GIConv) -1) |
1411 | g_iconv_close (converter: write_cd); |
1412 | |
1413 | return G_IO_STATUS_ERROR; |
1414 | } |
1415 | |
1416 | channel->do_encode = TRUE; |
1417 | } |
1418 | |
1419 | /* The encoding is ok, so set the fields in channel */ |
1420 | |
1421 | if (channel->read_cd != (GIConv) -1) |
1422 | g_iconv_close (converter: channel->read_cd); |
1423 | if (channel->write_cd != (GIConv) -1) |
1424 | g_iconv_close (converter: channel->write_cd); |
1425 | |
1426 | if (channel->encoded_read_buf && channel->encoded_read_buf->len > 0) |
1427 | { |
1428 | 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 | g_string_prepend_len (string: channel->read_buf, val: channel->encoded_read_buf->str, |
1435 | len: channel->encoded_read_buf->len); |
1436 | g_string_truncate (string: channel->encoded_read_buf, len: 0); |
1437 | } |
1438 | |
1439 | channel->read_cd = read_cd; |
1440 | channel->write_cd = write_cd; |
1441 | |
1442 | g_free (mem: channel->encoding); |
1443 | channel->encoding = g_strdup (str: encoding); |
1444 | |
1445 | return G_IO_STATUS_NORMAL; |
1446 | } |
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 | { |
1462 | g_return_val_if_fail (channel != NULL, NULL); |
1463 | |
1464 | return channel->encoding; |
1465 | } |
1466 | |
1467 | static GIOStatus |
1468 | g_io_channel_fill_buffer (GIOChannel *channel, |
1469 | GError **err) |
1470 | { |
1471 | gsize read_size, cur_len, oldlen; |
1472 | GIOStatus status; |
1473 | |
1474 | if (channel->is_seekable && channel->write_buf && channel->write_buf->len > 0) |
1475 | { |
1476 | status = g_io_channel_flush (channel, error: err); |
1477 | if (status != G_IO_STATUS_NORMAL) |
1478 | return status; |
1479 | } |
1480 | if (channel->is_seekable && channel->partial_write_buf[0] != '\0') |
1481 | { |
1482 | g_warning ("Partial character at end of write buffer not flushed." ); |
1483 | channel->partial_write_buf[0] = '\0'; |
1484 | } |
1485 | |
1486 | if (!channel->read_buf) |
1487 | channel->read_buf = g_string_sized_new (dfl_size: channel->buf_size); |
1488 | |
1489 | cur_len = channel->read_buf->len; |
1490 | |
1491 | g_string_set_size (string: channel->read_buf, len: channel->read_buf->len + channel->buf_size); |
1492 | |
1493 | status = channel->funcs->io_read (channel, channel->read_buf->str + cur_len, |
1494 | channel->buf_size, &read_size, err); |
1495 | |
1496 | g_assert ((status == G_IO_STATUS_NORMAL) || (read_size == 0)); |
1497 | |
1498 | g_string_truncate (string: channel->read_buf, len: read_size + cur_len); |
1499 | |
1500 | if ((status != G_IO_STATUS_NORMAL) && |
1501 | ((status != G_IO_STATUS_EOF) || (channel->read_buf->len == 0))) |
1502 | return status; |
1503 | |
1504 | g_assert (channel->read_buf->len > 0); |
1505 | |
1506 | if (channel->encoded_read_buf) |
1507 | oldlen = channel->encoded_read_buf->len; |
1508 | else |
1509 | { |
1510 | oldlen = 0; |
1511 | if (channel->encoding) |
1512 | channel->encoded_read_buf = g_string_sized_new (dfl_size: channel->buf_size); |
1513 | } |
1514 | |
1515 | if (channel->do_encode) |
1516 | { |
1517 | gsize errnum, inbytes_left, outbytes_left; |
1518 | gchar *inbuf, *outbuf; |
1519 | int errval; |
1520 | |
1521 | g_assert (channel->encoded_read_buf); |
1522 | |
1523 | reencode: |
1524 | |
1525 | inbytes_left = channel->read_buf->len; |
1526 | outbytes_left = MAX (channel->read_buf->len, |
1527 | channel->encoded_read_buf->allocated_len |
1528 | - channel->encoded_read_buf->len - 1); /* 1 for NULL */ |
1529 | outbytes_left = MAX (outbytes_left, 6); |
1530 | |
1531 | inbuf = channel->read_buf->str; |
1532 | g_string_set_size (string: channel->encoded_read_buf, |
1533 | len: channel->encoded_read_buf->len + outbytes_left); |
1534 | outbuf = channel->encoded_read_buf->str + channel->encoded_read_buf->len |
1535 | - outbytes_left; |
1536 | |
1537 | errnum = g_iconv (converter: channel->read_cd, inbuf: &inbuf, inbytes_left: &inbytes_left, |
1538 | outbuf: &outbuf, outbytes_left: &outbytes_left); |
1539 | errval = errno; |
1540 | |
1541 | g_assert (inbuf + inbytes_left == channel->read_buf->str |
1542 | + channel->read_buf->len); |
1543 | g_assert (outbuf + outbytes_left == channel->encoded_read_buf->str |
1544 | + channel->encoded_read_buf->len); |
1545 | |
1546 | g_string_erase (string: channel->read_buf, pos: 0, |
1547 | len: channel->read_buf->len - inbytes_left); |
1548 | g_string_truncate (string: channel->encoded_read_buf, |
1549 | len: channel->encoded_read_buf->len - outbytes_left); |
1550 | |
1551 | if (errnum == (gsize) -1) |
1552 | { |
1553 | switch (errval) |
1554 | { |
1555 | case EINVAL: |
1556 | if ((oldlen == channel->encoded_read_buf->len) |
1557 | && (status == G_IO_STATUS_EOF)) |
1558 | status = G_IO_STATUS_EOF; |
1559 | else |
1560 | status = G_IO_STATUS_NORMAL; |
1561 | break; |
1562 | case E2BIG: |
1563 | /* Buffer size at least 6, wrote at least on character */ |
1564 | g_assert (inbuf != channel->read_buf->str); |
1565 | goto reencode; |
1566 | case EILSEQ: |
1567 | if (oldlen < channel->encoded_read_buf->len) |
1568 | status = G_IO_STATUS_NORMAL; |
1569 | else |
1570 | { |
1571 | g_set_error_literal (err, G_CONVERT_ERROR, |
1572 | code: G_CONVERT_ERROR_ILLEGAL_SEQUENCE, |
1573 | _("Invalid byte sequence in conversion input" )); |
1574 | return G_IO_STATUS_ERROR; |
1575 | } |
1576 | break; |
1577 | default: |
1578 | g_assert (errval != EBADF); /* The converter should be open */ |
1579 | g_set_error (err, G_CONVERT_ERROR, code: G_CONVERT_ERROR_FAILED, |
1580 | _("Error during conversion: %s" ), g_strerror (errnum: errval)); |
1581 | return G_IO_STATUS_ERROR; |
1582 | } |
1583 | } |
1584 | g_assert ((status != G_IO_STATUS_NORMAL) |
1585 | || (channel->encoded_read_buf->len > 0)); |
1586 | } |
1587 | else if (channel->encoding) /* UTF-8 */ |
1588 | { |
1589 | gchar *nextchar, *lastchar; |
1590 | |
1591 | g_assert (channel->encoded_read_buf); |
1592 | |
1593 | nextchar = channel->read_buf->str; |
1594 | lastchar = channel->read_buf->str + channel->read_buf->len; |
1595 | |
1596 | while (nextchar < lastchar) |
1597 | { |
1598 | gunichar val_char; |
1599 | |
1600 | val_char = g_utf8_get_char_validated (p: nextchar, max_len: lastchar - nextchar); |
1601 | |
1602 | switch (val_char) |
1603 | { |
1604 | case -2: |
1605 | /* stop, leave partial character in buffer */ |
1606 | lastchar = nextchar; |
1607 | break; |
1608 | case -1: |
1609 | if (oldlen < channel->encoded_read_buf->len) |
1610 | status = G_IO_STATUS_NORMAL; |
1611 | else |
1612 | { |
1613 | g_set_error_literal (err, G_CONVERT_ERROR, |
1614 | code: G_CONVERT_ERROR_ILLEGAL_SEQUENCE, |
1615 | _("Invalid byte sequence in conversion input" )); |
1616 | status = G_IO_STATUS_ERROR; |
1617 | } |
1618 | lastchar = nextchar; |
1619 | break; |
1620 | default: |
1621 | nextchar = g_utf8_next_char (nextchar); |
1622 | break; |
1623 | } |
1624 | } |
1625 | |
1626 | if (lastchar > channel->read_buf->str) |
1627 | { |
1628 | gint copy_len = lastchar - channel->read_buf->str; |
1629 | |
1630 | g_string_append_len (string: channel->encoded_read_buf, val: channel->read_buf->str, |
1631 | len: copy_len); |
1632 | g_string_erase (string: channel->read_buf, pos: 0, len: copy_len); |
1633 | } |
1634 | } |
1635 | |
1636 | return status; |
1637 | } |
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 | { |
1665 | GIOStatus status; |
1666 | gsize got_length; |
1667 | |
1668 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
1669 | g_return_val_if_fail (str_return != NULL, G_IO_STATUS_ERROR); |
1670 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
1671 | G_IO_STATUS_ERROR); |
1672 | g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); |
1673 | |
1674 | status = g_io_channel_read_line_backend (channel, length: &got_length, terminator_pos, error); |
1675 | |
1676 | if (length && status != G_IO_STATUS_ERROR) |
1677 | *length = got_length; |
1678 | |
1679 | if (status == G_IO_STATUS_NORMAL) |
1680 | { |
1681 | 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 | g_assert (USE_BUF (channel)); |
1688 | line = g_memdup2 (USE_BUF (channel)->str, byte_size: got_length + 1); |
1689 | line[got_length] = '\0'; |
1690 | *str_return = g_steal_pointer (&line); |
1691 | g_string_erase (USE_BUF (channel), pos: 0, len: got_length); |
1692 | } |
1693 | else |
1694 | *str_return = NULL; |
1695 | |
1696 | return status; |
1697 | } |
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 | { |
1719 | gsize length; |
1720 | GIOStatus status; |
1721 | |
1722 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
1723 | g_return_val_if_fail (buffer != NULL, G_IO_STATUS_ERROR); |
1724 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
1725 | G_IO_STATUS_ERROR); |
1726 | g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); |
1727 | |
1728 | if (buffer->len > 0) |
1729 | g_string_truncate (string: buffer, len: 0); /* clear out the buffer */ |
1730 | |
1731 | status = g_io_channel_read_line_backend (channel, length: &length, terminator_pos, error); |
1732 | |
1733 | if (status == G_IO_STATUS_NORMAL) |
1734 | { |
1735 | g_assert (USE_BUF (channel)); |
1736 | g_string_append_len (string: buffer, USE_BUF (channel)->str, len: length); |
1737 | g_string_erase (USE_BUF (channel), pos: 0, len: length); |
1738 | } |
1739 | |
1740 | return status; |
1741 | } |
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 | { |
1750 | GIOStatus status; |
1751 | gsize checked_to, line_term_len, line_length, got_term_len; |
1752 | gboolean first_time = TRUE; |
1753 | |
1754 | if (!channel->use_buffer) |
1755 | { |
1756 | /* Can't do a raw read in read_line */ |
1757 | g_set_error_literal (err: error, G_CONVERT_ERROR, code: G_CONVERT_ERROR_FAILED, |
1758 | _("Can’t do a raw read in g_io_channel_read_line_string" )); |
1759 | return G_IO_STATUS_ERROR; |
1760 | } |
1761 | |
1762 | status = G_IO_STATUS_NORMAL; |
1763 | |
1764 | if (channel->line_term) |
1765 | line_term_len = channel->line_term_len; |
1766 | else |
1767 | 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 | checked_to = 0; |
1773 | |
1774 | while (TRUE) |
1775 | { |
1776 | gchar *nextchar, *lastchar; |
1777 | GString *use_buf; |
1778 | |
1779 | if (!first_time || (BUF_LEN (USE_BUF (channel)) == 0)) |
1780 | { |
1781 | read_again: |
1782 | status = g_io_channel_fill_buffer (channel, err: error); |
1783 | switch (status) |
1784 | { |
1785 | case G_IO_STATUS_NORMAL: |
1786 | if (BUF_LEN (USE_BUF (channel)) == 0) |
1787 | /* Can happen when using conversion and only read |
1788 | * part of a character |
1789 | */ |
1790 | { |
1791 | first_time = FALSE; |
1792 | continue; |
1793 | } |
1794 | break; |
1795 | case G_IO_STATUS_EOF: |
1796 | if (BUF_LEN (USE_BUF (channel)) == 0) |
1797 | { |
1798 | if (length) |
1799 | *length = 0; |
1800 | |
1801 | if (channel->encoding && channel->read_buf->len != 0) |
1802 | { |
1803 | g_set_error_literal (err: error, G_CONVERT_ERROR, |
1804 | code: G_CONVERT_ERROR_PARTIAL_INPUT, |
1805 | _("Leftover unconverted data in " |
1806 | "read buffer" )); |
1807 | return G_IO_STATUS_ERROR; |
1808 | } |
1809 | else |
1810 | return G_IO_STATUS_EOF; |
1811 | } |
1812 | break; |
1813 | default: |
1814 | if (length) |
1815 | *length = 0; |
1816 | return status; |
1817 | } |
1818 | } |
1819 | |
1820 | g_assert (BUF_LEN (USE_BUF (channel)) != 0); |
1821 | |
1822 | use_buf = USE_BUF (channel); /* The buffer has been created by this point */ |
1823 | |
1824 | first_time = FALSE; |
1825 | |
1826 | lastchar = use_buf->str + use_buf->len; |
1827 | |
1828 | for (nextchar = use_buf->str + checked_to; nextchar < lastchar; |
1829 | channel->encoding ? nextchar = g_utf8_next_char (nextchar) : nextchar++) |
1830 | { |
1831 | if (channel->line_term) |
1832 | { |
1833 | if (memcmp (s1: channel->line_term, s2: nextchar, n: line_term_len) == 0) |
1834 | { |
1835 | line_length = nextchar - use_buf->str; |
1836 | got_term_len = line_term_len; |
1837 | goto done; |
1838 | } |
1839 | } |
1840 | else /* auto detect */ |
1841 | { |
1842 | switch (*nextchar) |
1843 | { |
1844 | case '\n': /* unix */ |
1845 | line_length = nextchar - use_buf->str; |
1846 | got_term_len = 1; |
1847 | goto done; |
1848 | case '\r': /* Warning: do not use with sockets */ |
1849 | line_length = nextchar - use_buf->str; |
1850 | if ((nextchar == lastchar - 1) && (status != G_IO_STATUS_EOF) |
1851 | && (lastchar == use_buf->str + use_buf->len)) |
1852 | goto read_again; /* Try to read more data */ |
1853 | if ((nextchar < lastchar - 1) && (*(nextchar + 1) == '\n')) /* dos */ |
1854 | got_term_len = 2; |
1855 | else /* mac */ |
1856 | got_term_len = 1; |
1857 | goto done; |
1858 | case '\xe2': /* Unicode paragraph separator */ |
1859 | if (strncmp (s1: "\xe2\x80\xa9" , s2: nextchar, n: 3) == 0) |
1860 | { |
1861 | line_length = nextchar - use_buf->str; |
1862 | got_term_len = 3; |
1863 | goto done; |
1864 | } |
1865 | break; |
1866 | case '\0': /* Embedded null in input */ |
1867 | line_length = nextchar - use_buf->str; |
1868 | got_term_len = 1; |
1869 | goto done; |
1870 | default: /* no match */ |
1871 | break; |
1872 | } |
1873 | } |
1874 | } |
1875 | |
1876 | /* If encoding != NULL, valid UTF-8, didn't overshoot */ |
1877 | g_assert (nextchar == lastchar); |
1878 | |
1879 | /* Check for EOF */ |
1880 | |
1881 | if (status == G_IO_STATUS_EOF) |
1882 | { |
1883 | if (channel->encoding && channel->read_buf->len > 0) |
1884 | { |
1885 | g_set_error_literal (err: error, G_CONVERT_ERROR, code: G_CONVERT_ERROR_PARTIAL_INPUT, |
1886 | _("Channel terminates in a partial character" )); |
1887 | return G_IO_STATUS_ERROR; |
1888 | } |
1889 | line_length = use_buf->len; |
1890 | got_term_len = 0; |
1891 | break; |
1892 | } |
1893 | |
1894 | if (use_buf->len > line_term_len - 1) |
1895 | checked_to = use_buf->len - (line_term_len - 1); |
1896 | else |
1897 | checked_to = 0; |
1898 | } |
1899 | |
1900 | done: |
1901 | |
1902 | if (terminator_pos) |
1903 | *terminator_pos = line_length; |
1904 | |
1905 | if (length) |
1906 | *length = line_length + got_term_len; |
1907 | |
1908 | return G_IO_STATUS_NORMAL; |
1909 | } |
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 | { |
1934 | GIOStatus status; |
1935 | |
1936 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
1937 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
1938 | G_IO_STATUS_ERROR); |
1939 | g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); |
1940 | |
1941 | if (str_return) |
1942 | *str_return = NULL; |
1943 | if (length) |
1944 | *length = 0; |
1945 | |
1946 | if (!channel->use_buffer) |
1947 | { |
1948 | g_set_error_literal (err: error, G_CONVERT_ERROR, code: G_CONVERT_ERROR_FAILED, |
1949 | _("Can’t do a raw read in g_io_channel_read_to_end" )); |
1950 | return G_IO_STATUS_ERROR; |
1951 | } |
1952 | |
1953 | do |
1954 | status = g_io_channel_fill_buffer (channel, err: error); |
1955 | while (status == G_IO_STATUS_NORMAL); |
1956 | |
1957 | if (status != G_IO_STATUS_EOF) |
1958 | return status; |
1959 | |
1960 | if (channel->encoding && channel->read_buf->len > 0) |
1961 | { |
1962 | g_set_error_literal (err: error, G_CONVERT_ERROR, code: G_CONVERT_ERROR_PARTIAL_INPUT, |
1963 | _("Channel terminates in a partial character" )); |
1964 | return G_IO_STATUS_ERROR; |
1965 | } |
1966 | |
1967 | if (USE_BUF (channel) == NULL) |
1968 | { |
1969 | /* length is already set to zero */ |
1970 | if (str_return) |
1971 | *str_return = g_strdup (str: "" ); |
1972 | } |
1973 | else |
1974 | { |
1975 | if (length) |
1976 | *length = USE_BUF (channel)->len; |
1977 | |
1978 | if (str_return) |
1979 | *str_return = g_string_free (USE_BUF (channel), FALSE); |
1980 | else |
1981 | g_string_free (USE_BUF (channel), TRUE); |
1982 | |
1983 | if (channel->encoding) |
1984 | channel->encoded_read_buf = NULL; |
1985 | else |
1986 | channel->read_buf = NULL; |
1987 | } |
1988 | |
1989 | return G_IO_STATUS_NORMAL; |
1990 | } |
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 | { |
2018 | GIOStatus status; |
2019 | gsize got_bytes; |
2020 | |
2021 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
2022 | g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR); |
2023 | g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); |
2024 | |
2025 | if (count == 0) |
2026 | { |
2027 | if (bytes_read) |
2028 | *bytes_read = 0; |
2029 | return G_IO_STATUS_NORMAL; |
2030 | } |
2031 | g_return_val_if_fail (buf != NULL, G_IO_STATUS_ERROR); |
2032 | |
2033 | if (!channel->use_buffer) |
2034 | { |
2035 | gsize tmp_bytes; |
2036 | |
2037 | g_assert (!channel->read_buf || channel->read_buf->len == 0); |
2038 | |
2039 | status = channel->funcs->io_read (channel, buf, count, &tmp_bytes, error); |
2040 | |
2041 | if (bytes_read) |
2042 | *bytes_read = tmp_bytes; |
2043 | |
2044 | return status; |
2045 | } |
2046 | |
2047 | status = G_IO_STATUS_NORMAL; |
2048 | |
2049 | while (BUF_LEN (USE_BUF (channel)) < count && status == G_IO_STATUS_NORMAL) |
2050 | status = g_io_channel_fill_buffer (channel, err: error); |
2051 | |
2052 | /* Only return an error if we have no data */ |
2053 | |
2054 | if (BUF_LEN (USE_BUF (channel)) == 0) |
2055 | { |
2056 | g_assert (status != G_IO_STATUS_NORMAL); |
2057 | |
2058 | if (status == G_IO_STATUS_EOF && channel->encoding |
2059 | && BUF_LEN (channel->read_buf) > 0) |
2060 | { |
2061 | g_set_error_literal (err: error, G_CONVERT_ERROR, |
2062 | code: G_CONVERT_ERROR_PARTIAL_INPUT, |
2063 | _("Leftover unconverted data in read buffer" )); |
2064 | status = G_IO_STATUS_ERROR; |
2065 | } |
2066 | |
2067 | if (bytes_read) |
2068 | *bytes_read = 0; |
2069 | |
2070 | return status; |
2071 | } |
2072 | |
2073 | if (status == G_IO_STATUS_ERROR) |
2074 | g_clear_error (err: error); |
2075 | |
2076 | got_bytes = MIN (count, BUF_LEN (USE_BUF (channel))); |
2077 | |
2078 | g_assert (got_bytes > 0); |
2079 | |
2080 | if (channel->encoding) |
2081 | /* Don't validate for NULL encoding, binary safe */ |
2082 | { |
2083 | gchar *nextchar, *prevchar; |
2084 | |
2085 | g_assert (USE_BUF (channel) == channel->encoded_read_buf); |
2086 | |
2087 | nextchar = channel->encoded_read_buf->str; |
2088 | |
2089 | do |
2090 | { |
2091 | prevchar = nextchar; |
2092 | nextchar = g_utf8_next_char (nextchar); |
2093 | g_assert (nextchar != prevchar); /* Possible for *prevchar of -1 or -2 */ |
2094 | } |
2095 | while (nextchar < channel->encoded_read_buf->str + got_bytes); |
2096 | |
2097 | if (nextchar > channel->encoded_read_buf->str + got_bytes) |
2098 | got_bytes = prevchar - channel->encoded_read_buf->str; |
2099 | |
2100 | g_assert (got_bytes > 0 || count < 6); |
2101 | } |
2102 | |
2103 | memcpy (dest: buf, USE_BUF (channel)->str, n: got_bytes); |
2104 | g_string_erase (USE_BUF (channel), pos: 0, len: got_bytes); |
2105 | |
2106 | if (bytes_read) |
2107 | *bytes_read = got_bytes; |
2108 | |
2109 | return G_IO_STATUS_NORMAL; |
2110 | } |
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 | { |
2129 | GIOStatus status = G_IO_STATUS_NORMAL; |
2130 | |
2131 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
2132 | g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR); |
2133 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
2134 | G_IO_STATUS_ERROR); |
2135 | g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); |
2136 | |
2137 | while (BUF_LEN (channel->encoded_read_buf) == 0 && status == G_IO_STATUS_NORMAL) |
2138 | status = g_io_channel_fill_buffer (channel, err: error); |
2139 | |
2140 | /* Only return an error if we have no data */ |
2141 | |
2142 | if (BUF_LEN (USE_BUF (channel)) == 0) |
2143 | { |
2144 | g_assert (status != G_IO_STATUS_NORMAL); |
2145 | |
2146 | if (status == G_IO_STATUS_EOF && BUF_LEN (channel->read_buf) > 0) |
2147 | { |
2148 | g_set_error_literal (err: error, G_CONVERT_ERROR, |
2149 | code: G_CONVERT_ERROR_PARTIAL_INPUT, |
2150 | _("Leftover unconverted data in read buffer" )); |
2151 | status = G_IO_STATUS_ERROR; |
2152 | } |
2153 | |
2154 | if (thechar) |
2155 | *thechar = (gunichar) -1; |
2156 | |
2157 | return status; |
2158 | } |
2159 | |
2160 | if (status == G_IO_STATUS_ERROR) |
2161 | g_clear_error (err: error); |
2162 | |
2163 | if (thechar) |
2164 | *thechar = g_utf8_get_char (p: channel->encoded_read_buf->str); |
2165 | |
2166 | g_string_erase (string: channel->encoded_read_buf, pos: 0, |
2167 | g_utf8_next_char (channel->encoded_read_buf->str) |
2168 | - channel->encoded_read_buf->str); |
2169 | |
2170 | return G_IO_STATUS_NORMAL; |
2171 | } |
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 | { |
2203 | gsize count_unsigned; |
2204 | GIOStatus status; |
2205 | gssize wrote_bytes = 0; |
2206 | |
2207 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
2208 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
2209 | G_IO_STATUS_ERROR); |
2210 | g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR); |
2211 | |
2212 | if ((count < 0) && buf) |
2213 | count = strlen (s: buf); |
2214 | count_unsigned = count; |
2215 | |
2216 | if (count_unsigned == 0) |
2217 | { |
2218 | if (bytes_written) |
2219 | *bytes_written = 0; |
2220 | return G_IO_STATUS_NORMAL; |
2221 | } |
2222 | |
2223 | g_return_val_if_fail (buf != NULL, G_IO_STATUS_ERROR); |
2224 | g_return_val_if_fail (count_unsigned > 0, G_IO_STATUS_ERROR); |
2225 | |
2226 | /* Raw write case */ |
2227 | |
2228 | if (!channel->use_buffer) |
2229 | { |
2230 | gsize tmp_bytes; |
2231 | |
2232 | g_assert (!channel->write_buf || channel->write_buf->len == 0); |
2233 | g_assert (channel->partial_write_buf[0] == '\0'); |
2234 | |
2235 | status = channel->funcs->io_write (channel, buf, count_unsigned, |
2236 | &tmp_bytes, error); |
2237 | |
2238 | if (bytes_written) |
2239 | *bytes_written = tmp_bytes; |
2240 | |
2241 | return status; |
2242 | } |
2243 | |
2244 | /* General case */ |
2245 | |
2246 | if (channel->is_seekable && (( BUF_LEN (channel->read_buf) > 0) |
2247 | || (BUF_LEN (channel->encoded_read_buf) > 0))) |
2248 | { |
2249 | if (channel->do_encode && BUF_LEN (channel->encoded_read_buf) > 0) |
2250 | { |
2251 | g_warning ("Mixed reading and writing not allowed on encoded files" ); |
2252 | return G_IO_STATUS_ERROR; |
2253 | } |
2254 | status = g_io_channel_seek_position (channel, offset: 0, type: G_SEEK_CUR, error); |
2255 | if (status != G_IO_STATUS_NORMAL) |
2256 | { |
2257 | if (bytes_written) |
2258 | *bytes_written = 0; |
2259 | return status; |
2260 | } |
2261 | } |
2262 | |
2263 | if (!channel->write_buf) |
2264 | channel->write_buf = g_string_sized_new (dfl_size: channel->buf_size); |
2265 | |
2266 | while (wrote_bytes < count) |
2267 | { |
2268 | 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 | if (channel->write_buf->len >= channel->buf_size - MAX_CHAR_SIZE) |
2277 | { |
2278 | gsize did_write = 0, this_time; |
2279 | |
2280 | do |
2281 | { |
2282 | status = channel->funcs->io_write (channel, channel->write_buf->str |
2283 | + did_write, channel->write_buf->len |
2284 | - did_write, &this_time, error); |
2285 | did_write += this_time; |
2286 | } |
2287 | while (status == G_IO_STATUS_NORMAL && |
2288 | did_write < MIN (channel->write_buf->len, MAX_CHAR_SIZE)); |
2289 | |
2290 | g_string_erase (string: channel->write_buf, pos: 0, len: did_write); |
2291 | |
2292 | if (status != G_IO_STATUS_NORMAL) |
2293 | { |
2294 | if (status == G_IO_STATUS_AGAIN && wrote_bytes > 0) |
2295 | status = G_IO_STATUS_NORMAL; |
2296 | if (bytes_written) |
2297 | *bytes_written = wrote_bytes; |
2298 | return status; |
2299 | } |
2300 | } |
2301 | |
2302 | space_in_buf = MAX (channel->buf_size, channel->write_buf->allocated_len - 1) |
2303 | - 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 | g_assert (space_in_buf >= MAX_CHAR_SIZE); |
2309 | |
2310 | if (!channel->encoding) |
2311 | { |
2312 | gssize write_this = MIN (space_in_buf, count_unsigned - wrote_bytes); |
2313 | |
2314 | g_string_append_len (string: channel->write_buf, val: buf, len: write_this); |
2315 | buf += write_this; |
2316 | wrote_bytes += write_this; |
2317 | } |
2318 | else |
2319 | { |
2320 | const gchar *from_buf; |
2321 | gsize from_buf_len, from_buf_old_len, left_len; |
2322 | gsize err; |
2323 | gint errnum; |
2324 | |
2325 | if (channel->partial_write_buf[0] != '\0') |
2326 | { |
2327 | g_assert (wrote_bytes == 0); |
2328 | |
2329 | from_buf = channel->partial_write_buf; |
2330 | from_buf_old_len = strlen (s: channel->partial_write_buf); |
2331 | g_assert (from_buf_old_len > 0); |
2332 | from_buf_len = MIN (6, from_buf_old_len + count_unsigned); |
2333 | |
2334 | memcpy (dest: channel->partial_write_buf + from_buf_old_len, src: buf, |
2335 | n: from_buf_len - from_buf_old_len); |
2336 | } |
2337 | else |
2338 | { |
2339 | from_buf = buf; |
2340 | from_buf_len = count_unsigned - wrote_bytes; |
2341 | from_buf_old_len = 0; |
2342 | } |
2343 | |
2344 | reconvert: |
2345 | |
2346 | if (!channel->do_encode) /* UTF-8 encoding */ |
2347 | { |
2348 | const gchar *badchar; |
2349 | gsize try_len = MIN (from_buf_len, space_in_buf); |
2350 | |
2351 | /* UTF-8, just validate, emulate g_iconv */ |
2352 | |
2353 | if (!g_utf8_validate_len (str: from_buf, max_len: try_len, end: &badchar)) |
2354 | { |
2355 | gunichar try_char; |
2356 | gsize incomplete_len = from_buf + try_len - badchar; |
2357 | |
2358 | left_len = from_buf + from_buf_len - badchar; |
2359 | |
2360 | try_char = g_utf8_get_char_validated (p: badchar, max_len: incomplete_len); |
2361 | |
2362 | switch (try_char) |
2363 | { |
2364 | case -2: |
2365 | g_assert (incomplete_len < 6); |
2366 | if (try_len == from_buf_len) |
2367 | { |
2368 | errnum = EINVAL; |
2369 | err = (gsize) -1; |
2370 | } |
2371 | else |
2372 | { |
2373 | errnum = 0; |
2374 | err = (gsize) 0; |
2375 | } |
2376 | break; |
2377 | case -1: |
2378 | g_warning ("Invalid UTF-8 passed to g_io_channel_write_chars()." ); |
2379 | /* FIXME bail here? */ |
2380 | errnum = EILSEQ; |
2381 | err = (gsize) -1; |
2382 | break; |
2383 | default: |
2384 | g_assert_not_reached (); |
2385 | err = (gsize) -1; |
2386 | errnum = 0; /* Don't confuse the compiler */ |
2387 | } |
2388 | } |
2389 | else |
2390 | { |
2391 | err = (gsize) 0; |
2392 | errnum = 0; |
2393 | left_len = from_buf_len - try_len; |
2394 | } |
2395 | |
2396 | g_string_append_len (string: channel->write_buf, val: from_buf, |
2397 | len: from_buf_len - left_len); |
2398 | from_buf += from_buf_len - left_len; |
2399 | } |
2400 | else |
2401 | { |
2402 | gchar *outbuf; |
2403 | |
2404 | left_len = from_buf_len; |
2405 | g_string_set_size (string: channel->write_buf, len: channel->write_buf->len |
2406 | + space_in_buf); |
2407 | outbuf = channel->write_buf->str + channel->write_buf->len |
2408 | - space_in_buf; |
2409 | err = g_iconv (converter: channel->write_cd, inbuf: (gchar **) &from_buf, inbytes_left: &left_len, |
2410 | outbuf: &outbuf, outbytes_left: &space_in_buf); |
2411 | errnum = errno; |
2412 | g_string_truncate (string: channel->write_buf, len: channel->write_buf->len |
2413 | - space_in_buf); |
2414 | } |
2415 | |
2416 | if (err == (gsize) -1) |
2417 | { |
2418 | switch (errnum) |
2419 | { |
2420 | case EINVAL: |
2421 | g_assert (left_len < 6); |
2422 | |
2423 | if (from_buf_old_len == 0) |
2424 | { |
2425 | /* Not from partial_write_buf */ |
2426 | |
2427 | memcpy (dest: channel->partial_write_buf, src: from_buf, n: left_len); |
2428 | channel->partial_write_buf[left_len] = '\0'; |
2429 | if (bytes_written) |
2430 | *bytes_written = count_unsigned; |
2431 | return G_IO_STATUS_NORMAL; |
2432 | } |
2433 | |
2434 | /* Working in partial_write_buf */ |
2435 | |
2436 | if (left_len == from_buf_len) |
2437 | { |
2438 | /* Didn't convert anything, must still have |
2439 | * less than a full character |
2440 | */ |
2441 | |
2442 | g_assert (count_unsigned == from_buf_len - from_buf_old_len); |
2443 | |
2444 | channel->partial_write_buf[from_buf_len] = '\0'; |
2445 | |
2446 | if (bytes_written) |
2447 | *bytes_written = count_unsigned; |
2448 | |
2449 | return G_IO_STATUS_NORMAL; |
2450 | } |
2451 | |
2452 | g_assert (from_buf_len - left_len >= from_buf_old_len); |
2453 | |
2454 | /* We converted all the old data. This is fine */ |
2455 | |
2456 | break; |
2457 | case E2BIG: |
2458 | if (from_buf_len == left_len) |
2459 | { |
2460 | /* Nothing was written, add enough space for |
2461 | * at least one character. |
2462 | */ |
2463 | space_in_buf += MAX_CHAR_SIZE; |
2464 | goto reconvert; |
2465 | } |
2466 | break; |
2467 | case EILSEQ: |
2468 | g_set_error_literal (err: error, G_CONVERT_ERROR, |
2469 | code: G_CONVERT_ERROR_ILLEGAL_SEQUENCE, |
2470 | _("Invalid byte sequence in conversion input" )); |
2471 | if (from_buf_old_len > 0 && from_buf_len == left_len) |
2472 | g_warning ("Illegal sequence due to partial character " |
2473 | "at the end of a previous write." ); |
2474 | else |
2475 | wrote_bytes += from_buf_len - left_len - from_buf_old_len; |
2476 | if (bytes_written) |
2477 | *bytes_written = wrote_bytes; |
2478 | channel->partial_write_buf[0] = '\0'; |
2479 | return G_IO_STATUS_ERROR; |
2480 | default: |
2481 | g_set_error (err: error, G_CONVERT_ERROR, code: G_CONVERT_ERROR_FAILED, |
2482 | _("Error during conversion: %s" ), g_strerror (errnum)); |
2483 | if (from_buf_len >= left_len + from_buf_old_len) |
2484 | wrote_bytes += from_buf_len - left_len - from_buf_old_len; |
2485 | if (bytes_written) |
2486 | *bytes_written = wrote_bytes; |
2487 | channel->partial_write_buf[0] = '\0'; |
2488 | return G_IO_STATUS_ERROR; |
2489 | } |
2490 | } |
2491 | |
2492 | g_assert (from_buf_len - left_len >= from_buf_old_len); |
2493 | |
2494 | wrote_bytes += from_buf_len - left_len - from_buf_old_len; |
2495 | |
2496 | if (from_buf_old_len > 0) |
2497 | { |
2498 | /* We were working in partial_write_buf */ |
2499 | |
2500 | buf += from_buf_len - left_len - from_buf_old_len; |
2501 | channel->partial_write_buf[0] = '\0'; |
2502 | } |
2503 | else |
2504 | buf = from_buf; |
2505 | } |
2506 | } |
2507 | |
2508 | if (bytes_written) |
2509 | *bytes_written = count_unsigned; |
2510 | |
2511 | return G_IO_STATUS_NORMAL; |
2512 | } |
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 | { |
2531 | GIOStatus status; |
2532 | gchar static_buf[6]; |
2533 | gsize char_len, wrote_len; |
2534 | |
2535 | g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); |
2536 | g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR); |
2537 | g_return_val_if_fail ((error == NULL) || (*error == NULL), |
2538 | G_IO_STATUS_ERROR); |
2539 | g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR); |
2540 | |
2541 | char_len = g_unichar_to_utf8 (c: thechar, outbuf: static_buf); |
2542 | |
2543 | if (channel->partial_write_buf[0] != '\0') |
2544 | { |
2545 | g_warning ("Partial character written before writing unichar." ); |
2546 | channel->partial_write_buf[0] = '\0'; |
2547 | } |
2548 | |
2549 | status = g_io_channel_write_chars (channel, buf: static_buf, |
2550 | count: char_len, bytes_written: &wrote_len, error); |
2551 | |
2552 | /* We validate UTF-8, so we can't get a partial write */ |
2553 | |
2554 | g_assert (wrote_len == char_len || status != G_IO_STATUS_NORMAL); |
2555 | |
2556 | return status; |
2557 | } |
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) |
2582 | |