/*
* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <new>
#ifdef WIN32
#include <windows.h>
#else
#include <strings.h>
#include <iconv.h>
#endif
#include "uniconv.hpp"
int UniConv::DefaultCodePage2UTF8(const char* DCPStringRef, unsigned int DCPLength, char** UTF8StringRef, unsigned int* UTFLength) throw ()
{
int reslen = -1;
if(!UTF8StringRef || !UTFLength || !DCPStringRef)
return (int)-1;
#ifdef WIN32
//make Unicode string from its default code page
reslen = MultiByteToWideChar(CP_ACP, 0, DCPStringRef, DCPLength, NULL, 0);
if(0 == reslen)
return (int)-1;
WCHAR* unistr = new (std::nothrow) WCHAR[reslen+1];
if(!unistr)
return (int)-1;
reslen = MultiByteToWideChar(CP_ACP, 0, DCPStringRef, DCPLength, unistr, reslen);
if(0 == reslen)
{
delete[] unistr;
return (int)-1;
}
//make UTF-8 string from its Unicode encoding
unsigned int realutflen = 0;
realutflen = WideCharToMultiByte(CP_UTF8, 0, unistr, reslen, NULL, 0, NULL, NULL);
if(0 == realutflen)
{
delete[] unistr;
return (int)-1;
}
if(realutflen+1 > *UTFLength)
{
if(*UTF8StringRef)
delete[] *UTF8StringRef;
*UTF8StringRef = new (std::nothrow) char[realutflen+1];
if(!*UTF8StringRef)
{
delete[] unistr;
*UTFLength = 0;
return (int)-1;
}
}
*UTFLength = realutflen;
reslen = WideCharToMultiByte(CP_UTF8, 0, unistr, reslen, *UTF8StringRef, *UTFLength, NULL, NULL);
(*UTF8StringRef)[realutflen] = 0;
if(0 == reslen)
reslen = (int)-1;
//clean up temporarily allocated resources
delete[] unistr;
#else
//character set format: language[_territory][.codeset][@modifier]
char* dcp = getenv("LANG");
if(!dcp)
return (int)-1;
char* dot = strstr(dcp, ".");
if(dot)
dcp += ((dot-dcp) + 1);
char* atmark = strstr(dcp, "@");
if(atmark)
*(atmark) = 0;
if(strcasecmp(dcp, "UTF-8") == 0)
{
strcpy(*UTF8StringRef, DCPStringRef);
*UTFLength = DCPLength;
return DCPLength;
}
iconv_t convhan = iconv_open("UTF-8", dcp);
if((iconv_t)(-1) == convhan)
return (int)-1;
char* utf8str = new (std::nothrow) char[DCPLength*4];
if(!utf8str)
{
iconv_close(convhan);
return (int)-1;
}
int realutflen = DCPLength*4;
int origLen = realutflen;
char* pout = utf8str;
if(iconv(convhan, const_cast<char**>(&DCPStringRef), (size_t*)&DCPLength, &pout, (size_t*)&realutflen) < 0)
{
iconv_close(convhan);
delete[] utf8str;
return (int)-1;
}
realutflen = origLen - realutflen;
if((unsigned int)(realutflen+1) > *UTFLength)
{
if(*UTF8StringRef)
delete[] *UTF8StringRef;
*UTF8StringRef = new (std::nothrow) char[realutflen+1];
if(!*UTF8StringRef)
{
delete[] utf8str;
iconv_close(convhan);
return (int)-1;
}
}
strncpy(*UTF8StringRef, utf8str, realutflen);
(*UTF8StringRef)[realutflen] = 0;
*UTFLength = realutflen;
reslen = realutflen;
delete[] utf8str;
iconv_close(convhan);
#endif
return reslen;
}
int UniConv::UTF82DefaultCodePage(const char* UTF8StringRef, unsigned int UTFLength, char** DCPStringRef, unsigned int* DCPLength) throw ()
{
int reslen = -1;
if(!DCPStringRef || !DCPLength || !UTF8StringRef)
return (int)-1;
#ifdef WIN32
//make Unicode string from its UTF-8 encoding
reslen = MultiByteToWideChar(CP_UTF8, 0, UTF8StringRef, UTFLength, NULL, 0);
if(0 == reslen)
return (int)-1;
WCHAR* unistr = new (std::nothrow) WCHAR[reslen+1];
if(!unistr)
return (int)-1;
reslen = MultiByteToWideChar(CP_UTF8, 0, UTF8StringRef, UTFLength, unistr, reslen);
if(0 == reslen)
{
delete[] unistr;
return (int)-1;
}
//make default code paged string from its Unicode encoding
unsigned int realdcplen = 0;
realdcplen = WideCharToMultiByte(CP_ACP, 0, unistr, reslen, NULL, 0, NULL, NULL);
if(0 == realdcplen)
{
delete[] unistr;
return (int)-1;
}
if(realdcplen+1 > *DCPLength)
{
if(*DCPStringRef)
delete[] *DCPStringRef;
*DCPStringRef = new (std::nothrow) char[realdcplen+1];
if(!*DCPStringRef)
{
delete[] unistr;
*DCPLength = 0;
return (int)-1;
}
}
*DCPLength = realdcplen;
reslen = WideCharToMultiByte(CP_ACP, 0, unistr, reslen, *DCPStringRef, *DCPLength, NULL, NULL);
(*DCPStringRef)[realdcplen] = 0;
if(0 == reslen)
reslen = (int)-1;
//clean up temporarily allocated resources
delete[] unistr;
#else
//character set format: language[_territory][.codeset][@modifier]
char* dcp = getenv("LANG");
if(!dcp)
return (int)-1;
char* dot = strstr(dcp, ".");
if(dot)
dcp += ((dot-dcp) + 1);
char* atmark = strstr(dcp, "@");
if(atmark)
*(atmark) = 0;
iconv_t convhan = iconv_open(dcp, "UTF-8");
if((iconv_t)(-1) == convhan)
return (int)-1;
char* dcpstr = new (std::nothrow) char[UTFLength*4];
if(!dcpstr)
{
iconv_close(convhan);
return (int)-1;
}
int realdcplen = UTFLength*4;
int origLen = realdcplen;
char* pout = dcpstr;
if(iconv(convhan, const_cast<char**>(&UTF8StringRef), (size_t*)&UTFLength, &pout, (size_t*)&realdcplen) < 0)
{
iconv_close(convhan);
delete[] dcpstr;
return (int)-1;
}
realdcplen = origLen - realdcplen;
if((unsigned int)(realdcplen+1) > *DCPLength)
{
if(*DCPStringRef)
delete[] *DCPStringRef;
*DCPStringRef = new (std::nothrow) char[realdcplen+1];
if(!*DCPStringRef)
{
delete[] dcpstr;
iconv_close(convhan);
return (int)-1;
}
}
strncpy(*DCPStringRef, dcpstr, realdcplen);
(*DCPStringRef)[realdcplen] = 0;
*DCPLength = realdcplen;
reslen = realdcplen;
delete[] dcpstr;
iconv_close(convhan);
#endif
return reslen;
}
bool UniConv::IsPureASCIITextStream(const char* StringRef) throw ()
{
while (*StringRef && !(*StringRef++ & 0x80))
;
if (*StringRef)
return false;
else
return true;
}