/*****
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
*****/


#include "config.h"
#include "net/unicode.h"


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "iconv.h"


cUnicode::cUnicode (const char *str, int len /* = 0 */, bool internal /*= false*/, const char *charset /*= ""*/ )
{
	memset (m_charBuf, 0, sizeof (m_charBuf));
	memset (m_unicodeBuf, 0, sizeof (m_unicodeBuf));

	if (len <= 0)
		len = strlen(str);

	if (len > sizeof(m_charBuf) - 1)
		len = sizeof(m_charBuf) - 1;

	strncpy (m_charBuf, str, len);

	m_strLen = 0;
	m_charLen = len + 1; // +1 : '\0'
	//m_unicodeLen = m_charLen * sizeof(UNICHAR);

	//if (!charset) charset = nConfig::charset.c_str();
	if (!charset) charset = "ASCII";

	CharToUnicode (charset, internal);
}

cUnicode::cUnicode (const UNICHAR * str, int len /* = 0 */, bool internal /*= false*/, const char *charset /*= ""*/ )
{
	memset (m_charBuf, 0, sizeof (m_charBuf));
	memset (m_unicodeBuf, 0, sizeof (m_unicodeBuf));

	if (len <= 0 || len > sizeof(m_charBuf) - 1) 
		len = sizeof(m_charBuf) - 1;

	UnicodeCpy (str, len);

	//if (!charset) charset = nConfig::charset.c_str();
	if (!charset) charset = "ASCII";

	UnicodeToChar (charset, internal);
}

cUnicode::~cUnicode ()
{
}

void cUnicode::UnicodeCpy (const UNICHAR * str, int maxlen)
{
	UNICHAR *n = m_unicodeBuf;

	while (*str && maxlen)
	{
		*(n++) = *(str++);
		maxlen--;
	}

	*n = 0;

	m_strLen = 0;
	m_unicodeLen = (n - m_unicodeBuf + 1) * sizeof(UNICHAR);
}

void cUnicode::CharToUnicode(const char *charset, bool internal)
{
	const char *in  = m_charBuf;
	char *out = (char*)m_unicodeBuf;
	size_t inLen  = m_charLen;
	size_t outLen = sizeof(m_unicodeBuf);

	iconv_t cd = iconv_open(internal ? "UCS-2-INTERNAL" : "UCS-2", charset);
	if (cd < (iconv_t)0) return;
	
	if (iconv(cd, &in, &inLen, &out, &outLen) == (size_t)-1)
	{
		// converting error
		m_strLen = 0;
	}
	else
	{
		m_strLen = (UNICHAR*)out - m_unicodeBuf - 1;  // -1 '\0'
		m_unicodeLen = (m_strLen + 1) * sizeof(UNICHAR);
	}

	iconv_close(cd);
}

void cUnicode::UnicodeToChar(const char *charset, bool internal)
{
	const char *in  = (char*)m_unicodeBuf;
	char *out = m_charBuf;
	size_t inLen  = m_unicodeLen;
	size_t outLen = sizeof(m_charBuf);

	iconv_t cd = iconv_open(charset, internal ? "UCS-2-INTERNAL" : "UCS-2");
	if (cd < (iconv_t)0) return;
	
	if (iconv(cd, &in, &inLen, &out, &outLen) == (size_t)-1)
	{
		// converting error
		m_strLen = 0;
	}
	else
	{
		m_strLen  = out - m_charBuf - 1;  // -1 '\0'
		m_charLen = m_strLen + 1;
	}

	iconv_close(cd);
}


