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

📄 iconv.c

📁 Newlib 嵌入式 C库 标准实现代码
💻 C
字号:
/* * Copyright (c) 2003-2004, Artem B. Bityuckiy * Copyright (c) 1999,2000, Konstantin Chuguev. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//*FUNCTION<<iconv>>, <<iconv_open>>, <<iconv_close>>---charset conversion routinesINDEX	iconvINDEX	iconv_openINDEX	iconv_closeINDEX	_iconv_rINDEX	_iconv_open_rINDEX	_iconv_close_rANSI_SYNOPSIS	#include <iconv.h>	iconv_t iconv_open (const char *<[to]>, const char *<[from]>);	int iconv_close (iconv_t <[cd]>);        size_t iconv (iconv_t <[cd]>, const char **<[inbuf]>, 	              size_t *<[inbytesleft]>, 		      char **<[outbuf]>, size_t *<[outbytesleft]>),	iconv_t _iconv_open_r (struct _reent *<[rptr]>, 			       const char *<[to]>, const char *<[from]>);	int _iconv_close_r (struct _reent *<[rptr]>, iconv_t <[cd]>);        size_t _iconv_r (struct _reent *<[rptr]>,			 iconv_t <[cd]>, const char **<[inbuf]>, 	                 size_t *<[inbytesleft]>, 		         char **<[outbuf]>, size_t *<[outbytesleft]>),TRAD_SYNOPSIS	#include <iconv.h>        size_t iconv (<[cd]>, <[in]>, <[inleft]>, <[out]>, <[outleft]>)	iconv_t <[cd]>;	const char **<[in]>;	size_t *<[inleft]>;         char **<[out]>;       	size_t *<[outleft]>);	#include <iconv.h>	iconv_t iconv_open (<[to]>, <[from]>);	const char *<[to]>;       	const char *<[from]>;	#include <iconv.h>	int iconv_close (<[cd]>);	iconv_t <[cd]>;	#include <iconv.h>        size_t _iconv_r (<[rptr]>, <[cd]>, <[in]>, <[inleft]>, <[out]>, <[outleft]>)	struct _reent *<[rptr]>;	iconv_t <[cd]>;	const char **<[in]>;	size_t *<[inleft]>;         char **<[out]>;       	size_t *<[outleft]>);	#include <iconv.h>	iconv_t _iconv_open_r (<[rptr]>, <[to]>, <[from]>);	struct _reent *<[rptr]>;	const char *<[to]>;       	const char *<[from]>;	#include <iconv.h>	int iconv_close (<[rptr]>, <[cd]>);	struct _reent *<[rptr]>;	iconv_t <[cd]>;DESCRIPTIONThe function <<iconv>> converts characters from <[in]> which are in oneencoding to characters of another encoding, outputting them to <[out]>.The value <[inleft]> specifies the number of input bytes to convert whereasthe value <[outleft]> specifies the size remaining in the <[out]> buffer. The conversion descriptor <[cd]> specifies the conversion being performedand is created via <<iconv_open>>.An <<iconv>> conversion stops if: the input bytes are exhausted, the outputbuffer is full, an invalid input character sequence occurs, or theconversion specifier is invalid.The function <<iconv_open>> is used to specify a conversion from oneencoding: <[from]> to another: <[to]>.  The result of the call isto create a conversion specifier that can be used with <<iconv>>.The function <<iconv_close>> is used to close a conversion specifier afterit is no longer needed.The <<_iconv_r>>, <<_iconv_open_r>>, and <<_iconv_close_r>> functions arereentrant versions of <<iconv>>, <<iconv_open>>, and <<iconv_close>>,respectively.  An additional reentrancy struct pointer: <[rptr]> is passedto properly set <<errno>>.RETURNSThe <<iconv>> function returns the number of non-identical conversionsperformed.  If an error occurs, (size_t)-1 is returned and <<errno>>is set appropriately.  The values of <[inleft]>, <[in]>, <[out]>,and <[outleft]> are modified to indicate how much input was processedand how much output was created.The <<iconv_open>> function returns either a valid conversion specifieror (iconv_t)-1 to indicate failure.  If failure occurs, <<errno>> is setappropriately.The <<iconv_close>> function returns 0 on success or -1 on failure.If failure occurs <<errno>> is set appropriately.PORTABILITY<<iconv>>, <<iconv_open>>, and <<iconv_close>> are non-ANSI and are specifiedby the Single Unix specification.No supporting OS subroutine calls are required.*/#include <_ansi.h>#include <reent.h>#include <sys/types.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include <iconv.h>#include <wchar.h>#include <sys/iconvnls.h>#include "local.h"#include "conv.h"#include "ucsconv.h"/* * iconv interface functions as specified by Single Unix specification. */iconv_t_DEFUN(iconv_open, (to, from),                    _CONST char *to _AND                   _CONST char *from){  return _iconv_open_r (_REENT, to, from);}size_t_DEFUN(iconv, (cd, inbuf, inbytesleft, outbuf, outbytesleft),              iconv_t cd          _AND              _CONST char **inbuf _AND              size_t *inbytesleft _AND              char **outbuf       _AND              size_t *outbytesleft){    return _iconv_r (_REENT, cd, inbuf, inbytesleft, outbuf, outbytesleft);}int_DEFUN(iconv_close, (cd), iconv_t cd){    return _iconv_close_r (_REENT, cd);}#ifndef _REENT_ONLYiconv_t_DEFUN(_iconv_open_r, (rptr, to, from),                      struct _reent *rptr _AND                      _CONST char *to     _AND                      _CONST char *from){  iconv_conversion_t *ic;      if (to == NULL || from == NULL || *to == '\0' || *from == '\0')    return (iconv_t)-1;  if ((to = (_CONST char *)_iconv_resolve_encoding_name (rptr, to)) == NULL)    return (iconv_t)-1;  if ((from = (_CONST char *)_iconv_resolve_encoding_name (rptr, from)) == NULL)    {      _free_r (rptr, (_VOID_PTR)to);      return (iconv_t)-1;    }  ic = (iconv_conversion_t *)_malloc_r (rptr, sizeof (iconv_conversion_t));  if (ic == NULL)    return (iconv_t)-1;  /* Select which conversion type to use */  if (strcmp (from, to) == 0)    {      /* Use null conversion */      ic->handlers = &_iconv_null_conversion_handlers;      ic->data = ic->handlers->open (rptr, to, from);    }  else      {      /* Use UCS-based conversion */      ic->handlers = &_iconv_ucs_conversion_handlers;      ic->data = ic->handlers->open (rptr, to, from);    }  _free_r (rptr, (_VOID_PTR)to);  _free_r (rptr, (_VOID_PTR)from);  if (ic->data == NULL)    {      _free_r (rptr, (_VOID_PTR)ic);      return (iconv_t)-1;    }  return (_VOID_PTR)ic;}size_t_DEFUN(_iconv_r, (rptr, cd, inbuf, inbytesleft, outbuf, outbytesleft),                 struct _reent *rptr _AND                 iconv_t cd          _AND                 _CONST char **inbuf _AND                 size_t *inbytesleft _AND                 char **outbuf       _AND                 size_t *outbytesleft){  iconv_conversion_t *ic = (iconv_conversion_t *)cd;  if ((_VOID_PTR)cd == NULL || cd == (iconv_t)-1 || ic->data == NULL       || (ic->handlers != &_iconv_null_conversion_handlers           && ic->handlers != &_iconv_ucs_conversion_handlers))    {      __errno_r (rptr) = EBADF;      return (size_t)-1;    }  if (inbuf == NULL || *inbuf == NULL)    {      mbstate_t state_null = ICONV_ZERO_MB_STATE_T;            if (!ic->handlers->is_stateful(ic->data, 1))        return (size_t)0;            if (outbuf == NULL || *outbuf == NULL)        {          /* Reset shift state */          ic->handlers->set_state (ic->data, &state_null, 1);                    return (size_t)0;        }             if (outbytesleft != NULL)        {          mbstate_t state_save = ICONV_ZERO_MB_STATE_T;                    /* Save current shift state */                    ic->handlers->get_state (ic->data, &state_save, 1);                    /* Reset shift state */          ic->handlers->set_state (ic->data, &state_null, 1);          /* Get initial shift state sequence and it's length */          ic->handlers->get_state (ic->data, &state_null, 1);                    if (*outbytesleft >= state_null.__count)            {              memcpy ((_VOID_PTR)(*outbuf), (_VOID_PTR)&state_null, state_null.__count);                            *outbuf += state_null.__count;              *outbytesleft -= state_null.__count;              return (size_t)0;            }           /* Restore shift state if output buffer is too small */           ic->handlers->set_state (ic->data, &state_save, 1);        }             __errno_r (rptr) = E2BIG;      return (size_t)-1;    }    if (*inbytesleft == 0)    {      __errno_r (rptr) = EINVAL;      return (size_t)-1;    }     if (*outbytesleft == 0 || *outbuf == NULL)    {      __errno_r (rptr) = E2BIG;      return (size_t)-1;    }  return ic->handlers->convert (rptr,                                ic->data,                                (_CONST unsigned char**)inbuf,                                inbytesleft,                                (unsigned char**)outbuf,                                outbytesleft,                                0);}int_DEFUN(_iconv_close_r, (rptr, cd),                       struct _reent *rptr _AND                       iconv_t cd){  int res;  iconv_conversion_t *ic = (iconv_conversion_t *)cd;    if ((_VOID_PTR)cd == NULL || cd == (iconv_t)-1 || ic->data == NULL       || (ic->handlers != &_iconv_null_conversion_handlers           && ic->handlers != &_iconv_ucs_conversion_handlers))    {      __errno_r (rptr) = EBADF;      return -1;    }  res = (int)ic->handlers->close (rptr, ic->data);    _free_r (rptr, (_VOID_PTR)cd);  return res;}#endif /* !_REENT_ONLY */

⌨️ 快捷键说明

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