9af083fee14a97cf60cb1e0e8585ab0959be5784
[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   };
20
21 #ifndef CMAKE_BOOTSTRAP
22
23   codecvt(Encoding e);
24
25 protected:
26   ~codecvt() override;
27   bool do_always_noconv() const noexcept override;
28   result do_out(mbstate_t& state, const char* from, const char* from_end,
29                 const char*& from_next, char* to, char* to_end,
30                 char*& to_next) const override;
31   result do_unshift(mbstate_t& state, char* to, char*,
32                     char*& to_next) const override;
33   int do_max_length() const noexcept override;
34   int do_encoding() const noexcept override;
35
36 private:
37   // The mbstate_t argument to do_out and do_unshift is responsible
38   // for storing state between calls.  We cannot control the type
39   // since we want to imbue on standard streams.  However, we do
40   // know that it is a trivial type.  Define our own type to overlay
41   // on it safely with no alignment requirements.
42   struct State
43   {
44     // Buffer bytes we have consumed from a partial codepoint.
45     char partial[3];
46
47     // Number of bytes we have buffered from a partial codepoint.
48     unsigned char buffered : 4;
49
50     // Size of the current codepoint in bytes.
51     unsigned char size : 4;
52   };
53
54   bool m_noconv;
55 #  if defined(_WIN32)
56   unsigned int m_codepage;
57   result Decode(mbstate_t& state, int need, const char*& from_next,
58                 char*& to_next, char* to_end) const;
59   result DecodePartial(mbstate_t& state, char*& to_next, char* to_end) const;
60   void BufferPartial(mbstate_t& state, int need, const char*& from_next) const;
61 #  endif
62
63 #endif
64 };