예제 #1
0
파일: cellL10n.cpp 프로젝트: Apicio/rpcs3
//TODO: Check the code in emulation. If support for UTF8/UTF16/UTF32/UCS2/UCS4 should use wider chars.. awful.
int L10nConvertStr(int src_code, mem8_ptr_t src, mem64_t src_len, int dst_code, mem8_ptr_t dst, mem64_t dst_len)
{
	LOG_ERROR(HLE, "L10nConvertStr(src_code=%d,src=0x%x,src_len=%ld,dst_code=%d,dst=0x%x,dst_len=%ld)",
		src_code, src.GetAddr(), src_len.GetValue(), dst_code, dst.GetAddr(), dst_len.GetValue());
	LOG_ERROR(HLE, "L10nConvertStr: 1st char at dst: %x(Hex)", *((char*)Memory.VirtualToRealAddr(src.GetAddr())));
#ifdef _MSC_VER
	unsigned int srcCode = 0, dstCode = 0;	//OEM code pages
	bool src_page_converted = _L10nCodeParse(src_code, srcCode);	//Check if code is in list.
	bool dst_page_converted = _L10nCodeParse(dst_code, dstCode);

	if (((!src_page_converted) && (srcCode == 0))
		|| ((!dst_page_converted) && (dstCode == 0)))
		return ConverterUnknown;

	//if (strnlen_s((char*)src, *src_len) != *src_len) return SRCIllegal;
	std::string wrapped_source = (char*)Memory.VirtualToRealAddr(src.GetAddr());
	//std::string wrapped_source((char*)src);
	if (wrapped_source.length() != src_len.GetValue()) return SRCIllegal;
	std::string target = _OemToOem(srcCode, dstCode, wrapped_source);

	if (target.length() > dst_len.GetValue()) return DSTExhausted;

	Memory.WriteString(dst, target.c_str());

	return ConversionOK;
#else
	std::string srcCode, dstCode;
	int retValue = ConversionOK;
	if ((_L10nCodeParse(src_code, srcCode)) && (_L10nCodeParse(dst_code, dstCode)))
	{
		iconv_t ict = iconv_open(srcCode.c_str(), dstCode.c_str());
		char *srcBuf = (char*)Memory.VirtualToRealAddr(src.GetAddr());
		char *dstBuf = (char*)Memory.VirtualToRealAddr(dst.GetAddr());
		//char *srcBuf = (char*)src, *dstBuf = (char*)dst;
		//size_t srcLen = *src_len, dstLen = *dst_len;
		size_t srcLen = src_len.GetValue(), dstLen = dst_len.GetValue();
		size_t ictd = iconv(ict, &srcBuf, &srcLen, &dstBuf, &dstLen);
		if (ictd != src_len.GetValue())//if (ictd != *src_len)
		{
			if (errno == EILSEQ)
				retValue = SRCIllegal;  //Invalid multi-byte sequence
			else if (errno == E2BIG)
				retValue = DSTExhausted;//Not enough space
			else if (errno == EINVAL)
				retValue = SRCIllegal;
		}
		iconv_close(ict);
		//retValue = ConversionOK;
	}
	else retValue = ConverterUnknown;
	return retValue;
#endif
}
예제 #2
0
파일: cellL10n.cpp 프로젝트: Aishou/rpcs3
//TODO: Check the code in emulation. If support for UTF8/UTF16/UTF32/UCS2/UCS4 should use wider chars.. awful.
int L10nConvertStr(int src_code, vm::ptr<const void> src, vm::ptr<be_t<u32>> src_len, int dst_code, vm::ptr<void> dst, vm::ptr<be_t<u32>> dst_len)
{
	cellL10n->Todo("L10nConvertStr(src_code=%d,src=0x%x,src_len=%ld,dst_code=%d,dst=0x%x,dst_len=%ld)",
		src_code, src.addr(), src_len.addr(), dst_code, dst.addr(), dst_len.addr());
	cellL10n->Todo("L10nConvertStr: 1st char at dst: %x(Hex)", *((char*)src.get_ptr()));
#ifdef _MSC_VER
	unsigned int srcCode = 0, dstCode = 0;	//OEM code pages
	bool src_page_converted = _L10nCodeParse(src_code, srcCode);	//Check if code is in list.
	bool dst_page_converted = _L10nCodeParse(dst_code, dstCode);

	if (((!src_page_converted) && (srcCode == 0))
		|| ((!dst_page_converted) && (dstCode == 0)))
		return ConverterUnknown;

	//if (strnlen_s((char*)src, *src_len) != *src_len) return SRCIllegal;
	std::string wrapped_source = (char*)src.get_ptr();
	//std::string wrapped_source((char*)src);
	if (wrapped_source.length() != *src_len) return SRCIllegal;
	std::string target = _OemToOem(srcCode, dstCode, wrapped_source);

	if (target.length() > *dst_len) return DSTExhausted;

	memcpy(dst.get_ptr(), target.c_str(), target.size());

	return ConversionOK;
#else
	std::string srcCode, dstCode;
	int retValue = ConversionOK;
	if ((_L10nCodeParse(src_code, srcCode)) && (_L10nCodeParse(dst_code, dstCode)))
	{
		iconv_t ict = iconv_open(srcCode.c_str(), dstCode.c_str());
		char *srcBuf = (char*)src.get_ptr();
		char *dstBuf = (char*)dst.get_ptr();
		//char *srcBuf = (char*)src, *dstBuf = (char*)dst;
		//size_t srcLen = *src_len, dstLen = *dst_len;
		size_t srcLen = *src_len, dstLen = *dst_len;
		size_t ictd = iconv(ict, &srcBuf, &srcLen, &dstBuf, &dstLen);
		if (ictd != *src_len)//if (ictd != *src_len)
		{
			if (errno == EILSEQ)
				retValue = SRCIllegal;  //Invalid multi-byte sequence
			else if (errno == E2BIG)
				retValue = DSTExhausted;//Not enough space
			else if (errno == EINVAL)
				retValue = SRCIllegal;
		}
		iconv_close(ict);
		//retValue = ConversionOK;
	}
	else retValue = ConverterUnknown;
	return retValue;
#endif
}
예제 #3
0
파일: cellL10n.cpp 프로젝트: Klozz/rpcs3
s32 _ConvertStr(s32 src_code, const void *src, s32 src_len, s32 dst_code, void *dst, s32 *dst_len, bool allowIncomplete)
{
	HostCode srcCode = 0, dstCode = 0;	//OEM code pages
	bool src_page_converted = _L10nCodeParse(src_code, srcCode);	//Check if code is in list.
	bool dst_page_converted = _L10nCodeParse(dst_code, dstCode);

	if (((!src_page_converted) && (srcCode == 0))
		|| ((!dst_page_converted) && (dstCode == 0)))
		return ConverterUnknown;

#ifdef _MSC_VER
	std::string wrapped_source = std::string(static_cast<const char *>(src), src_len);
	std::string target = _OemToOem(srcCode, dstCode, wrapped_source);

	if (dst != NULL)
	{
		if (target.length() > *dst_len) return DSTExhausted;
		memcpy(dst, target.c_str(), target.length());
	}
	*dst_len = target.length();

	return ConversionOK;
#else
	s32 retValue = ConversionOK;
	iconv_t ict = iconv_open(dstCode, srcCode);
	size_t srcLen = src_len;
	if (dst != NULL)
	{
		size_t dstLen = *dst_len;
		size_t ictd = iconv(ict, (char **)&src, &srcLen, (char **)&dst, &dstLen);
		*dst_len -= dstLen;
		if (ictd == -1)
		{
			if (errno == EILSEQ)
				retValue = SRCIllegal;  //Invalid multi-byte sequence
			else if (errno == E2BIG)
				retValue = DSTExhausted;//Not enough space
			else if (errno == EINVAL)
			{
				if (allowIncomplete)
					*dst_len = -1;  // TODO: correct value?
				else
					retValue = SRCIllegal;
			}
		}
	}
	else
	{
		*dst_len = 0;
		char buf[16];
		while (srcLen > 0)
		{
			char *bufPtr = buf;
			size_t bufLeft = sizeof(buf);
			size_t ictd = iconv(ict, (char **)&src, &srcLen, (char **)&bufPtr, &bufLeft);
			*dst_len += sizeof(buf) - bufLeft;
			if (ictd == -1 && errno != E2BIG)
			{
				if (errno == EILSEQ)
					retValue = SRCIllegal;
				else if (errno == EINVAL)
				{
					if (allowIncomplete)
						*dst_len = -1;  // TODO: correct value?
					else
						retValue = SRCIllegal;
				}
				break;
			}
		}
	}
	iconv_close(ict);
	return retValue;
#endif
}