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

📄 giochannel.c

📁 嵌入式下基于MiniGUI的Web Browser
💻 C
📖 第 1 页 / 共 5 页
字号:
  if (BUF_LEN (USE_BUF (channel)) == 0)    {      g_assert (status != G_IO_STATUS_NORMAL);      if (status == G_IO_STATUS_EOF && channel->encoding          && BUF_LEN (channel->read_buf) > 0)        {          g_set_error (error, G_CONVERT_ERROR,                       G_CONVERT_ERROR_PARTIAL_INPUT,                       _("Leftover unconverted data in read buffer"));          status = G_IO_STATUS_ERROR;        }      if (bytes_read)        *bytes_read = 0;      return status;    }  if (status == G_IO_STATUS_ERROR)    g_clear_error (error);  got_bytes = MIN (count, BUF_LEN (USE_BUF (channel)));  g_assert (got_bytes > 0);  if (channel->encoding)    /* Don't validate for NULL encoding, binary safe */    {      gchar *nextchar, *prevchar;      g_assert (USE_BUF (channel) == channel->encoded_read_buf);      nextchar = channel->encoded_read_buf->str;      do        {          prevchar = nextchar;          nextchar = g_utf8_next_char (nextchar);          g_assert (nextchar != prevchar); /* Possible for *prevchar of -1 or -2 */        }      while (nextchar < channel->encoded_read_buf->str + got_bytes);      if (nextchar > channel->encoded_read_buf->str + got_bytes)        got_bytes = prevchar - channel->encoded_read_buf->str;      g_assert (got_bytes > 0 || count < 6);    }  memcpy (buf, USE_BUF (channel)->str, got_bytes);  g_string_erase (USE_BUF (channel), 0, got_bytes);  if (bytes_read)    *bytes_read = got_bytes;  return G_IO_STATUS_NORMAL;}/** * g_io_channel_read_unichar: * @channel: a #GIOChannel * @thechar: a location to return a character * @error: A location to return an error of type #GConvertError *         or #GIOChannelError * * This function cannot be called on a channel with %NULL encoding. * * Return value: a #GIOStatus **/GIOStatusg_io_channel_read_unichar     (GIOChannel   *channel,			       gunichar     *thechar,			       GError      **error){  GIOStatus status = G_IO_STATUS_NORMAL;  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);  g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR);  g_return_val_if_fail ((error == NULL) || (*error == NULL),			G_IO_STATUS_ERROR);  g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);  while (BUF_LEN (channel->encoded_read_buf) == 0 && status == G_IO_STATUS_NORMAL)    status = g_io_channel_fill_buffer (channel, error);  /* Only return an error if we have no data */  if (BUF_LEN (USE_BUF (channel)) == 0)    {      g_assert (status != G_IO_STATUS_NORMAL);      if (status == G_IO_STATUS_EOF && BUF_LEN (channel->read_buf) > 0)        {          g_set_error (error, G_CONVERT_ERROR,                       G_CONVERT_ERROR_PARTIAL_INPUT,                       _("Leftover unconverted data in read buffer"));          status = G_IO_STATUS_ERROR;        }      if (thechar)        *thechar = (gunichar) -1;      return status;    }  if (status == G_IO_STATUS_ERROR)    g_clear_error (error);  if (thechar)    *thechar = g_utf8_get_char (channel->encoded_read_buf->str);  g_string_erase (channel->encoded_read_buf, 0,                  g_utf8_next_char (channel->encoded_read_buf->str)                  - channel->encoded_read_buf->str);  return G_IO_STATUS_NORMAL;}/** * g_io_channel_write_chars: * @channel: a #GIOChannel * @buf: a buffer to write data from * @count: the size of the buffer. If -1, the buffer *         is taken to be a nul-terminated string. * @bytes_written: The number of bytes written. This can be nonzero *                 even if the return value is not %G_IO_STATUS_NORMAL. *                 If the return value is %G_IO_STATUS_NORMAL and the *                 channel is blocking, this will always be equal *                 to @count if @count >= 0. * @error: A location to return an error of type #GConvertError *         or #GIOChannelError * * Replacement for g_io_channel_write() with the new API. * * On seekable channels with encodings other than %NULL or UTF-8, generic * mixing of reading and writing is not allowed. A call to g_io_channel_write_chars () * may only be made on a channel from which data has been read in the * cases described in the documentation for g_io_channel_set_encoding (). * * Return value: the status of the operation. **/GIOStatusg_io_channel_write_chars (GIOChannel	*channel,                          const gchar	*buf,                          gssize	 count,			  gsize         *bytes_written,                          GError       **error){  GIOStatus status;  gssize wrote_bytes = 0;  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);  g_return_val_if_fail ((error == NULL) || (*error == NULL),			G_IO_STATUS_ERROR);  g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR);  if ((count < 0) && buf)    count = strlen (buf);    if (count == 0)    {      if (bytes_written)        *bytes_written = 0;      return G_IO_STATUS_NORMAL;    }  g_return_val_if_fail (buf != NULL, G_IO_STATUS_ERROR);  g_return_val_if_fail (count > 0, G_IO_STATUS_ERROR);  /* Raw write case */  if (!channel->use_buffer)    {      gsize tmp_bytes;            g_assert (!channel->write_buf || channel->write_buf->len == 0);      g_assert (channel->partial_write_buf[0] == '\0');            status = channel->funcs->io_write (channel, buf, count, &tmp_bytes, error);      if (bytes_written)	*bytes_written = tmp_bytes;      return status;    }  /* General case */  if (channel->is_seekable && (( BUF_LEN (channel->read_buf) > 0)    || (BUF_LEN (channel->encoded_read_buf) > 0)))    {      if (channel->do_encode && BUF_LEN (channel->encoded_read_buf) > 0)        {          g_warning("Mixed reading and writing not allowed on encoded files");          return G_IO_STATUS_ERROR;        }      status = g_io_channel_seek_position (channel, 0, G_SEEK_CUR, error);      if (status != G_IO_STATUS_NORMAL)        {          if (bytes_written)            *bytes_written = 0;          return status;        }    }  if (!channel->write_buf)    channel->write_buf = g_string_sized_new (channel->buf_size);  while (wrote_bytes < count)    {      gsize space_in_buf;      /* If the buffer is full, try a write immediately. In       * the nonblocking case, this prevents the user from       * writing just a little bit to the buffer every time       * and never receiving an EAGAIN.       */      if (channel->write_buf->len >= channel->buf_size)        {          gsize did_write = 0, this_time;          do            {              status = channel->funcs->io_write (channel, channel->write_buf->str                                                 + did_write, channel->write_buf->len                                                 - did_write, &this_time, error);              did_write += this_time;            }          while (status == G_IO_STATUS_NORMAL &&                 did_write < MIN (channel->write_buf->len, MAX_CHAR_SIZE));          g_string_erase (channel->write_buf, 0, did_write);          if (status != G_IO_STATUS_NORMAL)            {              if (status == G_IO_STATUS_AGAIN && wrote_bytes > 0)                status = G_IO_STATUS_NORMAL;              if (bytes_written)                *bytes_written = wrote_bytes;              return status;            }        }      space_in_buf = MAX (channel->buf_size, channel->write_buf->allocated_len - 1)                     - channel->write_buf->len; /* 1 for NULL */      /* This is only true because g_io_channel_set_buffer_size ()       * ensures that channel->buf_size >= MAX_CHAR_SIZE.       */      g_assert (space_in_buf >= MAX_CHAR_SIZE);      if (!channel->encoding)        {          gssize write_this = MIN (space_in_buf, count - wrote_bytes);          g_string_append_len (channel->write_buf, buf, write_this);          buf += write_this;          wrote_bytes += write_this;        }      else        {          const gchar *from_buf;          gsize from_buf_len, from_buf_old_len, left_len;          size_t err;          gint errnum;          if (channel->partial_write_buf[0] != '\0')            {              g_assert (wrote_bytes == 0);              from_buf = channel->partial_write_buf;              from_buf_old_len = strlen (channel->partial_write_buf);              g_assert (from_buf_old_len > 0);              from_buf_len = MIN (6, from_buf_old_len + count);              memcpy (channel->partial_write_buf + from_buf_old_len, buf,                      from_buf_len - from_buf_old_len);            }          else            {              from_buf = buf;              from_buf_len = count - wrote_bytes;              from_buf_old_len = 0;            }reconvert:          if (!channel->do_encode) /* UTF-8 encoding */            {              const gchar *badchar;              gsize try_len = MIN (from_buf_len, space_in_buf);              /* UTF-8, just validate, emulate g_iconv */              if (!g_utf8_validate (from_buf, try_len, &badchar))                {                  gunichar try_char;                  gsize incomplete_len = from_buf + try_len - badchar;                  left_len = from_buf + from_buf_len - badchar;                  try_char = g_utf8_get_char_validated (badchar, incomplete_len);                  switch (try_char)                    {                      case -2:                        g_assert (incomplete_len < 6);                        if (try_len == from_buf_len)                          {                            errnum = EINVAL;                            err = (size_t) -1;                          }                        else                          {                            errnum = 0;                            err = (size_t) 0;                          }                        break;                      case -1:                        g_warning ("Invalid UTF-8 passed to g_io_channel_write_chars().");                        /* FIXME bail here? */                        errnum = EILSEQ;                        err = (size_t) -1;                        break;                      default:                        g_assert_not_reached ();                        err = (size_t) -1;                        errnum = 0; /* Don't confunse the compiler */                    }                }              else                {                  err = (size_t) 0;                  errnum = 0;                  left_len = from_buf_len - try_len;                }              g_string_append_len (channel->write_buf, from_buf,                                   from_buf_len - left_len);              from_buf += from_buf_len - left_len;            }          else            {               gchar *outbuf;               left_len = from_buf_len;               g_string_set_size (channel->write_buf, channel->write_buf->len                                  + space_in_buf);               outbuf = channel->write_buf->str + channel->write_buf->len                        - space_in_buf;               err = g_iconv (channel->write_cd, (gchar **) &from_buf, &left_len,                              &outbuf, &space_in_buf);               errnum = errno;               g_string_truncate (channel->write_buf, channel->write_buf->len                                  - space_in_buf);            }          if (err == (size_t) -1)            {              switch (errnum)        	{                  case EINVAL:                    g_assert (left_len < 6);                    if (from_buf_old_len == 0)                      {                        /* Not from partial_write_buf */                        memcpy (channel->partial_write_buf, from_buf, left_len);                        channel->partial_write_buf[left_len] = '\0';                        if (bytes_written)                          *bytes_written = count;                        return G_IO_STATUS_NORMAL;                      }                    /* Working in partial_write_buf */                    if (left_len == from_buf_len)                      {                        /* Didn't convert anything, must still have                         * less than a full character                         */                        g_assert (count == from_buf_len - from_buf_old_len);                        channel->partial_write_buf[from_buf_len] = '\0';                        if (bytes_written)                          *bytes_written = count;                        return G_IO_STATUS_NORMAL;                      }                    g_assert (from_buf_len - left_len >= from_buf_old_len);                    /* We converted all the old data. This is fine */                    break;                  case E2BIG:                    if (from_buf_len == left_len)                      {                        /* Nothing was written, add enough space for                         * at least one character.                         */                        space_in_buf += MAX_CHAR_SIZE;                        goto reconvert;                      }                    break;                  case EILSEQ:                    g_set_error (error, G_CONVERT_ERROR,                      G_CONVERT_ERROR_ILLEGAL_SEQUENCE,                      _("Invalid byte sequence in conversion input"));                    if (from_buf_old_len > 0 && from_buf_len == left_len)                      g_warning ("Illegal sequence due to partial character "                                 "at the end of a previous write.\n");                    else                      wrote_bytes += from_buf_len - left_len - from_buf_old_len;                    if (bytes_written)                      *bytes_written = wrote_bytes;                    channel->partial_write_buf[0] = '\0';                    return G_IO_STATUS_ERROR;                  default:                    g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,                      _("Error during conversion: %s"), g_strerror (errnum));                    if (from_buf_len >= left_len + from_buf_old_len)                      wrote_bytes += from_buf_len - left_len - from_buf_old_len;                    if (bytes_written)                      *bytes_written = wrote_bytes;                    channel->partial_write_buf[0] = '\0';                    return G_IO_STATUS_ERROR;       

⌨️ 快捷键说明

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