#pragma once #include "codepage.h" #include <util/generic/noncopyable.h> // WARNING: Do not use this functions - use functions from wide.h or recyr.hh instead. namespace NICONVPrivate { inline const char* CharsetName(ECharset code) { return NameByCharset(code); } inline const char* CharsetName(const char* code) { return code; } template <int size> inline const char* UnicodeNameBySize(); template <> inline const char* UnicodeNameBySize<1>() { return "UTF-8"; } template <> inline const char* UnicodeNameBySize<2>() { return "UTF-16LE"; } template <> inline const char* UnicodeNameBySize<4>() { return "UCS-4LE"; } template <class C> inline const char* UnicodeName() { return UnicodeNameBySize<sizeof(C)>(); } class TDescriptor : NNonCopyable::TNonCopyable { private: void* Descriptor_; const char* From_; const char* To_; public: template <class TFrom, class TTo> inline TDescriptor(TFrom from, TTo to) : TDescriptor(CharsetName(from), CharsetName(to)) { } TDescriptor(const char* from, const char* to); ~TDescriptor(); inline void* Get() const { return Descriptor_; } inline bool Invalid() const { return Descriptor_ == (void*)(-1); } inline const char* From() const noexcept { return From_; } inline const char* To() const noexcept { return To_; } }; template <class TFrom, class TTo> inline bool CanConvert(TFrom from, TTo to) { TDescriptor descriptor(from, to); return !descriptor.Invalid(); } size_t RecodeImpl(const TDescriptor& descriptor, const char* in, char* out, size_t inSize, size_t outSize, size_t& read, size_t& written); void DoRecode(const TDescriptor& descriptor, const char* in, char* out, size_t inSize, size_t outSize, size_t& read, size_t& written); template <class TFrom, class TTo> inline void Recode(TFrom from, TTo to, const char* in, char* out, size_t inSize, size_t outSize, size_t& read, size_t& written) { TDescriptor descriptor(from, to); DoRecode(descriptor, in, out, inSize, outSize, read, written); } template <class TCharType> inline void RecodeToUnicode(ECharset from, const char* in, TCharType* out, size_t inSize, size_t outSize, size_t& read, size_t& written) { const size_t charSize = sizeof(TCharType); Recode(from, UnicodeName<TCharType>(), in, reinterpret_cast<char*>(out), inSize, outSize * charSize, read, written); written /= charSize; } template <class TCharType> inline void RecodeFromUnicode(ECharset to, const TCharType* in, char* out, size_t inSize, size_t outSize, size_t& read, size_t& written) { const size_t charSize = sizeof(TCharType); Recode(UnicodeName<TCharType>(), to, reinterpret_cast<const char*>(in), out, inSize * charSize, outSize, read, written); read /= charSize; } RECODE_RESULT DoRecodeNoThrow(const TDescriptor& d, const char* in, char* out, size_t inSize, size_t outSize, size_t& read, size_t& written); template <class TFrom, class TTo> inline RECODE_RESULT RecodeNoThrow(TFrom from, TTo to, const char* in, char* out, size_t inSize, size_t outSize, size_t& read, size_t& written) { TDescriptor descriptor(from, to); return DoRecodeNoThrow(descriptor, in, out, inSize, outSize, read, written); } template <class TCharType> inline RECODE_RESULT RecodeToUnicodeNoThrow(ECharset from, const char* in, TCharType* out, size_t inSize, size_t outSize, size_t& read, size_t& written) { const size_t charSize = sizeof(TCharType); RECODE_RESULT res = RecodeNoThrow(from, UnicodeName<TCharType>(), in, reinterpret_cast<char*>(out), inSize, outSize * charSize, read, written); written /= charSize; return res; } template <class TCharType> inline RECODE_RESULT RecodeFromUnicodeNoThrow(ECharset to, const TCharType* in, char* out, size_t inSize, size_t outSize, size_t& read, size_t& written) { const size_t charSize = sizeof(TCharType); RECODE_RESULT res = RecodeNoThrow(UnicodeName<TCharType>(), to, reinterpret_cast<const char*>(in), out, inSize * charSize, outSize, read, written); read /= charSize; return res; } }