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

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