SWIutfconversions.c
上传用户:xqtpzdz
上传日期:2022-05-21
资源大小:1764k
文件大小:28k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. /* SWIutfconversions, Unicode conversions */
  2. /****************License************************************************
  3.  * Vocalocity OpenVXI
  4.  * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
  5.  * This program is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU General Public License
  7.  * as published by the Free Software Foundation; either version 2
  8.  * of the License, or (at your option) any later version.
  9.  *  
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
  19.  * registered trademarks of Vocalocity, Inc. 
  20.  * OpenVXI is a trademark of Scansoft, Inc. and used under license 
  21.  * by Vocalocity.
  22.  ***********************************************************************/
  23. /* -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
  24.  */
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <SWIutfconversions.h>
  28. #if 0
  29. #include "Encoding.h"
  30. #include <cstring>
  31. #include <cwchar>
  32. #include <vector>
  33. #include <algorithm>
  34. bool initialized = false;
  35. // ---------------------------------------------------------------------------
  36. // Define a registry of decoder functions.
  37. // ---------------------------------------------------------------------------
  38. typedef bool (*DECODERFUNCTION)(const char *,
  39.                                 std::basic_string<wchar_t> &);
  40. class EncoderEntry {
  41. public:
  42.   const char * name;
  43.   DECODERFUNCTION function;
  44.   EncoderEntry(const char * x, DECODERFUNCTION y)
  45.     : name(x), function(y) { }
  46.   EncoderEntry(const EncoderEntry & x) : name(x.name), function(x.function) { }
  47.   EncoderEntry & operator=(const EncoderEntry & x)
  48.   { if (this != &x) { name = x.name;  function = x.function; }
  49.     return *this; }
  50. };
  51. bool operator<(const EncoderEntry & x, const EncoderEntry & y)
  52. { return strcmp(x.name, y.name) < 0; }
  53. // ---------------------------------------------------------------------------
  54. typedef std::vector<EncoderEntry> DECODER_REGISTRY;
  55. DECODER_REGISTRY decoderRegistry;
  56. void InitializeDecoder()
  57. {
  58.   if(initialized)
  59.     return;
  60.   decoderRegistry.push_back(EncoderEntry("utf-8",       DecodeUTF8));
  61.   decoderRegistry.push_back(EncoderEntry("utf8",        DecodeUTF8));
  62.   decoderRegistry.push_back(EncoderEntry("us-ascii",    DecodeASCII));
  63.   decoderRegistry.push_back(EncoderEntry("us_ascii",    DecodeASCII));
  64.   decoderRegistry.push_back(EncoderEntry("usascii",     DecodeASCII));
  65.   decoderRegistry.push_back(EncoderEntry("ascii",       DecodeASCII));
  66.   decoderRegistry.push_back(EncoderEntry("iso8859-1",   DecodeISO8859_1));
  67.   decoderRegistry.push_back(EncoderEntry("iso-8859-1",  DecodeISO8859_1));
  68.   decoderRegistry.push_back(EncoderEntry("iso_8859-1",  DecodeISO8859_1));
  69.   decoderRegistry.push_back(EncoderEntry("latin1",      DecodeISO8859_1));
  70.   decoderRegistry.push_back(EncoderEntry("latin-1",     DecodeISO8859_1));
  71.   decoderRegistry.push_back(EncoderEntry("latin_1",     DecodeISO8859_1));
  72.   decoderRegistry.push_back(EncoderEntry("ibm-819",     DecodeISO8859_1));
  73.   decoderRegistry.push_back(EncoderEntry("ibm819",      DecodeISO8859_1));
  74.   decoderRegistry.push_back(EncoderEntry("iso8859-2",   DecodeISO8859_2));
  75.   decoderRegistry.push_back(EncoderEntry("iso-8859-2",  DecodeISO8859_2));
  76.   decoderRegistry.push_back(EncoderEntry("iso_8859-2",  DecodeISO8859_2));
  77.   decoderRegistry.push_back(EncoderEntry("latin2",      DecodeISO8859_2));
  78.   decoderRegistry.push_back(EncoderEntry("latin-2",     DecodeISO8859_2));
  79.   decoderRegistry.push_back(EncoderEntry("latin_2",     DecodeISO8859_2));
  80.   decoderRegistry.push_back(EncoderEntry("iso8859-3",   DecodeISO8859_3));
  81.   decoderRegistry.push_back(EncoderEntry("iso-8859-3",  DecodeISO8859_3));
  82.   decoderRegistry.push_back(EncoderEntry("iso_8859-3",  DecodeISO8859_3));
  83.   decoderRegistry.push_back(EncoderEntry("latin3",      DecodeISO8859_3));
  84.   decoderRegistry.push_back(EncoderEntry("latin-3",     DecodeISO8859_3));
  85.   decoderRegistry.push_back(EncoderEntry("latin_3",     DecodeISO8859_3));
  86.   decoderRegistry.push_back(EncoderEntry("iso8859-4",   DecodeISO8859_4));
  87.   decoderRegistry.push_back(EncoderEntry("iso-8859-4",  DecodeISO8859_4));
  88.   decoderRegistry.push_back(EncoderEntry("iso_8859-4",  DecodeISO8859_4));
  89.   decoderRegistry.push_back(EncoderEntry("latin4",      DecodeISO8859_4));
  90.   decoderRegistry.push_back(EncoderEntry("latin-4",     DecodeISO8859_4));
  91.   decoderRegistry.push_back(EncoderEntry("latin_4",     DecodeISO8859_4));
  92.   decoderRegistry.push_back(EncoderEntry("iso8859-15",  DecodeISO8859_15));
  93.   decoderRegistry.push_back(EncoderEntry("iso-8859-15", DecodeISO8859_15));
  94.   decoderRegistry.push_back(EncoderEntry("iso_8859-15", DecodeISO8859_15));
  95.   decoderRegistry.push_back(EncoderEntry("latin9",      DecodeISO8859_15));
  96.   decoderRegistry.push_back(EncoderEntry("latin-9",     DecodeISO8859_15));
  97.   decoderRegistry.push_back(EncoderEntry("latin_9",     DecodeISO8859_15));
  98.   std::sort(decoderRegistry.begin(), decoderRegistry.end());
  99.   initialized = true;
  100. }
  101. static bool DoInitialization()
  102. {
  103.   if(initialized)
  104.     return true;
  105.   InitializeDecoder();
  106.   return true;
  107. }
  108. bool do_initialization = DoInitialization();
  109. int DecodeString(const char * encodingName,
  110.                  const char * inputString,
  111.                  std::basic_string<wchar_t> & outputString)
  112. {
  113.   if (!initialized || encodingName == NULL || inputString == NULL)
  114.     return -1;
  115.   // (1) Convert string to lowercase.
  116.   std::basic_string<char> encoding(encodingName);
  117.   for (unsigned int i = 0; i < encoding.length(); ++i)
  118.     if (encoding[i] < 0x5B && encoding[i] > 0x40)
  119.       encoding[i] += 0x20;
  120.   DECODER_REGISTRY::iterator j 
  121.     = std::lower_bound(decoderRegistry.begin(), decoderRegistry.end(),
  122.                        EncoderEntry(encoding.c_str(), NULL));
  123.   if (j == decoderRegistry.end() || encoding != (*j).name) return -1;
  124.   if ((*j).function(inputString, outputString)) return 0;
  125.   return 1;
  126. }
  127. // ---------------------------------------------------------------------------
  128. // Now we define the 'simple' decoder functions
  129. // ---------------------------------------------------------------------------
  130. bool DecodeASCII(const char * in, std::basic_string<wchar_t> & out)
  131. {
  132.   out.erase();
  133.   while (*in != '') {
  134.     char c = *in;
  135.     if (c > 0x7f || c < 0) return false;
  136.     out += wchar_t(c);
  137.     ++in;
  138.   }
  139.   return true;
  140. }
  141. bool DecodeISO8859_1(const char * in, std::basic_string<wchar_t> & out)
  142. {
  143.   out.erase();
  144.   while (*in != '') {
  145.     out += wchar_t(*in);
  146.     ++in;
  147.   } 
  148.   return true;
  149. }
  150. bool DecodeISO8859_2(const char * in, std::basic_string<wchar_t> & out)
  151. {
  152.   out.erase();
  153.   wchar_t w;
  154.   while (*in != '') {
  155.     switch (*in) {
  156.     case 0xA1:  w = 0x0104;  break; // LATIN CAPITAL LETTER A WITH OGONEK
  157.     case 0xA2:  w = 0x02D8;  break; // BREVE
  158.     case 0xA3:  w = 0x0141;  break; // LATIN CAPITAL LETTER L WITH STROKE
  159.     case 0xA5:  w = 0x013D;  break; // LATIN CAPITAL LETTER L WITH CARON
  160.     case 0xA6:  w = 0x015A;  break; // LATIN CAPITAL LETTER S WITH ACUTE
  161.     case 0xA9:  w = 0x0160;  break; // LATIN CAPITAL LETTER S WITH CARON
  162.     case 0xAA:  w = 0x015E;  break; // LATIN CAPITAL LETTER S WITH CEDILLA
  163.     case 0xAB:  w = 0x0164;  break; // LATIN CAPITAL LETTER T WITH CARON
  164.     case 0xAC:  w = 0x0179;  break; // LATIN CAPITAL LETTER Z WITH ACUTE
  165.     case 0xAE:  w = 0x017D;  break; // LATIN CAPITAL LETTER Z WITH CARON
  166.     case 0xAF:  w = 0x017B;  break; // LATIN CAPITAL LETTER Z WITH DOT ABOVE
  167.     case 0xB1:  w = 0x0105;  break; // LATIN SMALL LETTER A WITH OGONEK
  168.     case 0xB2:  w = 0x02DB;  break; // OGONEK
  169.     case 0xB3:  w = 0x0142;  break; // LATIN SMALL LETTER L WITH STROKE
  170.     case 0xB5:  w = 0x013E;  break; // LATIN SMALL LETTER L WITH CARON
  171.     case 0xB6:  w = 0x015B;  break; // LATIN SMALL LETTER S WITH ACUTE
  172.     case 0xB7:  w = 0x02C7;  break; // CARON
  173.     case 0xB9:  w = 0x0161;  break; // LATIN SMALL LETTER S WITH CARON
  174.     case 0xBA:  w = 0x015F;  break; // LATIN SMALL LETTER S WITH CEDILLA
  175.     case 0xBB:  w = 0x0165;  break; // LATIN SMALL LETTER T WITH CARON
  176.     case 0xBC:  w = 0x017A;  break; // LATIN SMALL LETTER Z WITH ACUTE
  177.     case 0xBD:  w = 0x02DD;  break; // DOUBLE ACUTE ACCENT
  178.     case 0xBE:  w = 0x017E;  break; // LATIN SMALL LETTER Z WITH CARON
  179.     case 0xBF:  w = 0x017C;  break; // LATIN SMALL LETTER Z WITH DOT ABOVE
  180.     case 0xC0:  w = 0x0154;  break; // LATIN CAPITAL LETTER R WITH ACUTE
  181.     case 0xC3:  w = 0x0102;  break; // LATIN CAPITAL LETTER A WITH BREVE
  182.     case 0xC5:  w = 0x0139;  break; // LATIN CAPITAL LETTER L WITH ACUTE
  183.     case 0xC6:  w = 0x0106;  break; // LATIN CAPITAL LETTER C WITH ACUTE
  184.     case 0xC8:  w = 0x010C;  break; // LATIN CAPITAL LETTER C WITH CARON
  185.     case 0xCA:  w = 0x0118;  break; // LATIN CAPITAL LETTER E WITH OGONEK
  186.     case 0xCC:  w = 0x011A;  break; // LATIN CAPITAL LETTER E WITH CARON
  187.     case 0xCF:  w = 0x010E;  break; // LATIN CAPITAL LETTER D WITH CARON
  188.     case 0xD0:  w = 0x0110;  break; // LATIN CAPITAL LETTER D WITH STROKE
  189.     case 0xD1:  w = 0x0143;  break; // LATIN CAPITAL LETTER N WITH ACUTE
  190.     case 0xD2:  w = 0x0147;  break; // LATIN CAPITAL LETTER N WITH CARON
  191.     case 0xD5:  w = 0x0150;  break; // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
  192.     case 0xD8:  w = 0x0158;  break; // LATIN CAPITAL LETTER R WITH CARON
  193.     case 0xD9:  w = 0x016E;  break; // LATIN CAPITAL LETTER U WITH RING ABOVE
  194.     case 0xDB:  w = 0x0170;  break; // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
  195.     case 0xDE:  w = 0x0162;  break; // LATIN CAPITAL LETTER T WITH CEDILLA
  196.     case 0xE0:  w = 0x0155;  break; // LATIN SMALL LETTER R WITH ACUTE
  197.     case 0xE3:  w = 0x0103;  break; // LATIN SMALL LETTER A WITH BREVE
  198.     case 0xE5:  w = 0x013A;  break; // LATIN SMALL LETTER L WITH ACUTE
  199.     case 0xE6:  w = 0x0107;  break; // LATIN SMALL LETTER C WITH ACUTE
  200.     case 0xE8:  w = 0x010D;  break; // LATIN SMALL LETTER C WITH CARON
  201.     case 0xEA:  w = 0x0119;  break; // LATIN SMALL LETTER E WITH OGONEK
  202.     case 0xEC:  w = 0x011B;  break; // LATIN SMALL LETTER E WITH CARON
  203.     case 0xEF:  w = 0x010F;  break; // LATIN SMALL LETTER D WITH CARON
  204.     case 0xF0:  w = 0x0111;  break; // LATIN SMALL LETTER D WITH STROKE
  205.     case 0xF1:  w = 0x0144;  break; // LATIN SMALL LETTER N WITH ACUTE
  206.     case 0xF2:  w = 0x0148;  break; // LATIN SMALL LETTER N WITH CARON
  207.     case 0xF5:  w = 0x0151;  break; // LATIN SMALL LETTER O WITH DOUBLE ACUTE
  208.     case 0xF8:  w = 0x0159;  break; // LATIN SMALL LETTER R WITH CARON
  209.     case 0xF9:  w = 0x016F;  break; // LATIN SMALL LETTER U WITH RING ABOVE
  210.     case 0xFB:  w = 0x0171;  break; // LATIN SMALL LETTER U WITH DOUBLE ACUTE
  211.     case 0xFE:  w = 0x0163;  break; // LATIN SMALL LETTER T WITH CEDILLA
  212.     case 0xFF:  w = 0x02D9;  break; // DOT ABOVE
  213.     default:
  214.       w = wchar_t(*in);
  215.       break;
  216.     }
  217.     out += w;
  218.     ++in;
  219.   }
  220.   return true;
  221. }
  222. bool DecodeISO8859_3(const char * in, std::basic_string<wchar_t> & out)
  223. {
  224.   out.erase();
  225.   wchar_t w;
  226.   while (*in != '') {
  227.     switch (*in) {
  228.     case 0xA1:  w = 0x0126;  break; // LATIN CAPITAL LETTER H WITH STROKE
  229.     case 0xA2:  w = 0x02D8;  break; // BREVE
  230.     case 0xA6:  w = 0x0124;  break; // LATIN CAPITAL LETTER H WITH CIRCUMFLEX
  231.     case 0xA9:  w = 0x0130;  break; // LATIN CAPITAL LETTER I WITH DOT ABOVE
  232.     case 0xAA:  w = 0x015E;  break; // LATIN CAPITAL LETTER S WITH CEDILLA
  233.     case 0xAB:  w = 0x011E;  break; // LATIN CAPITAL LETTER G WITH BREVE
  234.     case 0xAC:  w = 0x0134;  break; // LATIN CAPITAL LETTER J WITH CIRCUMFLEX
  235.     case 0xAF:  w = 0x017B;  break; // LATIN CAPITAL LETTER Z WITH DOT ABOVE
  236.     case 0xB1:  w = 0x0127;  break; // LATIN SMALL LETTER H WITH STROKE
  237.     case 0xB6:  w = 0x0125;  break; // LATIN SMALL LETTER H WITH CIRCUMFLEX
  238.     case 0xB9:  w = 0x0131;  break; // LATIN SMALL LETTER DOTLESS I
  239.     case 0xBA:  w = 0x015F;  break; // LATIN SMALL LETTER S WITH CEDILLA
  240.     case 0xBB:  w = 0x011F;  break; // LATIN SMALL LETTER G WITH BREVE
  241.     case 0xBC:  w = 0x0135;  break; // LATIN SMALL LETTER J WITH CIRCUMFLEX
  242.     case 0xBF:  w = 0x017C;  break; // LATIN SMALL LETTER Z WITH DOT ABOVE
  243.     case 0xC5:  w = 0x010A;  break; // LATIN CAPITAL LETTER C WITH DOT ABOVE
  244.     case 0xC6:  w = 0x0108;  break; // LATIN CAPITAL LETTER C WITH CIRCUMFLEX
  245.     case 0xD5:  w = 0x0120;  break; // LATIN CAPITAL LETTER G WITH DOT ABOVE
  246.     case 0xD8:  w = 0x011C;  break; // LATIN CAPITAL LETTER G WITH CIRCUMFLEX
  247.     case 0xDD:  w = 0x016C;  break; // LATIN CAPITAL LETTER U WITH BREVE
  248.     case 0xDE:  w = 0x015C;  break; // LATIN CAPITAL LETTER S WITH CIRCUMFLEX
  249.     case 0xE5:  w = 0x010B;  break; // LATIN SMALL LETTER C WITH DOT ABOVE
  250.     case 0xE6:  w = 0x0109;  break; // LATIN SMALL LETTER C WITH CIRCUMFLEX
  251.     case 0xF5:  w = 0x0121;  break; // LATIN SMALL LETTER G WITH DOT ABOVE
  252.     case 0xF8:  w = 0x011D;  break; // LATIN SMALL LETTER G WITH CIRCUMFLEX
  253.     case 0xFD:  w = 0x016D;  break; // LATIN SMALL LETTER U WITH BREVE
  254.     case 0xFE:  w = 0x015D;  break; // LATIN SMALL LETTER S WITH CIRCUMFLEX
  255.     case 0xFF:  w = 0x02D9;  break; // DOT ABOVE
  256.     default:
  257.       w = wchar_t(*in);
  258.       break;
  259.     }
  260.     out += w;
  261.     ++in;
  262.   }
  263.   return true;
  264. }
  265. bool DecodeISO8859_4(const char * in, std::basic_string<wchar_t> & out)
  266. {
  267.   out.erase();
  268.   wchar_t w;
  269.   while (*in != '') {
  270.     switch (*in) {
  271.     case 0xA1:  w = 0x0104;  break; // LATIN CAPITAL LETTER A WITH OGONEK
  272.     case 0xA2:  w = 0x0138;  break; // LATIN SMALL LETTER KRA
  273.     case 0xA3:  w = 0x0156;  break; // LATIN CAPITAL LETTER R WITH CEDILLA
  274.     case 0xA5:  w = 0x0128;  break; // LATIN CAPITAL LETTER I WITH TILDE
  275.     case 0xA6:  w = 0x013B;  break; // LATIN CAPITAL LETTER L WITH CEDILLA
  276.     case 0xA9:  w = 0x0160;  break; // LATIN CAPITAL LETTER S WITH CARON
  277.     case 0xAA:  w = 0x0112;  break; // LATIN CAPITAL LETTER E WITH MACRON
  278.     case 0xAB:  w = 0x0122;  break; // LATIN CAPITAL LETTER G WITH CEDILLA
  279.     case 0xAC:  w = 0x0166;  break; // LATIN CAPITAL LETTER T WITH STROKE
  280.     case 0xAE:  w = 0x017D;  break; // LATIN CAPITAL LETTER Z WITH CARON
  281.     case 0xB1:  w = 0x0105;  break; // LATIN SMALL LETTER A WITH OGONEK
  282.     case 0xB2:  w = 0x02DB;  break; // OGONEK
  283.     case 0xB3:  w = 0x0157;  break; // LATIN SMALL LETTER R WITH CEDILLA
  284.     case 0xB5:  w = 0x0129;  break; // LATIN SMALL LETTER I WITH TILDE
  285.     case 0xB6:  w = 0x013C;  break; // LATIN SMALL LETTER L WITH CEDILLA
  286.     case 0xB7:  w = 0x02C7;  break; // CARON
  287.     case 0xB9:  w = 0x0161;  break; // LATIN SMALL LETTER S WITH CARON
  288.     case 0xBA:  w = 0x0113;  break; // LATIN SMALL LETTER E WITH MACRON
  289.     case 0xBB:  w = 0x0123;  break; // LATIN SMALL LETTER G WITH CEDILLA
  290.     case 0xBC:  w = 0x0167;  break; // LATIN SMALL LETTER T WITH STROKE
  291.     case 0xBD:  w = 0x014A;  break; // LATIN CAPITAL LETTER ENG
  292.     case 0xBE:  w = 0x017E;  break; // LATIN SMALL LETTER Z WITH CARON
  293.     case 0xBF:  w = 0x014B;  break; // LATIN SMALL LETTER ENG
  294.     case 0xC0:  w = 0x0100;  break; // LATIN CAPITAL LETTER A WITH MACRON
  295.     case 0xC7:  w = 0x012E;  break; // LATIN CAPITAL LETTER I WITH OGONEK
  296.     case 0xC8:  w = 0x010C;  break; // LATIN CAPITAL LETTER C WITH CARON
  297.     case 0xCA:  w = 0x0118;  break; // LATIN CAPITAL LETTER E WITH OGONEK
  298.     case 0xCC:  w = 0x0116;  break; // LATIN CAPITAL LETTER E WITH DOT ABOVE
  299.     case 0xCF:  w = 0x012A;  break; // LATIN CAPITAL LETTER I WITH MACRON
  300.     case 0xD0:  w = 0x0110;  break; // LATIN CAPITAL LETTER D WITH STROKE
  301.     case 0xD1:  w = 0x0145;  break; // LATIN CAPITAL LETTER N WITH CEDILLA
  302.     case 0xD2:  w = 0x014C;  break; // LATIN CAPITAL LETTER O WITH MACRON
  303.     case 0xD3:  w = 0x0136;  break; // LATIN CAPITAL LETTER K WITH CEDILLA
  304.     case 0xD9:  w = 0x0172;  break; // LATIN CAPITAL LETTER U WITH OGONEK
  305.     case 0xDD:  w = 0x0168;  break; // LATIN CAPITAL LETTER U WITH TILDE
  306.     case 0xDE:  w = 0x016A;  break; // LATIN CAPITAL LETTER U WITH MACRON
  307.     case 0xE0:  w = 0x0101;  break; // LATIN SMALL LETTER A WITH MACRON
  308.     case 0xE7:  w = 0x012F;  break; // LATIN SMALL LETTER I WITH OGONEK
  309.     case 0xE8:  w = 0x010D;  break; // LATIN SMALL LETTER C WITH CARON
  310.     case 0xEA:  w = 0x0119;  break; // LATIN SMALL LETTER E WITH OGONEK
  311.     case 0xEC:  w = 0x0117;  break; // LATIN SMALL LETTER E WITH DOT ABOVE
  312.     case 0xEF:  w = 0x012B;  break; // LATIN SMALL LETTER I WITH MACRON
  313.     case 0xF0:  w = 0x0111;  break; // LATIN SMALL LETTER D WITH STROKE
  314.     case 0xF1:  w = 0x0146;  break; // LATIN SMALL LETTER N WITH CEDILLA
  315.     case 0xF2:  w = 0x014D;  break; // LATIN SMALL LETTER O WITH MACRON
  316.     case 0xF3:  w = 0x0137;  break; // LATIN SMALL LETTER K WITH CEDILLA
  317.     case 0xF9:  w = 0x0173;  break; // LATIN SMALL LETTER U WITH OGONEK
  318.     case 0xFD:  w = 0x0169;  break; // LATIN SMALL LETTER U WITH TILDE
  319.     case 0xFE:  w = 0x016B;  break; // LATIN SMALL LETTER U WITH MACRON
  320.     case 0xFF:  w = 0x02D9;  break; // DOT ABOVE
  321.     default:
  322.       w = wchar_t(*in);
  323.       break;
  324.     }
  325.     out += w;
  326.     ++in;
  327.   }
  328.   return true;
  329. }
  330. bool DecodeISO8859_15(const char * in, std::basic_string<wchar_t> & out)
  331. {
  332.   out.erase();
  333.   wchar_t w;
  334.   while (*in != '') {
  335.     switch (*in) {
  336.     case 0xA4:  w = 0x20AC;  break; // EURO SIGN
  337.     case 0xA6:  w = 0x0160;  break; // LATIN CAPITAL LETTER S WITH CARON
  338.     case 0xA8:  w = 0x0161;  break; // LATIN SMALL LETTER S WITH CARON
  339.     case 0xB4:  w = 0x017D;  break; // LATIN CAPITAL LETTER Z WITH CARON
  340.     case 0xB8:  w = 0x017E;  break; // LATIN SMALL LETTER Z WITH CARON
  341.     case 0xBC:  w = 0x0152;  break; // LATIN CAPITAL LIGATURE OE
  342.     case 0xBD:  w = 0x0153;  break; // LATIN SMALL LIGATURE OE
  343.     case 0xBE:  w = 0x0178;  break; // LATIN CAPITAL LETTER Y WITH DIAERESIS
  344.     default:
  345.       w = wchar_t(*in);
  346.       break;
  347.     }
  348.     out += w;
  349.     ++in;
  350.   }
  351.   return true;
  352. }
  353. #endif
  354. // ---------------------------------------------------------------------------
  355. // Jerry Carter writes:
  356. //
  357. // The UTF-8 encoding / decoding routines were modified from the Apache Xerces
  358. // project.  The original translated from UTF-8 to UTF-16.  In this version, I
  359. // have removed support for surrogate characters.  This removes the difference
  360. // between platforms which treat wchar_t as UTF-16 (Windows) and those which
  361. // use UTF-32 (Linux, MacOS, etc.).
  362. //
  363. // The Apache license appears below (as required).
  364. /*
  365.  * The Apache Software License, Version 1.1
  366.  * 
  367.  * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
  368.  * reserved.
  369.  * 
  370.  * Redistribution and use in source and binary forms, with or without
  371.  * modification, are permitted provided that the following conditions
  372.  * are met:
  373.  * 
  374.  * 1. Redistributions of source code must retain the above copyright
  375.  *    notice, this list of conditions and the following disclaimer. 
  376.  * 
  377.  * 2. Redistributions in binary form must reproduce the above copyright
  378.  *    notice, this list of conditions and the following disclaimer in
  379.  *    the documentation and/or other materials provided with the
  380.  *    distribution.
  381.  * 
  382.  * 3. The end-user documentation included with the redistribution,
  383.  *    if any, must include the following acknowledgment:  
  384.  *       "This product includes software developed by the
  385.  *        Apache Software Foundation (http://www.apache.org/)."
  386.  *    Alternately, this acknowledgment may appear in the software itself,
  387.  *    if and wherever such third-party acknowledgments normally appear.
  388.  * 
  389.  * 4. The names "Xerces" and "Apache Software Foundation" must
  390.  *    not be used to endorse or promote products derived from this
  391.  *    software without prior written permission. For written 
  392.  *    permission, please contact apache@apache.org.
  393.  * 
  394.  * 5. Products derived from this software may not be called "Apache",
  395.  *    nor may "Apache" appear in their name, without prior written
  396.  *    permission of the Apache Software Foundation.
  397.  * 
  398.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  399.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  400.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  401.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  402.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  403.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  404.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  405.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  406.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  407.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  408.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  409.  * SUCH DAMAGE.
  410.  * ====================================================================
  411.  * 
  412.  * This software consists of voluntary contributions made by many
  413.  * individuals on behalf of the Apache Software Foundation, and was
  414.  * originally based on software copyright (c) 1999, International
  415.  * Business Machines, Inc., http://www.ibm.com .  For more information
  416.  * on the Apache Software Foundation, please see
  417.  * <http://www.apache.org/>.
  418.  */
  419. //  gUTFBytes
  420. //      A list of counts of trailing bytes for each initial byte in the input.
  421. //
  422. //  gUTFOffsets
  423. //      A list of values to offset each result char type, according to how
  424. //      many source bytes when into making it.
  425. //
  426. //  gFirstByteMark
  427. //      A list of values to mask onto the first byte of an encoded sequence,
  428. //      indexed by the number of bytes used to create the sequence.
  429. static const char gUTFBytes[256] =
  430. {
  431.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  432.     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  433.     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  434.     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  435.     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  436.     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  437.     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  438.     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  439.     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  440.     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  441.     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  442.     ,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  443.     ,   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
  444.     ,   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
  445.     ,   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
  446.     ,   3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5
  447. };
  448. static const unsigned long gUTFOffsets[6] =
  449. {  0, 0x3080, 0xE2080, 0x3C82080, 0xFA082080, 0x82082080 };
  450. static const unsigned char gFirstByteMark[7] =
  451. {  0x00, 0x00, 0xC0, 0xE0,
  452.    0xF0, 0xF8, 0xFC };
  453. int SWIutf8towcslen(const unsigned char* src)
  454. {
  455.   int len = 0;
  456.   while (*src != '') {
  457.     unsigned int trailingBytes;
  458.     // Get the next leading byte out
  459.     const unsigned char firstByte = (unsigned char) *src;
  460.     // See how many trailing src bytes this sequence is going to require
  461.     trailingBytes = gUTFBytes[firstByte];
  462.     src += trailingBytes + 1;
  463.     len++;
  464.   }
  465.   return len;
  466. }
  467. SWIcharResult SWIutf8towcs( const unsigned char *src, wchar_t *dst, int maxdstlen )
  468. {
  469.   // Get pointers to our start and end points of the input buffer
  470.   const unsigned char* srcPtr = src;
  471.   const unsigned char* srcEnd = src + strlen((const char *)src);
  472.   //wchar_t *dstSave = dst;
  473.   wchar_t *dstEnd = dst+maxdstlen;  /* leave room for null */
  474.   //  We now loop until we run out of input data.
  475.   while (srcPtr < srcEnd) {
  476.     unsigned int trailingBytes;
  477.     unsigned long tmpVal = 0;
  478.     // Get the next leading byte out
  479.     const unsigned char firstByte = (unsigned char) *srcPtr;
  480.     // Special-case ASCII, which is a leading byte value of <= 127
  481.     if (firstByte <= 127) {
  482.       *dst++ = (wchar_t) firstByte;
  483.       srcPtr++;
  484.       continue;
  485.     }
  486.     // See how many trailing src bytes this sequence is going to require
  487.     trailingBytes = gUTFBytes[firstByte];
  488.     
  489.     //  If there are not enough source bytes to do this one, then we
  490.     //  are done. Note that we done >= here because we are implicitly
  491.     //  counting the 1 byte we get no matter what.
  492.     if (srcPtr + trailingBytes >= srcEnd)
  493.       return SWIchar_FAIL;  // ??
  494.     // Looks ok, so lets build up the value
  495.     switch (trailingBytes) {
  496.     case 5: tmpVal += *srcPtr++; tmpVal <<= 6;
  497.     case 4: tmpVal += *srcPtr++; tmpVal <<= 6;
  498.     case 3: tmpVal += *srcPtr++; tmpVal <<= 6;
  499.     case 2: tmpVal += *srcPtr++; tmpVal <<= 6;
  500.     case 1: tmpVal += *srcPtr++; tmpVal <<= 6;
  501.     case 0: tmpVal += *srcPtr++;
  502.       break;
  503.     default:
  504.       return SWIchar_ERROR;
  505.     }
  506.     tmpVal -= gUTFOffsets[trailingBytes];
  507.     // If surrogate pairs would be required for 16-bit characters, fail.
  508.     if (tmpVal & 0xFFFF0000)
  509.       return SWIchar_FAIL;
  510.     if ( dst >= dstEnd ) {
  511.       return SWIchar_BUFFER_OVERFLOW;
  512.     }
  513.     *dst++ = (wchar_t)tmpVal;
  514.   }
  515.   *dst = L'';
  516.   
  517.  // return dst-dstSave;
  518.   return SWIchar_SUCCESS;   // check this (CARO)
  519. }
  520. int SWIwcstoutf8len(const wchar_t* src)
  521. {
  522.   int len = 0;
  523.   while (*src != 0) {
  524.     unsigned int encodedBytes;
  525.     wchar_t curVal = (*src++) & 0x0000FFFF;
  526.     // Watchout for surrogates.
  527.     if ((curVal >= 0xD800 && curVal <= 0xDBFF) || curVal == 0xFFFE ||
  528. curVal == 0xFFFF)
  529.       return -2;
  530.     // Figure out how many bytes we need
  531.     if (curVal < 0x80)                encodedBytes = 1;
  532.     else if (curVal < 0x800)          encodedBytes = 2;
  533.     else if (curVal < 0x10000)        encodedBytes = 3;
  534.     else if (curVal < 0x200000)       encodedBytes = 4;
  535.     else if (curVal < 0x4000000)      encodedBytes = 5;
  536.     else if (curVal <= 0x7FFFFFFF)    encodedBytes = 6;
  537.     else {
  538.       // THIS SHOULD NOT HAPPEN!
  539.       return -2;
  540.     }
  541.     //  And spit out the bytes. We spit them out in reverse order
  542.     //  here, so bump up the output pointer and work down as we go.
  543.     len += encodedBytes;
  544.   }
  545.   return len;
  546. }
  547. SWIcharResult SWIwcstoutf8(const wchar_t *src, unsigned char *dst, int maxdstlen)
  548. {
  549.   //  Get pointers to our start and end points of the input buffer.
  550.   const wchar_t* srcPtr = src;
  551.   const wchar_t* srcEnd = srcPtr + wcslen(src);
  552.   //unsigned char *dstSave = dst;
  553.   unsigned char *dstEnd = dst+maxdstlen;
  554.   while (srcPtr < srcEnd) {
  555.     unsigned int encodedBytes;
  556.     wchar_t curVal = (*srcPtr++) & 0x0000FFFF;
  557.     // Watchout for surrogates.
  558.     if ( ((curVal >= 0xD800) && (curVal <= 0xDFFF)) ||
  559.          ((curVal == 0xFFFE) || curVal == 0xFFFF) )
  560.       return SWIchar_FAIL;
  561.     // Figure out how many bytes we need
  562.     if (curVal < 0x80)                encodedBytes = 1;
  563.     else if (curVal < 0x800)          encodedBytes = 2;
  564.     else if (curVal < 0x10000)        encodedBytes = 3;
  565.     else if (curVal < 0x200000)       encodedBytes = 4;
  566.     else if (curVal < 0x4000000)      encodedBytes = 5;
  567.     else if (curVal <= 0x7FFFFFFF)    encodedBytes = 6;
  568.     else {
  569.       // THIS SHOULD NOT HAPPEN!
  570.       return SWIchar_ERROR;
  571.     }
  572.     //  And spit out the bytes. We spit them out in reverse order
  573.     //  here, so bump up the output pointer and work down as we go.
  574.     dst += encodedBytes;
  575.     if ( dst > dstEnd ) {
  576.       return SWIchar_BUFFER_OVERFLOW;
  577.     }
  578.     switch(encodedBytes) {
  579.     case 6 : *--dst = (unsigned char) ((curVal | 0x80) & 0xBF);
  580.       curVal >>= 6;
  581.     case 5 : *--dst = (unsigned char)((curVal | 0x80) & 0xBF);
  582.       curVal >>= 6;
  583.     case 4 : *--dst = (unsigned char)((curVal | 0x80) & 0xBF);
  584.       curVal >>= 6;
  585.     case 3 : *--dst = (unsigned char)((curVal | 0x80) & 0xBF);
  586.       curVal >>= 6;
  587.     case 2 : *--dst = (unsigned char)((curVal | 0x80) & 0xBF);
  588.       curVal >>= 6;
  589.     case 1 : *--dst = (unsigned char)(curVal | gFirstByteMark[encodedBytes]);
  590.     }
  591.     dst += encodedBytes;
  592.   }
  593.   *dst = '';
  594.   // return dst-dstSave
  595.   return SWIchar_SUCCESS; // check this (CARO)
  596. }