AuroraRuntime/Source/Locale/Encoding/EncoderAdapter.cpp

161 lines
3.9 KiB
C++

/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: EncoderAdapter.cpp
Date: 2021-8-19
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "Encoding.hpp"
#include "EncoderIConv.hpp"
#include "EncoderNSL.hpp"
#include "ConvertInternal.hpp"
#include "EncoderAdapter.hpp"
namespace Aurora::Locale::Encoding
{
EncoderAdapter::EncoderAdapter()
{
}
EncoderAdapter::~EncoderAdapter()
{
}
void EncoderAdapter::Init(ECodePage page, bool decode)
{
this->page = page;
this->decode = decode;
}
bool EncoderAdapter::TestPage(ECodePage ref)
{
return ((page == ref) ||
((page == ECodePage::eSysUnk) &&
(GetInternalCodePage() == ref)));
}
AuStreamReadWrittenPair_t EncoderAdapter::CPToUTF8(const void *in, AuUInt32 length, void *utf8, AuUInt32 utf8Max)
{
AuStreamReadWrittenPair_t ret {};
if (!length)
{
return {};
}
if (!in)
{
return {};
}
if (!utf8Max)
{
utf8 = nullptr;
}
// decode using internal and/or optimized apis first
if (TestPage(ECodePage::eUTF8))
{
length = CountUTF8Length({in, length}, true);
if (utf8Max)
{
auto readable = AuMin(length, utf8Max);
readable = CountUTF8Length({in, readable}, true);
if (utf8 && in)
{
AuMemcpy(utf8, in, readable);
}
return {readable, readable};
}
return {length, length};
}
// never remove me. the stl and windows can't bet trusted to fail on conversion failure.
// furthermore, some platforms may restrict the subset of an encoding scheme across the entire au ecosystem
if (TestPage(ECodePage::eGBK))
{
length = GBK::CountGbk(in, length, true);
}
else if (TestPage(ECodePage::eSJIS))
{
auto temp = length;
length = SJIS::CountSJIS(in, length, true);
}
else if (TestPage(ECodePage::eUTF16) || TestPage(ECodePage::eUTF16BE))
{
length = UTF16::Count16(in, length, true, TestPage(ECodePage::eUTF16));
}
else if ((page == ECodePage::eUTF32) || (page == ECodePage::eUTF32BE))
{
length &= ~3;
}
if (!length)
{
return {};
}
ret = Win32CPToUTF8(page, in, length, utf8, utf8Max);
if (!ret.first)
{
ret = IConvCPToUTF8(page, in, length, utf8, utf8Max);
if (!ret.first)
{
ret = STLCPToUTF8(page, in, length, utf8, utf8Max);
}
}
return ret;
}
AuStreamReadWrittenPair_t EncoderAdapter::UTF8ToCp(const void *utf8, AuUInt32 utf8Length, void *cp, AuUInt32 cpLen)
{
AuStreamReadWrittenPair_t ret {};
if (!utf8)
{
return {};
}
if (!utf8Length)
{
return {};
}
if (!cpLen)
{
cp = nullptr;
}
if (TestPage(ECodePage::eUTF8))
{
utf8Length = CountUTF8Length({utf8, utf8Length}, true);
auto readable = AuMin(utf8Length, cpLen);
if (utf8 && cp)
{
AuMemcpy(cp, utf8, readable);
}
return {utf8Length, cp ? readable : utf8Length};
}
ret = Win32UTF8ToCp(page, utf8, utf8Length, cp, cpLen);
if (!ret.first)
{
ret = IConvUTF8ToCp(page, utf8, utf8Length, cp, cpLen);
if (!ret.first)
{
ret = STLUTF8ToCp(page, utf8, utf8Length, cp, cpLen);
}
}
return ret;
}
}