/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: EncoderAdapter.cpp Date: 2021-8-19 Author: Reece ***/ #include #include "../Locale.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 == ECodePage::eSysUnk) && (GetInternalCodePage() == ref)) || (page == ref)); } AuStreamReadWrittenPair_t EncoderAdapter::CPToUTF8(const void *in, AuUInt32 length, void *utf8, AuUInt32 utf8Max) { AuStreamReadWrittenPair_t ret {}; if (!length) { return {}; } if (!in) { return {}; } // decode using internal and/or optimized apis first if (TestPage(ECodePage::eUTF8)) { length = CountUTF8Length({in, length}, true); auto readable = AuMin(length, utf8Max); if (utf8 && in) { AuMemcpy(utf8, in, readable); } return {readable, readable}; } // never remove me. the stl and windows can't bet trusted to fail on conversion failure if (TestPage(ECodePage::eGBK)) { length = GBK::CountGbk(in, length, true); } else if (TestPage(ECodePage::eSJIS)) { length = SJIS::CountSJIS(in, length, true); } else if (TestPage(ECodePage::eUTF16) || TestPage(ECodePage::eUTF16BE)) { length = UTF16::Count16(in, length, true); } else if ((page == ECodePage::eUTF32) || (page == ECodePage::eUTF32BE)) { length &= ~3; } ret = Win32CPToUTF8(page, in, length, utf8, utf8Max); if (!ret.first) { // TODO: iconv support here 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 (TestPage(ECodePage::eUTF8)) { auto readable = AuMin(utf8Length, cpLen); if (utf8 && cp) { AuMemcpy(cp, utf8, readable); } return {utf8Length, utf8 ? cpLen : utf8Length}; } ret = Win32UTF8ToCp(page, utf8, utf8Length, cp, cpLen); if (!ret.first) { // TODO: iconv support here ret = STLUTF8ToCp(page, utf8, utf8Length, cp, cpLen); } return ret; } }