enc/utf_16be.c

Go to the documentation of this file.
00001 /**********************************************************************
00002   utf_16be.c -  Oniguruma (regular expression library)
00003 **********************************************************************/
00004 /*-
00005  * Copyright (c) 2002-2008  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  * 1. Redistributions of source code must retain the above copyright
00012  *    notice, this list of conditions and the following disclaimer.
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in the
00015  *    documentation and/or other materials provided with the distribution.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
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       /* 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
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",   /* name */
00241   4,            /* max byte length */
00242   2,            /* min byte length */
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 

Generated on 19 Jul 2016 for Ruby by  doxygen 1.4.7