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 #include "regenc.h"
00031
00032 #define UTF16_IS_SURROGATE_FIRST(c) (((c) & 0xfc) == 0xd8)
00033 #define UTF16_IS_SURROGATE_SECOND(c) (((c) & 0xfc) == 0xdc)
00034 #define UTF16_IS_SURROGATE(c) (((c) & 0xf8) == 0xd8)
00035
00036 #if 0
00037 static const int EncLen_UTF16[] = {
00038 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00039 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00040 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00041 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00042 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00043 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00044 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00045 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00046 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00047 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00048 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00049 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00050 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00051 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 2, 2, 2, 2,
00052 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00053 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
00054 };
00055 #endif
00056
00057 static int
00058 utf16be_mbc_enc_len(const UChar* p, const OnigUChar* e ARG_UNUSED,
00059 OnigEncoding enc ARG_UNUSED)
00060 {
00061 int byte = p[0];
00062 if (!UTF16_IS_SURROGATE(byte)) {
00063 if (2 <= e-p)
00064 return ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(2);
00065 else
00066 return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(1);
00067 }
00068 if (UTF16_IS_SURROGATE_FIRST(byte)) {
00069 switch (e-p) {
00070 case 1: return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(3);
00071 case 2: return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(2);
00072 case 3:
00073 if (UTF16_IS_SURROGATE_SECOND(p[2]))
00074 return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(1);
00075 break;
00076 default:
00077 if (UTF16_IS_SURROGATE_SECOND(p[2]))
00078 return ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(4);
00079 break;
00080 }
00081 }
00082 return ONIGENC_CONSTRUCT_MBCLEN_INVALID();
00083 }
00084
00085 static int
00086 utf16be_is_mbc_newline(const UChar* p, const UChar* end,
00087 OnigEncoding enc)
00088 {
00089 if (p + 1 < end) {
00090 if (*(p+1) == 0x0a && *p == 0x00)
00091 return 1;
00092 #ifdef USE_UNICODE_ALL_LINE_TERMINATORS
00093 if ((*(p+1) == 0x0b || *(p+1) == 0x0c || *(p+1) == 0x0d || *(p+1) == 0x85)
00094 && *p == 0x00)
00095 return 1;
00096 if (*p == 0x20 && (*(p+1) == 0x29 || *(p+1) == 0x28))
00097 return 1;
00098 #endif
00099 }
00100 return 0;
00101 }
00102
00103 static OnigCodePoint
00104 utf16be_mbc_to_code(const UChar* p, const UChar* end ARG_UNUSED,
00105 OnigEncoding enc)
00106 {
00107 OnigCodePoint code;
00108
00109 if (UTF16_IS_SURROGATE_FIRST(*p)) {
00110 code = ((((p[0] << 8) + p[1]) & 0x03ff) << 10)
00111 + (((p[2] << 8) + p[3]) & 0x03ff) + 0x10000;
00112 }
00113 else {
00114 code = p[0] * 256 + p[1];
00115 }
00116 return code;
00117 }
00118
00119 static int
00120 utf16be_code_to_mbclen(OnigCodePoint code,
00121 OnigEncoding enc)
00122 {
00123 return (code > 0xffff ? 4 : 2);
00124 }
00125
00126 static int
00127 utf16be_code_to_mbc(OnigCodePoint code, UChar *buf,
00128 OnigEncoding enc)
00129 {
00130 UChar* p = buf;
00131
00132 if (code > 0xffff) {
00133 unsigned int high = (code >> 10) + 0xD7C0;
00134 unsigned int low = (code & 0x3FF) + 0xDC00;
00135 *p++ = (high >> 8) & 0xFF;
00136 *p++ = high & 0xFF;
00137 *p++ = (low >> 8) & 0xFF;
00138 *p++ = low & 0xFF;
00139 return 4;
00140 }
00141 else {
00142 *p++ = (UChar )((code & 0xff00) >> 8);
00143 *p++ = (UChar )(code & 0xff);
00144 return 2;
00145 }
00146 }
00147
00148 static int
00149 utf16be_mbc_case_fold(OnigCaseFoldType flag,
00150 const UChar** pp, const UChar* end, UChar* fold,
00151 OnigEncoding enc)
00152 {
00153 const UChar* p = *pp;
00154
00155 if (ONIGENC_IS_ASCII_CODE(*(p+1)) && *p == 0) {
00156 p++;
00157 #ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
00158 if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
00159 if (*p == 0x49) {
00160 *fold++ = 0x01;
00161 *fold = 0x31;
00162 (*pp) += 2;
00163 return 2;
00164 }
00165 }
00166 #endif
00167
00168 *fold++ = 0;
00169 *fold = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
00170 *pp += 2;
00171 return 2;
00172 }
00173 else
00174 return onigenc_unicode_mbc_case_fold(enc, flag,
00175 pp, end, fold);
00176 }
00177
00178 #if 0
00179 static int
00180 utf16be_is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
00181 {
00182 const UChar* p = *pp;
00183
00184 (*pp) += EncLen_UTF16[*p];
00185
00186 if (*p == 0) {
00187 int c, v;
00188
00189 p++;
00190 if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
00191 return TRUE;
00192 }
00193
00194 c = *p;
00195 v = ONIGENC_IS_UNICODE_ISO_8859_1_BIT_CTYPE(c,
00196 (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
00197
00198 if ((v | BIT_CTYPE_LOWER) != 0) {
00199
00200 if (c >= 0xaa && c <= 0xba)
00201 return FALSE;
00202 else
00203 return TRUE;
00204 }
00205 return (v != 0 ? TRUE : FALSE);
00206 }
00207
00208 return FALSE;
00209 }
00210 #endif
00211
00212 static UChar*
00213 utf16be_left_adjust_char_head(const UChar* start, const UChar* s, const UChar* end,
00214 OnigEncoding enc ARG_UNUSED)
00215 {
00216 if (s <= start) return (UChar* )s;
00217
00218 if ((s - start) % 2 == 1) {
00219 s--;
00220 }
00221
00222 if (UTF16_IS_SURROGATE_SECOND(*s) && s > start + 1)
00223 s -= 2;
00224
00225 return (UChar* )s;
00226 }
00227
00228 static int
00229 utf16be_get_case_fold_codes_by_str(OnigCaseFoldType flag,
00230 const OnigUChar* p, const OnigUChar* end,
00231 OnigCaseFoldCodeItem items[],
00232 OnigEncoding enc)
00233 {
00234 return onigenc_unicode_get_case_fold_codes_by_str(enc,
00235 flag, p, end, items);
00236 }
00237
00238 OnigEncodingDefine(utf_16be, UTF_16BE) = {
00239 utf16be_mbc_enc_len,
00240 "UTF-16BE",
00241 4,
00242 2,
00243 utf16be_is_mbc_newline,
00244 utf16be_mbc_to_code,
00245 utf16be_code_to_mbclen,
00246 utf16be_code_to_mbc,
00247 utf16be_mbc_case_fold,
00248 onigenc_unicode_apply_all_case_fold,
00249 utf16be_get_case_fold_codes_by_str,
00250 onigenc_unicode_property_name_to_ctype,
00251 onigenc_unicode_is_code_ctype,
00252 onigenc_utf16_32_get_ctype_code_range,
00253 utf16be_left_adjust_char_head,
00254 onigenc_always_false_is_allowed_reverse_match,
00255 0,
00256 ONIGENC_FLAG_UNICODE,
00257 };
00258 ENC_ALIAS("UCS-2BE", "UTF-16BE")
00259