@@ -21,6 +21,42 @@ using std::ostream;
2121using std::string;
2222using std::wstring;
2323
24+ // Maps cp437 characters to Unicode codepoints.
25+ static char16_t cp437_table[256 ] = {
26+ 0x0000 , 0x263a , 0x263b , 0x2665 , 0x2666 , 0x2663 , 0x2660 , 0x2022 ,
27+ 0x25d8 , 0x25cb , 0x25d9 , 0x2642 , 0x2640 , 0x266a , 0x266b , 0x263c ,
28+ 0x25ba , 0x25c4 , 0x2195 , 0x203c , 0x00b6 , 0x00a7 , 0x25ac , 0x21a8 ,
29+ 0x2191 , 0x2193 , 0x2192 , 0x2190 , 0x221f , 0x2194 , 0x25b2 , 0x25bc ,
30+ 0x0020 , 0x0021 , 0x0022 , 0x0023 , 0x0024 , 0x0025 , 0x0026 , 0x0027 ,
31+ 0x0028 , 0x0029 , 0x002a , 0x002b , 0x002c , 0x002d , 0x002e , 0x002f ,
32+ 0x0030 , 0x0031 , 0x0032 , 0x0033 , 0x0034 , 0x0035 , 0x0036 , 0x0037 ,
33+ 0x0038 , 0x0039 , 0x003a , 0x003b , 0x003c , 0x003d , 0x003e , 0x003f ,
34+ 0x0040 , 0x0041 , 0x0042 , 0x0043 , 0x0044 , 0x0045 , 0x0046 , 0x0047 ,
35+ 0x0048 , 0x0049 , 0x004a , 0x004b , 0x004c , 0x004d , 0x004e , 0x004f ,
36+ 0x0050 , 0x0051 , 0x0052 , 0x0053 , 0x0054 , 0x0055 , 0x0056 , 0x0057 ,
37+ 0x0058 , 0x0059 , 0x005a , 0x005b , 0x005c , 0x005d , 0x005e , 0x005f ,
38+ 0x0060 , 0x0061 , 0x0062 , 0x0063 , 0x0064 , 0x0065 , 0x0066 , 0x0067 ,
39+ 0x0068 , 0x0069 , 0x006a , 0x006b , 0x006c , 0x006d , 0x006e , 0x006f ,
40+ 0x0070 , 0x0071 , 0x0072 , 0x0073 , 0x0074 , 0x0075 , 0x0076 , 0x0077 ,
41+ 0x0078 , 0x0079 , 0x007a , 0x007b , 0x007c , 0x007d , 0x007e , 0x2302 ,
42+ 0x00c7 , 0x00fc , 0x00e9 , 0x00e2 , 0x00e4 , 0x00e0 , 0x00e5 , 0x00e7 ,
43+ 0x00ea , 0x00eb , 0x00e8 , 0x00ef , 0x00ee , 0x00ec , 0x00c4 , 0x00c5 ,
44+ 0x00c9 , 0x00e6 , 0x00c6 , 0x00f4 , 0x00f6 , 0x00f2 , 0x00fb , 0x00f9 ,
45+ 0x00ff , 0x00d6 , 0x00dc , 0x00a2 , 0x00a3 , 0x00a5 , 0x20a7 , 0x0192 ,
46+ 0x00e1 , 0x00ed , 0x00f3 , 0x00fa , 0x00f1 , 0x00d1 , 0x00aa , 0x00ba ,
47+ 0x00bf , 0x2310 , 0x00ac , 0x00bd , 0x00bc , 0x00a1 , 0x00ab , 0x00bb ,
48+ 0x2591 , 0x2592 , 0x2593 , 0x2502 , 0x2524 , 0x2561 , 0x2562 , 0x2556 ,
49+ 0x2555 , 0x2563 , 0x2551 , 0x2557 , 0x255d , 0x255c , 0x255b , 0x2510 ,
50+ 0x2514 , 0x2534 , 0x252c , 0x251c , 0x2500 , 0x253c , 0x255e , 0x255f ,
51+ 0x255a , 0x2554 , 0x2569 , 0x2566 , 0x2560 , 0x2550 , 0x256c , 0x2567 ,
52+ 0x2568 , 0x2564 , 0x2565 , 0x2559 , 0x2558 , 0x2552 , 0x2553 , 0x256b ,
53+ 0x256a , 0x2518 , 0x250c , 0x2588 , 0x2584 , 0x258c , 0x2590 , 0x2580 ,
54+ 0x03b1 , 0x00df , 0x0393 , 0x03c0 , 0x03a3 , 0x03c3 , 0x00b5 , 0x03c4 ,
55+ 0x03a6 , 0x0398 , 0x03a9 , 0x03b4 , 0x221e , 0x03c6 , 0x03b5 , 0x2229 ,
56+ 0x2261 , 0x00b1 , 0x2265 , 0x2264 , 0x2320 , 0x2321 , 0x00f7 , 0x2248 ,
57+ 0x00b0 , 0x2219 , 0x00b7 , 0x221a , 0x207f , 0x00b2 , 0x25a0 , 0x00a0 ,
58+ };
59+
2460TextEncoder::Encoding TextEncoder::_default_encoding = TextEncoder::E_utf8;
2561
2662/* *
@@ -177,6 +213,20 @@ encode_wchar(char32_t ch, TextEncoder::Encoding encoding) {
177213 };
178214 return string (encoded, 4 );
179215 }
216+
217+ case E_cp437:
218+ if ((ch & ~0x7f ) == 0 ) {
219+ return string (1 , (char )ch);
220+ }
221+ else if (ch >= 0 && ch < 0x266b ) {
222+ // This case is not optimized, because we don't really need it right now.
223+ for (int i = 0 ; i < 256 ; ++i) {
224+ if (cp437_table[i] == ch) {
225+ return std::string (1 , (char )i);
226+ }
227+ }
228+ }
229+ return " ." ;
180230 }
181231
182232 return " " ;
@@ -233,6 +283,15 @@ decode_text(const string &text, TextEncoder::Encoding encoding) {
233283 return decode_text_impl (decoder);
234284 }
235285
286+ case E_cp437:
287+ {
288+ std::wstring result (text.size (), 0 );
289+ for (size_t i = 0 ; i < result.size (); ++i) {
290+ result[i] = cp437_table[(uint8_t )text[i]];
291+ }
292+ return result;
293+ }
294+
236295 case E_iso8859:
237296 default :
238297 {
@@ -382,6 +441,9 @@ operator << (ostream &out, TextEncoder::Encoding encoding) {
382441
383442 case TextEncoder::E_utf16be:
384443 return out << " utf16be" ;
444+
445+ case TextEncoder::E_cp437:
446+ return out << " cp437" ;
385447 };
386448
387449 return out << " **invalid TextEncoder::Encoding(" << (int )encoding << " )**" ;
@@ -402,6 +464,8 @@ operator >> (istream &in, TextEncoder::Encoding &encoding) {
402464 } else if (word == " unicode" || word == " utf16be" || word == " utf-16be" ||
403465 word == " utf16-be" || word == " utf-16-be" ) {
404466 encoding = TextEncoder::E_utf16be;
467+ } else if (word == " cp437" ) {
468+ encoding = TextEncoder::E_cp437;
405469 } else {
406470 ostream *notify_ptr = StringDecoder::get_notify_ptr ();
407471 if (notify_ptr != nullptr ) {
0 commit comments