E-MailRelay
gcodepage.cpp
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2024 Graeme Walker <graeme_walker@users.sourceforge.net>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16// ===
17///
18/// \file gcodepage.cpp
19///
20
21#include "gdef.h"
22#include "gcodepage.h"
23#include "gconvert.h"
24#include <array>
25#include <algorithm>
26#include <vector>
27#include <cstdint> // std::uint_least16_t
28
29namespace G
30{
31 namespace CodePageImp
32 {
33 using value_type = std::uint_least16_t ;
34 constexpr std::array<value_type,256> cp850 {{
35 0x0000, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C,
36 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC,
37 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
38 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
39 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
40 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
41 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
42 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x2302,
43 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7, 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
44 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9, 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
45 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA, 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
46 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0, 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
47 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3, 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
48 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE, 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
49 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE, 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
50 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8, 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0,
51 }} ;
52 constexpr std::array<value_type,256> cp8859_15 {{
53 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
54 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
55 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
56 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
57 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
58 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
59 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
60 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
61 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
62 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
63 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7, 0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
64 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x00B7, 0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF,
65 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
66 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
67 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
68 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF,
69 }} ;
70 constexpr std::array<value_type,256> cp1252 {{
71 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
72 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
73 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
74 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
75 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
76 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
77 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
78 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
79 0x20AC, 0xFFFF, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFF, 0x017D, 0xFFFF,
80 0xFFFF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFF, 0x017E, 0x0178,
81 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
82 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
83 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
84 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
85 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
86 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF,
87 }} ;
88 constexpr std::array<value_type,256> cp1252_bestfit {{
89 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
90 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
91 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
92 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
93 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
94 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
95 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
96 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
97 0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008D, 0x017D, 0x008F,
98 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x009D, 0x017E, 0x0178,
99 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
100 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
101 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
102 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
103 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
104 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF,
105 }} ;
106
107 std::string fromCodePage( std::string_view , const value_type * , std::size_t , wchar_t e = L'\xFFFD' ) ;
108 std::string toCodePage( std::string_view , const value_type * , std::size_t , char e ) ;
109 std::string fromCodePage850( std::string_view s ) ;
110 std::string toCodePage850( std::string_view s ) ;
111 std::string fromCodePage1252( std::string_view s ) ;
112 std::string toCodePage1252( std::string_view s ) ;
113 std::string toCodePageImp( unsigned int cp , std::string_view , char e , std::string (*fallback_fn)(std::string_view) ) ;
114 std::string fromCodePageImp( unsigned int cp , std::string_view , std::string (*fallback_fn)(std::string_view) ) ;
115
116 std::size_t sizet( int i ) { return i >= 0 ? static_cast<std::size_t>(i) : std::size_t(0) ; }
117 template <typename T> int isize( const T & container ) { return static_cast<int>( container.size() ) ; }
118 template <typename T> typename T::value_type * dataout( T & string ) { return &string[0] ; }
119
120 #ifdef G_UNIX
121 static constexpr int CP_OEMCP = 1 ;
122 static constexpr int CP_ACP = 2 ;
123 static constexpr int WC_NO_BEST_FIT_CHARS = 1 ;
124 inline int WideCharToMultiByte( int , int , const wchar_t * , int , char * , int , char * , bool * ) { return 0 ; }
125 inline int MultiByteToWideChar( int , int , const char * , int , wchar_t * , int ) { return 0 ; }
126 #endif
127 }
128}
129
130std::string G::CodePageImp::fromCodePage( std::string_view sv , const value_type * map_begin ,
131 std::size_t map_size , wchar_t e )
132{
133 std::array<char,4> u8buffer ;
134 std::string result ;
135 result.reserve( sv.size() * 2U ) ;
136 for( char c : sv )
137 {
138 unsigned int uc = static_cast<unsigned char>(c) ;
139 wchar_t w = uc <= map_size && map_begin[uc] != 0xFFFF ? static_cast<wchar_t>( map_begin[uc] ) : e ;
140 char * u8p = u8buffer.data() ;
141 auto u8n = Convert::u8out( w , u8p ) ;
142 for( auto i = 0U ; i < u8n ; i++ )
143 result.append( 1U , u8buffer[i] ) ;
144 }
145 return result ;
146}
147
148std::string G::CodePageImp::toCodePage( std::string_view sv , const value_type * map_begin ,
149 std::size_t map_size , char e )
150{
151 std::string result ;
152 result.reserve( sv.size() ) ;
153
154 const unsigned char * p = reinterpret_cast<const unsigned char*>( sv.data() ) ;
155 std::size_t n = sv.size() ;
156 std::size_t d = 0U ;
157 for( std::size_t i = 0U ; i < n ; i += d , p += d )
158 {
159 auto pair = Convert::u8in( p , n-i ) ;
160 d = pair.second ;
161 if( pair.first == Convert::unicode_error )
162 {
163 result.append( 1U , e ) ;
164 d = 1U ;
165 }
166 else
167 {
168 auto const map_end = map_begin + map_size ;
169 auto map_p = std::find( map_begin , map_end , static_cast<value_type>(pair.first) ) ;
170 if( map_p == map_end || (*map_p) == 0xFFFF )
171 result.append( 1U , e ) ;
172 else
173 result.append( 1U , static_cast<unsigned char>(static_cast<unsigned int>(std::distance(map_begin,map_p))) ) ;
174 }
175 }
176 return result ;
177}
178
179std::string G::CodePage::fromCodePage850( std::string_view s )
180{
181 using namespace G::CodePageImp ;
182 return fromCodePage( s , cp850.data() , cp850.size() ) ;
183}
184
185std::string G::CodePage::toCodePage850( std::string_view s )
186{
187 using namespace G::CodePageImp ;
188 return toCodePage( s , cp850.data() , cp850.size() , oem_error ) ;
189}
190
191std::string G::CodePage::fromCodePage1252( std::string_view s )
192{
193 using namespace G::CodePageImp ;
194 return fromCodePage( s , cp1252.data() , cp1252.size() ) ;
195}
196
197std::string G::CodePage::toCodePage1252( std::string_view s )
198{
199 using namespace G::CodePageImp ;
200 return toCodePage( s , cp1252.data() , cp1252.size() , ansi_error ) ;
201}
202
203std::string G::CodePage::toCodePageOem( std::string_view s )
204{
205 using namespace G::CodePageImp ;
206 if( s.empty() )
207 return {} ;
208 else if( G::is_windows() )
209 return toCodePageImp( CP_OEMCP , s , oem_error , &toCodePage850 ) ;
210 else
211 return toCodePage850( s ) ;
212}
213
214std::string G::CodePage::toCodePageAnsi( std::string_view s )
215{
216 using namespace G::CodePageImp ;
217 if( s.empty() )
218 return {} ;
219 else if( G::is_windows() )
220 return toCodePageImp( CP_ACP , s , ansi_error , &toCodePage1252 ) ;
221 else
222 return toCodePage1252( s ) ;
223}
224
225std::string G::CodePageImp::toCodePageImp( unsigned int cp , std::string_view s , char e ,
226 std::string (*fallback_fn)(std::string_view) )
227{
228 std::wstring ws = Convert::widen( s ) ;
229 int rc1 = WideCharToMultiByte( cp , WC_NO_BEST_FIT_CHARS ,
230 ws.data() , isize(ws) ,
231 nullptr , 0 ,
232 &e , nullptr ) ;
233 if( rc1 <= 0 )
234 return fallback_fn( s ) ;
235 std::string buffer( sizet(rc1)+1U , '\0' ) ;
236 int rc2 = WideCharToMultiByte( cp , WC_NO_BEST_FIT_CHARS ,
237 ws.data() , isize(ws) ,
238 dataout(buffer) , isize(buffer) ,
239 &e , nullptr ) ;
240 if( rc1 != rc2 )
241 return fallback_fn( s ) ;
242 buffer.resize( sizet(rc1) ) ;
243 return buffer ;
244}
245
246std::string G::CodePage::fromCodePageOem( std::string_view s )
247{
248 using namespace G::CodePageImp ;
249 if( s.empty() )
250 return {} ;
251 else if( G::is_windows() )
252 return fromCodePageImp( CP_OEMCP , s , &fromCodePage850 ) ;
253 else
254 return fromCodePage850( s ) ;
255}
256
257std::string G::CodePage::fromCodePageAnsi( std::string_view s )
258{
259 using namespace G::CodePageImp ;
260 if( s.empty() )
261 return {} ;
262 else if( G::is_windows() )
263 return fromCodePageImp( CP_ACP , s , &fromCodePage1252 ) ;
264 else
265 return fromCodePage850( s ) ;
266}
267
268std::string G::CodePageImp::fromCodePageImp( unsigned int cp , std::string_view s ,
269 std::string (*fallback_fn)(std::string_view) )
270{
271 int rc1 = MultiByteToWideChar( cp , WC_NO_BEST_FIT_CHARS ,
272 s.data() , isize(s) ,
273 nullptr , 0 ) ;
274 if( rc1 <= 0 )
275 return fallback_fn( s ) ;
276 std::vector<wchar_t> buffer( sizet(rc1)+1U , L'\0' ) ;
277 int rc2 = MultiByteToWideChar( cp , 0 ,
278 s.data() , isize(s) ,
279 dataout(buffer) , isize(buffer) ) ;
280 if( rc1 != rc2 )
281 return fallback_fn( s ) ;
282 buffer.resize( sizet(rc1) ) ;
283 return Convert::narrow( buffer.data() , buffer.size() ) ;
284}
285
286#if 0
287#!/usr/bin/perl
288use strict ;
289use FileHandle ;
290my @url = (
291 [ "" , "https://www.unicode.org/Public/MAPPINGS/VENDORS/MISC/IBMGRAPH.TXT" ] ,
292 [ "cp850" , "https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP850.TXT" ] ,
293 [ "cp8859_15" , "https://www.unicode.org/Public/MAPPINGS/ISO8859/8859-15.TXT" ] ,
294 [ "cp1252" , "https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT" ] ,
295 [ "cp1252_bestfit" , "https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit1252.txt" ] ,
296) ;
297my $extra = {} ;
298for my $url_pair ( @url )
299{
300 my ( $name , $url ) = @{$url_pair} ;
301 my $fh = new FileHandle( "wget -q -O - $url |" ) ;
302 if( $name eq "" )
303 {
304 while(<$fh>)
305 {
306 chomp( my $line = $_ ) ;
307 next if $line !~ m/^\d\d/ ;
308 my ($uhex,$chex) = split( /\s/ , $line ) ;
309 $extra->{hex("0x${chex}")} = "0x${uhex}" ;
310 }
311 }
312 else
313 {
314 my $n = 0 ;
315 print "\t\tconstexpr std::array<value_type,256> $name {{\n\t\t\t" ;
316 while(<$fh>)
317 {
318 chomp( my $line = $_ ) ;
319 my ($lhex,$rhex) = split( /\s/ , $line ) ;
320 if( $lhex =~ m/^0x/ )
321 {
322 my $lvalue = hex($lhex) ;
323 die if $lvalue != $n++ ;
324 my $rvalue = hex($rhex) ;
325 $rhex = "0xFFFF" if $rhex eq "" ;
326 $rhex =~ tr/[a-f]/[A-F]/ ;
327 if( $name eq "cp850" && exists($extra->{$lvalue}) ) { $rhex = $extra->{$lvalue} }
328 print $rhex , ", " ;
329 print "\n\t\t\t" if( ($n%16) == 0 ) ;
330 }
331 elsif( $lhex =~ m/WCTABLE/ ) # 1252 part two
332 {
333 last ;
334 }
335 }
336 print "}} ;\n" ;
337 }
338}
339#endif
340
std::string fromCodePageAnsi(std::string_view)
Converts from the active OEM codepage (see GetACP(), 1252 on unix) to UTF-8.
Definition: gcodepage.cpp:257
std::string toCodePageOem(std::string_view)
Converts from UTF-8 to the active OEM codepage (see GetOEMCP(), 850 on unix).
Definition: gcodepage.cpp:203
std::string toCodePage850(std::string_view s)
Converts from UTF-8 to codepage 850.
Definition: gcodepage.cpp:185
std::string fromCodePage1252(std::string_view s)
Converts from codepage 1252 to UTF-8.
Definition: gcodepage.cpp:191
std::string fromCodePageOem(std::string_view)
Converts from the active OEM codepage (see GetOEMCP(), 850 on unix) to UTF-8.
Definition: gcodepage.cpp:246
std::string fromCodePage850(std::string_view s)
Converts from codepage 850 to UTF-8.
Definition: gcodepage.cpp:179
std::string toCodePageAnsi(std::string_view)
Converts from UTF-8 to the active "ansi" codepage (see GetACP(), 1252 on unix).
Definition: gcodepage.cpp:214
std::string toCodePage1252(std::string_view s)
Converts from UTF-8 to codepage 1252.
Definition: gcodepage.cpp:197
Low-level classes.
Definition: garg.h:36