/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: EncoderAdapter.cpp Date: 2021-8-19 Author: Reece ***/ #include #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; } }