source: trunk/third/glib2/glib/giochannel.c @ 20721

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