Imported Upstream version 3.25.0
[platform/upstream/cmake.git] / Source / cm_codecvt.hxx
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #pragma once
4
5 #include "cmConfigure.h" // IWYU pragma: keep
6
7 #include <cwchar>
8 #include <locale>
9
10 class codecvt : public std::codecvt<char, char, mbstate_t>
11 {
12 public:
13   enum Encoding
14   {
15     None,
16     UTF8,
17     UTF8_WITH_BOM,
18     ANSI,
19     ConsoleOutput,
20   };
21
22 #ifndef CMAKE_BOOTSTRAP
23
24   codecvt(Encoding e);
25
26 protected:
27   ~codecvt() override;
28   bool do_always_noconv() const noexcept override;
29   result do_out(mbstate_t& state, const char* from, const char* from_end,
30                 const char*& from_next, char* to, char* to_end,
31                 char*& to_next) const override;
32   result do_unshift(mbstate_t& state, char* to, char*,
33                     char*& to_next) const override;
34   int do_max_length() const noexcept override;
35   int do_encoding() const noexcept override;
36
37 private:
38   // The mbstate_t argument to do_out and do_unshift is responsible
39   // for storing state between calls.  We cannot control the type
40   // since we want to imbue on standard streams.  However, we do
41   // know that it is a trivial type.  Define our own type to overlay
42   // on it safely with no alignment requirements.
43   struct State
44   {
45     // Buffer bytes we have consumed from a partial codepoint.
46     char partial[3];
47
48     // Number of bytes we have buffered from a partial codepoint.
49     unsigned char buffered : 4;
50
51     // Size of the current codepoint in bytes.
52     unsigned char size : 4;
53   };
54
55   bool m_noconv;
56 #  if defined(_WIN32)
57   unsigned int m_codepage;
58   result Decode(mbstate_t& state, int need, const char*& from_next,
59                 char*& to_next, char* to_end) const;
60   result DecodePartial(mbstate_t& state, char*& to_next, char* to_end) const;
61   void BufferPartial(mbstate_t& state, int need, const char*& from_next) const;
62 #  endif
63
64 #endif
65 };