⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 giochannel.c

📁 嵌入式下基于MiniGUI的Web Browser
💻 C
📖 第 1 页 / 共 5 页
字号:
            }          }        break;      case G_SEEK_SET:      case G_SEEK_END:        break;      default:        g_warning ("g_io_channel_seek_position: unknown seek type");        return G_IO_STATUS_ERROR;    }  if (channel->use_buffer)    {      status = g_io_channel_flush (channel, error);      if (status != G_IO_STATUS_NORMAL)        return status;    }  status = channel->funcs->io_seek (channel, offset, type, error);  if ((status == G_IO_STATUS_NORMAL) && (channel->use_buffer))    {      if (channel->read_buf)        g_string_truncate (channel->read_buf, 0);      /* Conversion state no longer matches position in file */      if (channel->read_cd != (GIConv) -1)        g_iconv (channel->read_cd, NULL, NULL, NULL, NULL);      if (channel->write_cd != (GIConv) -1)        g_iconv (channel->write_cd, NULL, NULL, NULL, NULL);      if (channel->encoded_read_buf)        {          g_assert (channel->encoded_read_buf->len == 0 || !channel->do_encode);          g_string_truncate (channel->encoded_read_buf, 0);        }      if (channel->partial_write_buf[0] != '\0')        {          g_warning ("Partial character at end of write buffer not flushed.\n");          channel->partial_write_buf[0] = '\0';        }    }  return status;}/** * g_io_channel_set_buffered: * @channel: a #GIOChannel * @buffered: whether to set the channel buffered or unbuffered * * The buffering state can only be set if the channel's encoding * is %NULL. For any other encoding, the channel must be buffered. * * A buffered channel can only be set unbuffered if the channel's * internal buffers have been flushed. Newly created channels or * channels which have returned %G_IO_STATUS_EOF * not require such a flush. For write-only channels, a call to * g_io_channel_flush () is sufficient. For all other channels, * the buffers may be flushed by a call to g_io_channel_seek_position (). * This includes the possibility of seeking with seek type %G_SEEK_CUR * and an offset of zero. Note that this means that socket-based * channels cannot be set unbuffered once they have had data * read from them. * * On unbuffered channels, it is safe to mix read and write * calls from the new and old APIs, if this is necessary for * maintaining old code. * * The default state of the channel is buffered. **/voidg_io_channel_set_buffered	(GIOChannel *channel,				 gboolean    buffered){  g_return_if_fail (channel != NULL);  if (channel->encoding != NULL)    {      g_warning ("Need to have NULL encoding to set the buffering state of the "                 "channel.\n");      return;    }  g_return_if_fail (!channel->read_buf || channel->read_buf->len == 0);  g_return_if_fail (!channel->write_buf || channel->write_buf->len == 0);  channel->use_buffer = buffered;}/** * g_io_channel_get_buffered: * @channel: a #GIOChannel. * * Returns whether @channel is buffered. * * Return Value: %TRUE if the @channel is buffered.  **/gbooleang_io_channel_get_buffered	(GIOChannel *channel){  g_return_val_if_fail (channel != NULL, FALSE);  return channel->use_buffer;}/** * g_io_channel_set_encoding: * @channel: a #GIOChannel * @encoding: the encoding type * @error: location to store an error of type #GConvertError. * * Sets the encoding for the input/output of the channel. The internal * encoding is always UTF-8. The default encoding for the * external file is UTF-8. * * The encoding %NULL is safe to use with binary data. * * The encoding can only be set if one of the following conditions * is true: * * 1. The channel was just created, and has not been written to *    or read from yet. * * 2. The channel is write-only. * * 3. The channel is a file, and the file pointer was just *    repositioned by a call to g_io_channel_seek_position(). *    (This flushes all the internal buffers.) * * 4. The current encoding is %NULL or UTF-8. * * 5. One of the (new API) read functions has just returned %G_IO_STATUS_EOF *    (or, in the case of g_io_channel_read_to_end (), %G_IO_STATUS_NORMAL). * * 6. One of the functions g_io_channel_read_chars () or g_io_channel_read_unichar () *    has returned %G_IO_STATUS_AGAIN or %G_IO_STATUS_ERROR. This may be *    useful in the case of %G_CONVERT_ERROR_ILLEGAL_SEQUENCE. *    Returning one of these statuses from g_io_channel_read_line (), *    g_io_channel_read_line_string (), or g_io_channel_read_to_end () *    does <emphasis>not</emphasis> guarantee that the encoding can be changed. * * Channels which do not meet one of the above conditions cannot call * g_io_channel_seek_position () with an offset of %G_SEEK_CUR, * and, if they are "seekable", cannot * call g_io_channel_write_chars () after calling one * of the API "read" functions. * * Return Value: %G_IO_STATUS_NORMAL if the encoding was successfully set. **/GIOStatusg_io_channel_set_encoding (GIOChannel	*channel,                           const gchar	*encoding,			   GError      **error){  GIConv read_cd, write_cd;  gboolean did_encode;  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);  g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR);  /* Make sure the encoded buffers are empty */  g_return_val_if_fail (!channel->do_encode || !channel->encoded_read_buf ||			channel->encoded_read_buf->len == 0, G_IO_STATUS_ERROR);  if (!channel->use_buffer)    {      g_warning ("Need to set the channel buffered before setting the encoding.\n");      g_warning ("Assuming this is what you meant and acting accordingly.\n");      channel->use_buffer = TRUE;    }  if (channel->partial_write_buf[0] != '\0')    {      g_warning ("Partial character at end of write buffer not flushed.\n");      channel->partial_write_buf[0] = '\0';    }  did_encode = channel->do_encode;  if (!encoding || strcmp (encoding, "UTF8") == 0 || strcmp (encoding, "UTF-8") == 0)    {      channel->do_encode = FALSE;      read_cd = write_cd = (GIConv) -1;    }  else    {      gint err = 0;      const gchar *from_enc = NULL, *to_enc = NULL;      if (channel->is_readable)        {          read_cd = g_iconv_open ("UTF-8", encoding);          if (read_cd == (GIConv) -1)            {              err = errno;              from_enc = "UTF-8";              to_enc = encoding;            }        }      else        read_cd = (GIConv) -1;      if (channel->is_writeable && err == 0)        {          write_cd = g_iconv_open (encoding, "UTF-8");          if (write_cd == (GIConv) -1)            {              err = errno;              from_enc = encoding;              to_enc = "UTF-8";            }        }      else        write_cd = (GIConv) -1;      if (err != 0)        {          g_assert (from_enc);          g_assert (to_enc);          if (err == EINVAL)            g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION,                         _("Conversion from character set `%s' to `%s' is not supported"),                         from_enc, to_enc);          else            g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,                         _("Could not open converter from `%s' to `%s': %s"),                         from_enc, to_enc, g_strerror (err));          if (read_cd != (GIConv) -1)            g_iconv_close (read_cd);          if (write_cd != (GIConv) -1)            g_iconv_close (write_cd);          return G_IO_STATUS_ERROR;        }      channel->do_encode = TRUE;    }  /* The encoding is ok, so set the fields in channel */  if (channel->read_cd != (GIConv) -1)    g_iconv_close (channel->read_cd);  if (channel->write_cd != (GIConv) -1)    g_iconv_close (channel->write_cd);  if (channel->encoded_read_buf && channel->encoded_read_buf->len > 0)    {      g_assert (!did_encode); /* Encoding UTF-8, NULL doesn't use encoded_read_buf */      /* This is just validated UTF-8, so we can copy it back into read_buf       * so it can be encoded in whatever the new encoding is.       */      g_string_prepend_len (channel->read_buf, channel->encoded_read_buf->str,                            channel->encoded_read_buf->len);      g_string_truncate (channel->encoded_read_buf, 0);    }  channel->read_cd = read_cd;  channel->write_cd = write_cd;  g_free (channel->encoding);  channel->encoding = g_strdup (encoding);  return G_IO_STATUS_NORMAL;}/** * g_io_channel_get_encoding: * @channel: a #GIOChannel * * Gets the encoding for the input/output of the channel. The internal * encoding is always UTF-8. The encoding %NULL makes the * channel safe for binary data. * * Return value: A string containing the encoding, this string is *   owned by GLib and must not be freed. **/G_CONST_RETURN gchar*g_io_channel_get_encoding (GIOChannel      *channel){  g_return_val_if_fail (channel != NULL, NULL);  return channel->encoding;}static GIOStatusg_io_channel_fill_buffer (GIOChannel *channel,                          GError    **err){  gsize read_size, cur_len, oldlen;  GIOStatus status;  if (channel->is_seekable && channel->write_buf && channel->write_buf->len > 0)    {      status = g_io_channel_flush (channel, err);      if (status != G_IO_STATUS_NORMAL)        return status;    }  if (channel->is_seekable && channel->partial_write_buf[0] != '\0')    {      g_warning ("Partial character at end of write buffer not flushed.\n");      channel->partial_write_buf[0] = '\0';    }  if (!channel->read_buf)    channel->read_buf = g_string_sized_new (channel->buf_size);  cur_len = channel->read_buf->len;  g_string_set_size (channel->read_buf, channel->read_buf->len + channel->buf_size);  status = channel->funcs->io_read (channel, channel->read_buf->str + cur_len,                                    channel->buf_size, &read_size, err);  g_assert ((status == G_IO_STATUS_NORMAL) || (read_size == 0));  g_string_truncate (channel->read_buf, read_size + cur_len);  if ((status != G_IO_STATUS_NORMAL)    && ((status != G_IO_STATUS_EOF) || (channel->read_buf->len == 0)))    return status;  g_assert (channel->read_buf->len > 0);  if (channel->encoded_read_buf)    oldlen = channel->encoded_read_buf->len;  else    {      oldlen = 0;      if (channel->encoding)        channel->encoded_read_buf = g_string_sized_new (channel->buf_size);    }  if (channel->do_encode)    {      size_t errnum, inbytes_left, outbytes_left;      gchar *inbuf, *outbuf;      int errval;      g_assert (channel->encoded_read_buf);reencode:      inbytes_left = channel->read_buf->len;      outbytes_left = MAX (channel->read_buf->len,                           channel->encoded_read_buf->allocated_len                           - channel->encoded_read_buf->len - 1); /* 1 for NULL */      outbytes_left = MAX (outbytes_left, 6);      inbuf = channel->read_buf->str;      g_string_set_size (channel->encoded_read_buf,                         channel->encoded_read_buf->len + outbytes_left);      outbuf = channel->encoded_read_buf->str + channel->encoded_read_buf->len               - outbytes_left;      errnum = g_iconv (channel->read_cd, &inbuf, &inbytes_left,			&outbuf, &outbytes_left);      errval = errno;      g_assert (inbuf + inbytes_left == channel->read_buf->str                + channel->read_buf->len);      g_assert (outbuf + outbytes_left == channel->encoded_read_buf->str                + channel->encoded_read_buf->len);      g_string_erase (channel->read_buf, 0,		      channel->read_buf->len - inbytes_left);      g_string_truncate (channel->encoded_read_buf,			 channel->encoded_read_buf->len - outbytes_left);      if (errnum == (size_t) -1)        {          switch (errval)            {              case EINVAL:                if ((oldlen == channel->encoded_read_buf->len)                  && (status == G_IO_STATUS_EOF))                  status = G_IO_STATUS_EOF;                else                  status = G_IO_STATUS_NORMAL;                break;              case E2BIG:                /* Buffer size at least 6, wrote at least on character */                g_assert (inbuf != channel->read_buf->str);                goto reencode;              case EILSEQ:                if (oldlen < channel->encoded_read_buf->len)                  status = G_IO_STATUS_NORMAL;                else                  {                    g_set_error (err, G_CONVERT_ERROR,                      G_CONVERT_ERROR_ILLEGAL_SEQUENCE,                      _("Invalid byte sequence in conversion input"));                    return G_IO_STATUS_ERROR;                  }                break;              default:                g_assert (errval != EBADF); /* The converter should be open */                g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,                  _("Error during conversion: %s"), g_strerror (errval));                return G_IO_STATUS_ERROR;            }        }      g_assert ((status != G_IO_STATUS_NORMAL)               || (channel->encoded_read_buf->len > 0));    }  else if (channel->encoding) /* UTF-8 */    {      gchar *nextchar, *lastchar;      g_assert (channel->encoded_read_buf);      nextchar = channel->read_buf->str;      lastchar = channel->read_buf->str + channel->read_buf->len;      while (nextchar < lastchar)        {          gunichar val_char;          val_char = g_utf8_get_char_validated (nextchar, lastchar - nextchar);          switch (val_char)            {              case -2:                /* stop, leave partial character in buffer */                lastchar = nextchar;                break;              case -1:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -