00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "Poco/UTF16Encoding.h"
00038 #include "Poco/ByteOrder.h"
00039 #include "Poco/String.h"
00040
00041
00042 namespace Poco {
00043
00044
00045 const char* UTF16Encoding::_names[] =
00046 {
00047 "UTF-16",
00048 "UTF16",
00049 NULL
00050 };
00051
00052
00053 const TextEncoding::CharacterMap UTF16Encoding::_charMap =
00054 {
00055 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00056 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00057 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00058 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00059 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00060 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00061 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00062 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00063 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00064 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00065 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00066 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00067 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00068 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00069 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00070 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00071 };
00072
00073
00074 UTF16Encoding::UTF16Encoding(ByteOrderType byteOrder)
00075 {
00076 setByteOrder(byteOrder);
00077 }
00078
00079
00080 UTF16Encoding::UTF16Encoding(int byteOrderMark)
00081 {
00082 setByteOrder(byteOrderMark);
00083 }
00084
00085
00086 UTF16Encoding::~UTF16Encoding()
00087 {
00088 }
00089
00090
00091 UTF16Encoding::ByteOrderType UTF16Encoding::getByteOrder() const
00092 {
00093 #if defined(POCO_ARCH_BIG_ENDIAN)
00094 return _flipBytes ? LITTLE_ENDIAN_BYTE_ORDER : BIG_ENDIAN_BYTE_ORDER;
00095 #else
00096 return _flipBytes ? BIG_ENDIAN_BYTE_ORDER : LITTLE_ENDIAN_BYTE_ORDER;
00097 #endif
00098 }
00099
00100
00101 void UTF16Encoding::setByteOrder(ByteOrderType byteOrder)
00102 {
00103 #if defined(POCO_ARCH_BIG_ENDIAN)
00104 _flipBytes = byteOrder == LITTLE_ENDIAN_BYTE_ORDER;
00105 #else
00106 _flipBytes = byteOrder == BIG_ENDIAN_BYTE_ORDER;;
00107 #endif
00108 }
00109
00110
00111 void UTF16Encoding::setByteOrder(int byteOrderMark)
00112 {
00113 _flipBytes = byteOrderMark != 0xFEFF;
00114 }
00115
00116
00117 const char* UTF16Encoding::canonicalName() const
00118 {
00119 return _names[0];
00120 }
00121
00122
00123 bool UTF16Encoding::isA(const std::string& encodingName) const
00124 {
00125 for (const char** name = _names; *name; ++name)
00126 {
00127 if (Poco::icompare(encodingName, *name) == 0)
00128 return true;
00129 }
00130 return false;
00131 }
00132
00133
00134 const TextEncoding::CharacterMap& UTF16Encoding::characterMap() const
00135 {
00136 return _charMap;
00137 }
00138
00139
00140 int UTF16Encoding::convert(const unsigned char* bytes) const
00141 {
00142 UInt16 uc;
00143 unsigned char* p = (unsigned char*) &uc;
00144 *p++ = *bytes++;
00145 *p++ = *bytes++;
00146 return _flipBytes ? ByteOrder::flipBytes(uc) : uc;
00147 }
00148
00149
00150 int UTF16Encoding::convert(int ch, unsigned char* bytes, int length) const
00151 {
00152 if (ch <= 0xFFFF)
00153 {
00154 if (bytes && length >= 2)
00155 {
00156 UInt16 ch1 = _flipBytes ? ByteOrder::flipBytes((UInt16) ch) : (UInt16) ch;
00157 unsigned char* p = (unsigned char*) &ch1;
00158 *bytes++ = *p++;
00159 *bytes++ = *p++;
00160 }
00161 return 2;
00162 }
00163 else
00164 {
00165 if (bytes && length >= 4)
00166 {
00167 int ch1 = ch - 0x10000;
00168 UInt16 w1 = 0xD800 + ((ch1 >> 10) & 0x3FF);
00169 UInt16 w2 = 0xDC00 + (ch1 & 0x3FF);
00170 if (_flipBytes)
00171 {
00172 w1 = ByteOrder::flipBytes(w1);
00173 w2 = ByteOrder::flipBytes(w2);
00174 }
00175 unsigned char* p = (unsigned char*) &w1;
00176 *bytes++ = *p++;
00177 *bytes++ = *p++;
00178 p = (unsigned char*) &w2;
00179 *bytes++ = *p++;
00180 *bytes++ = *p++;
00181 }
00182 return 4;
00183 }
00184 }
00185
00186
00187 }