Пример #1
0
static int luacconv(lua_State *L)
{
	cconv_t cd;
	const char *fromcode, *tocode, *str;
	char *outstr, *p;
	size_t	inlen, outlen, size;

	if (lua_gettop(L) != 3)
	{
		lua_pushstring(L, "Bad argument number");
		lua_error(L);
		return 1;
	}

	fromcode = lua_tostring(L, 1);
	tocode = lua_tostring(L, 2);
	str = lua_tolstring(L, 3, &inlen);
	if((cd = cconv_open(tocode, fromcode)) == (cconv_t)(-1)) {
		lua_pushstring(L, str);
		return 1;
	}
	outlen = 3 * inlen;
	outstr = p = (char *)malloc(outlen);

	cm_memzero(outstr, outlen);

	size = cconv(cd, (const char **)&str, &inlen, &p, &outlen);
	cconv_close(cd);
	if (size == (size_t)(-1))
	{
		lua_pushstring(L, str);
		free(outstr);
		return 1;
	}
	lua_pushstring(L, outstr);
	free(outstr);
	return 1;
}
Пример #2
0
/**
 * Open a cconv handle.
 *
 * @param   tocode	Convert to-code.
 * @param   fromcode	Convert from-code.
 * @retval  t_handle	Cconv handle,(-1: error).
 */
cconv_t cconv_open(const char* tocode, const char* fromcode)
{
	char code[8] = {0, };
	char *ptr;
	cconv_struct* cd = (cconv_struct*)malloc(sizeof(cconv_struct));
	cd->cconv_cd = CCONV_NULL;
	cd->iconv_cd = NULL;
	cd->gb_utf8  = NULL;
	cd->bg_utf8  = NULL;
	cd->utf8_gb  = NULL;
	cd->utf8_bg  = NULL;
	cd->size_factor = 4;

	/* //IGNORE //TRANSPORT etc. */
	if((ptr = strstr(fromcode, "//")) != NULL)
	{
		strncpy(cd->options, ptr     , 16);
		strncpy(code       , fromcode, ptr - fromcode);
		fromcode = code;
	}

	if(0 == strcasecmp(CCONV_CODE_GBL, fromcode))
	{
		cd->gb_utf8 = iconv_open(CCONV_CODE_UTF, CCONV_CODE_GBL);
		if(0 == strcasecmp(CCONV_CODE_UHT, tocode) || 0 == strcasecmp(CCONV_CODE_UHK, tocode)
				||0 == strcasecmp(CCONV_CODE_UTW, tocode))
		{
			cd->cconv_cd = CCONV_GBL_TO_UHT;
		}
		else if(0 == strcasecmp(CCONV_CODE_UHS, tocode) || 0 == strcasecmp(CCONV_CODE_UCN, tocode))
			cd->cconv_cd = CCONV_GBL_TO_UHS;
		else if(0 == strcasecmp(CCONV_CODE_BIG, tocode))
		{
			cd->cconv_cd = CCONV_GBL_TO_BIG;
			cd->utf8_bg  = iconv_open(CCONV_CODE_BIG, CCONV_CODE_UTF);
		}
		else if(0 == strcasecmp(CCONV_CODE_GHS, tocode))
		{
			cd->cconv_cd = CCONV_GBL_TO_GHS;
			cd->utf8_gb  = iconv_open(CCONV_CODE_GBL, CCONV_CODE_UTF);
		}
		else if(0 == strcasecmp(CCONV_CODE_GHT, tocode))
		{
			cd->cconv_cd = CCONV_GBL_TO_GHT;
			cd->utf8_gb  = iconv_open(CCONV_CODE_GBL, CCONV_CODE_UTF);
		}
	}
	else
	if(0 == strcasecmp(CCONV_CODE_UTF, fromcode)
	 ||0 == strcasecmp(CCONV_CODE_UHS, fromcode)
	 ||0 == strcasecmp(CCONV_CODE_UHT, fromcode)
	 ||0 == strcasecmp(CCONV_CODE_UCN, fromcode)
	 ||0 == strcasecmp(CCONV_CODE_UHK, fromcode)
	 ||0 == strcasecmp(CCONV_CODE_UTW, fromcode)
	) {
		if(0 == strcasecmp(CCONV_CODE_UHS, tocode) || 0 == strcasecmp(CCONV_CODE_UCN, tocode))
			cd->cconv_cd = CCONV_UTF_TO_UHS;
		else if(0 == strcasecmp(CCONV_CODE_UHT, tocode) || 0 == strcasecmp(CCONV_CODE_UHK, tocode)
		     || 0 == strcasecmp(CCONV_CODE_UTW, tocode))
			cd->cconv_cd = CCONV_UTF_TO_UHT;
		else if(0 == strcasecmp(CCONV_CODE_GBL, tocode))
		{
			cd->cconv_cd = CCONV_UTF_TO_GBL;
			cd->utf8_gb  = iconv_open(CCONV_CODE_GBL, CCONV_CODE_UTF);
		}
		else if(0 == strcasecmp(CCONV_CODE_BIG, tocode))
		{
			cd->cconv_cd = CCONV_UTF_TO_BIG;
			cd->utf8_bg  = iconv_open(CCONV_CODE_BIG, CCONV_CODE_UTF);
		}

		cd->size_factor = 1;
	}
	else
	if(0 == strcasecmp(CCONV_CODE_BIG, fromcode))
	{
		if(0 == strcasecmp(CCONV_CODE_GBL, tocode))
		{
			cd->cconv_cd = CCONV_BIG_TO_GBL;
			cd->bg_utf8  = iconv_open(CCONV_CODE_UTF, CCONV_CODE_BIG);
			cd->utf8_gb  = iconv_open(CCONV_CODE_GBL, CCONV_CODE_UTF);
		}
		else if(0 == strcasecmp(CCONV_CODE_UHS, tocode) || 0 == strcasecmp(CCONV_CODE_UCN, tocode))
		{
			cd->cconv_cd = CCONV_BIG_TO_UHS;
			cd->bg_utf8  = iconv_open(CCONV_CODE_UTF, CCONV_CODE_BIG);
		}

		/* just use iconv to do others. */
	}

	if(cd->cconv_cd == CCONV_NULL)
		cd->iconv_cd = iconv_open(tocode, fromcode);
	
	if( cd->iconv_cd == (iconv_t)(-1) || cd->gb_utf8  == (iconv_t)(-1)
	 || cd->bg_utf8  == (iconv_t)(-1) || cd->utf8_gb  == (iconv_t)(-1)
	 || cd->utf8_bg  == (iconv_t)(-1)) {
		cconv_close(cd);
		return (cconv_t)(CCONV_ERROR);
	}

	return cd;
}