//===-- TextEncoding.h - Text encoding conversion class -----------*- C++ -*-=// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// /// \file /// This file provides a utility class to convert between different character /// set encodings. /// //===----------------------------------------------------------------------===// #ifndef LLVM_SUPPORT_TEXT_ENCODING_H #define LLVM_SUPPORT_TEXT_ENCODING_H #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Config/config.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorOr.h" #include #include namespace llvm { template class SmallVectorImpl; namespace details { class TextEncodingConverterImplBase { private: /// Converts a string. /// \param[in] Source source string /// \param[out] Result container for converted string /// \return error code in case something went wrong /// /// The following error codes can occur, among others: /// - std::errc::argument_list_too_long: The result requires more than /// std::numeric_limits::max() bytes. /// - std::errc::illegal_byte_sequence: The input contains an invalid /// multibyte sequence. /// - std::errc::invalid_argument: The input contains an incomplete /// multibyte sequence. /// /// If the destination encoding is stateful, the shift state will be set /// to the initial state. /// /// In case of an error, the result string contains the successfully converted /// part of the input string. /// virtual std::error_code convertString(StringRef Source, SmallVectorImpl &Result) = 0; /// Resets the converter to the initial state. virtual void reset() = 0; public: virtual ~TextEncodingConverterImplBase() = default; /// Converts a string and resets the converter to the initial state. std::error_code convert(StringRef Source, SmallVectorImpl &Result) { auto EC = convertString(Source, Result); reset(); return EC; } }; } // namespace details // Names inspired by https://wg21.link/p1885. enum class TextEncoding { /// UTF-8 character set encoding. UTF8, /// IBM EBCDIC 1047 character set encoding. IBM1047 }; /// Utility class to convert between different character encodings. class TextEncodingConverter { std::unique_ptr Converter; TextEncodingConverter( std::unique_ptr Converter) : Converter(std::move(Converter)) {} public: /// Creates a TextEncodingConverter instance. /// Returns std::errc::invalid_argument in case the requested conversion is /// not supported. /// \param[in] From the source character encoding /// \param[in] To the target character encoding /// \return a TextEncodingConverter instance or an error code LLVM_ABI static ErrorOr create(TextEncoding From, TextEncoding To); /// Creates a TextEncodingConverter instance. /// Returns std::errc::invalid_argument in case the requested conversion is /// not supported. /// \param[in] From name of the source character encoding /// \param[in] To name of the target character encoding /// \return a TextEncodingConverter instance or an error code LLVM_ABI static ErrorOr create(StringRef From, StringRef To); TextEncodingConverter(const TextEncodingConverter &) = delete; TextEncodingConverter &operator=(const TextEncodingConverter &) = delete; TextEncodingConverter(TextEncodingConverter &&Other) : Converter(std::move(Other.Converter)) {} TextEncodingConverter &operator=(TextEncodingConverter &&Other) { if (this != &Other) Converter = std::move(Other.Converter); return *this; } ~TextEncodingConverter() = default; /// Converts a string. /// \param[in] Source source string /// \param[out] Result container for converted string /// \return error code in case something went wrong std::error_code convert(StringRef Source, SmallVectorImpl &Result) const { return Converter->convert(Source, Result); } ErrorOr convert(StringRef Source) const { SmallString<100> Result; auto EC = Converter->convert(Source, Result); if (!EC) return std::string(Result); return EC; } }; } // namespace llvm #endif