Changeset 1269

Show
Ignore:
Timestamp:
11/26/07 03:28:16 (9 months ago)
Author:
Geert
Message:

Removing enable_utf8 config setting.

The reason it was added in r1250 was to make Kohana load faster, which is a valid reason. However, UTF-8 support is integrated throughout Kohana and should always be supported. To achieve that while cutting out a lot of load time, the utf8 functions now moved to separate files that are only loaded when needed.

My benchmarks on the loading of utf8.php went from about 0.0072 to 0.0030 seconds.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/application/config/config.php

    r1250 r1269  
    1111 *  index_page           - name of the front controller, can be removed with URL rewriting 
    1212 *  url_suffix           - an extension that will be added to all generated URLs 
    13  *  enable_utf8          - enable or disable internal utf8 support 
    1413 *  global_xss_filtering - enable or disable XSS attack filtering on all user input 
    1514 *  allow_config_set     - enable or disable setting of Config items 
     
    2423        'index_page'           => 'index.php', 
    2524        'url_suffix'           => '', 
    26         'enable_utf8'          => TRUE, 
    2725        'global_xss_filtering' => FALSE, 
    2826        'allow_config_set'     => FALSE, 
  • trunk/system/core/Bootstrap.php

    r1250 r1269  
    1919 
    2020Benchmark::start(SYSTEM_BENCHMARK.'_kohana_loading'); 
     21require SYSPATH.'core/utf8'.EXT; 
    2122require SYSPATH.'core/Config'.EXT; 
    2223require SYSPATH.'core/Log'.EXT; 
  • trunk/system/core/Kohana.php

    r1266 r1269  
    114114                // magic_quotes_gpc later. 
    115115                set_magic_quotes_runtime(0); 
    116  
    117                 // Only include utf8 support if it's enabled 
    118                 Config::item('core.enable_utf8') and require SYSPATH.'core/utf8'.EXT; 
    119116 
    120117                // Send default text/html UTF-8 header 
  • trunk/system/core/utf8.php

    r1230 r1269  
    181181        public static function transliterate_to_ascii($str, $case = 0) 
    182182        { 
    183                 static $UTF8_LOWER_ACCENTS = NULL; 
    184                 static $UTF8_UPPER_ACCENTS = NULL; 
    185  
    186                 if ($case <= 0) 
    187                 { 
    188                         if ($UTF8_LOWER_ACCENTS === NULL) 
    189                         { 
    190                                 $UTF8_LOWER_ACCENTS = array( 
    191                                         'à' => 'a',  'ÃŽ' => 'o',  'ď' => 'd',  'ᾟ' => 'f',  'ë' => 'e',  'Å¡' => 's',  'Æ¡' => 'o', 
    192                                         'ß' => 'ss', 'ă' => 'a',  'ř' => 'r',  'ț' => 't',  'ň' => 'n',  'ā' => 'a',  'Ä·' => 'k', 
    193                                         'ŝ' => 's',  'ỳ' => 'y',  'ņ' => 'n',  'ĺ' => 'l',  'ħ' => 'h',  'ṗ' => 'p',  'ó' => 'o', 
    194                                         'ú' => 'u',  'ě' => 'e',  'é' => 'e',  'ç' => 'c',  'ẁ' => 'w',  'ċ' => 'c',  'õ' => 'o', 
    195                                         'ṡ' => 's',  'Þ' => 'o',  'Ä£' => 'g',  'ŧ' => 't',  'ș' => 's',  'ė' => 'e',  'ĉ' => 'c', 
    196                                         'ś' => 's',  'î' => 'i',  'ű' => 'u',  'ć' => 'c',  'ę' => 'e',  'ŵ' => 'w',  'ṫ' => 't', 
    197                                         'Å«' => 'u',  'č' => 'c',  'ö' => 'o',  'Ú' => 'e',  'Å·' => 'y',  'Ä 
    198 ' => 'a',  'ł' => 'l', 
    199                                         'ų' => 'u',  'ů' => 'u',  'ş' => 's',  'ğ' => 'g',  'ÄŒ' => 'l',  'ƒ' => 'f',  'ÅŸ' => 'z', 
    200                                         'ẃ' => 'w',  'ឃ' => 'b',  'Ã¥' => 'a',  'ì' => 'i',  'ï' => 'i',  'ᾋ' => 'd',  'Å¥' => 't', 
    201                                         'ŗ' => 'r',  'À' => 'a',  'í' => 'i',  'ŕ' => 'r',  'ê' => 'e',  'ÃŒ' => 'u',  'ò' => 'o', 
    202                                         'ē' => 'e',  'ñ' => 'n',  'ń' => 'n',  'Ä¥' => 'h',  'ĝ' => 'g',  'đ' => 'd',  'ĵ' => 'j', 
    203                                         'ÿ' => 'y',  'Å©' => 'u',  'Å­' => 'u',  'ư' => 'u',  'Å£' => 't',  'Ü' => 'y',  'ő' => 'o', 
    204                                         'â' => 'a',  'ÄŸ' => 'l',  'Ạ
    205 ' => 'w',  'ÅŒ' => 'z',  'Ä«' => 'i',  'ã' => 'a',  'Ä¡' => 'g', 
    206                                         'ṁ' => 'm',  'ō' => 'o',  'Ä©' => 'i',  'ù' => 'u',  'į' => 'i',  'ź' => 'z',  'á' => 'a', 
    207                                         'û' => 'u',  'ß' => 'th', 'ð' => 'dh', 'Ê' => 'ae', 'µ' => 'u',  'ĕ' => 'e', 
    208                                 ); 
    209                         } 
    210  
    211                         $str = str_replace( 
    212                                 array_keys($UTF8_LOWER_ACCENTS), 
    213                                 array_values($UTF8_LOWER_ACCENTS), 
    214                                 $str 
    215                         ); 
    216                 } 
    217  
    218                 if ($case >= 0) 
    219                 { 
    220                         if ($UTF8_UPPER_ACCENTS === NULL) 
    221                         { 
    222                                 $UTF8_UPPER_ACCENTS = array( 
    223                                         'À' => 'A',  'Ô' => 'O',  'Ď' => 'D',  'ᾞ' => 'F',  'Ë' => 'E',  'Å ' => 'S',  'Æ ' => 'O', 
    224                                         'Ă' => 'A',  'Ř' => 'R',  'Ț' => 'T',  'Ň' => 'N',  'Ā' => 'A',  'Ķ' => 'K',  'Ĕ' => 'E', 
    225                                         'Ŝ' => 'S',  'Ỳ' => 'Y',  'Å 
    226 ' => 'N',  'Ĺ' => 'L',  'ÄŠ' => 'H',  'Ṗ' => 'P',  'Ó' => 'O', 
    227                                         'Ú' => 'U',  'Ě' => 'E',  'É' => 'E',  'Ç' => 'C',  'Ẁ' => 'W',  'Ċ' => 'C',  'Õ' => 'O', 
    228                                         'á¹ ' => 'S',  'Ø' => 'O',  'Ä¢' => 'G',  'ÅŠ' => 'T',  'Ș' => 'S',  'Ė' => 'E',  'Ĉ' => 'C', 
    229                                         'Ś' => 'S',  'Î' => 'I',  'Ű' => 'U',  'Ć' => 'C',  'Ę' => 'E',  'ÅŽ' => 'W',  'Ṫ' => 'T', 
    230                                         'Ū' => 'U',  'Č' => 'C',  'Ö' => 'O',  'È' => 'E',  'Ŷ' => 'Y',  'Ą' => 'A',  'Ł' => 'L', 
    231                                         'Ų' => 'U',  'Å®' => 'U',  'Ş' => 'S',  'Ğ' => 'G',  'Ä»' => 'L',  'Ƒ' => 'F',  'Åœ' => 'Z', 
    232                                         'Ẃ' => 'W',  'ᾂ' => 'B',  'à
    233 ' => 'A',  'Ì' => 'I',  'Ï' => 'I',  'ᾊ' => 'D',  'Å€' => 'T', 
    234                                         'Ŗ' => 'R',  'Ä' => 'A',  'Í' => 'I',  'Ŕ' => 'R',  'Ê' => 'E',  'Ü' => 'U',  'Ò' => 'O', 
    235                                         'Ē' => 'E',  'Ñ' => 'N',  'Ń' => 'N',  'Ä€' => 'H',  'Ĝ' => 'G',  'Đ' => 'D',  'ÄŽ' => 'J', 
    236                                         'Åž' => 'Y',  'Åš' => 'U',  'Ŭ' => 'U',  'Ư' => 'U',  'Å¢' => 'T',  'Ý' => 'Y',  'Ő' => 'O', 
    237                                         'Â' => 'A',  'Äœ' => 'L',  'Ẅ' => 'W',  'Å»' => 'Z',  'Ī' => 'I',  'Ã' => 'A',  'Ä ' => 'G', 
    238                                         'Ṁ' => 'M',  'Ō' => 'O',  'Äš' => 'I',  'Ù' => 'U',  'Ä®' => 'I',  'Ź' => 'Z',  'Á' => 'A', 
    239                                         'Û' => 'U',  'Þ' => 'Th', 'Ð' => 'Dh', 'Æ' => 'Ae', 
    240                                 ); 
    241                         } 
    242  
    243                         $str = str_replace( 
    244                                 array_keys($UTF8_UPPER_ACCENTS), 
    245                                 array_values($UTF8_UPPER_ACCENTS), 
    246                                 $str 
    247                         ); 
    248                 } 
    249  
    250                 return $str; 
     183                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     184                return _transliterate_to_ascii($str, $case); 
    251185        } 
    252186 
     
    263197        public static function strlen($str) 
    264198        { 
    265                 // Try mb_strlen() first because it's faster than combination of is_ascii() and strlen() 
    266                 if (SERVER_UTF8) 
    267                 { 
    268                         return mb_strlen($str); 
    269                 } 
    270                 if (self::is_ascii($str)) 
    271                 { 
    272                         return strlen($str); 
    273                 } 
    274  
    275                 return strlen(utf8_decode($str)); 
     199                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     200                return _strlen($str); 
    276201        } 
    277202 
     
    291216        public static function strpos($str, $search, $offset = 0) 
    292217        { 
    293                 $offset = (int) $offset; 
    294  
    295                 if (SERVER_UTF8) 
    296                 { 
    297                         return mb_strpos($str, $search, $offset); 
    298                 } 
    299                 if (self::is_ascii($str) AND self::is_ascii($search)) 
    300                 { 
    301                         return strpos($str, $search, $offset); 
    302                 } 
    303  
    304                 if ($offset == 0) 
    305                 { 
    306                         $array = explode($search, $str, 2); 
    307                         return (isset($array[1])) ? self::strlen($array[0]) : FALSE; 
    308                 } 
    309  
    310                 $str = self::substr($str, $offset); 
    311                 $pos = self::strpos($str, $search); 
    312                 return ($pos === FALSE) ? FALSE : $pos + $offset; 
     218                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     219                return _strpos($str, $search, $offset); 
    313220        } 
    314221 
     
    328235        public static function strrpos($str, $search, $offset = 0) 
    329236        { 
    330                 $offset = (int) $offset; 
    331  
    332                 if (SERVER_UTF8) 
    333                 { 
    334                         return mb_strrpos($str, $search, $offset); 
    335                 } 
    336                 if (self::is_ascii($str) AND self::is_ascii($search)) 
    337                 { 
    338                         return strrpos($str, $search, $offset); 
    339                 } 
    340  
    341                 if ($offset == 0) 
    342                 { 
    343                         $array = explode($search, $str, -1); 
    344                         return (isset($array[0])) ? self::strlen(implode($search, $array)) : FALSE; 
    345                 } 
    346  
    347                 $str = self::substr($str, $offset); 
    348                 $pos = self::strrpos($str, $search); 
    349                 return ($pos === FALSE) ? FALSE : $pos + $offset; 
     237                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     238                return _strrpos($str, $search, $offset); 
    350239        } 
    351240 
     
    365254        public static function substr($str, $offset, $length = NULL) 
    366255        { 
    367                 if (SERVER_UTF8) 
    368                 { 
    369                         return ($length === NULL) ? mb_substr($str, $offset) : mb_substr($str, $offset, $length); 
    370                 } 
    371                 if (self::is_ascii($str)) 
    372                 { 
    373                         return ($length === NULL) ? substr($str, $offset) : substr($str, $offset, $length); 
    374                 } 
    375  
    376                 // Normalize params 
    377                 $str    = (string) $str; 
    378                 $strlen = self::strlen($str); 
    379                 $offset = (int) ($offset < 0) ? max(0, $strlen + $offset) : $offset; // Normalize to positive offset 
    380                 $length = ($length === NULL) ? NULL : (int) $length; 
    381  
    382                 // Impossible 
    383                 if ($length === 0 OR $offset >= $strlen OR ($length < 0 AND $length <= $offset - $strlen)) 
    384                 { 
    385                         return ''; 
    386                 } 
    387  
    388                 // Whole string 
    389                 if ($offset == 0 AND ($length === NULL OR $length >= $strlen)) 
    390                 { 
    391                         return $str; 
    392                 } 
    393  
    394                 // Build regex 
    395                 $regex = '^'; 
    396  
    397                 // Create an offset expression 
    398                 if ($offset > 0) 
    399                 { 
    400                         // PCRE repeating quantifiers must be less than 65536, so repeat when necessary 
    401                         $x = (int) ($offset / 65535); 
    402                         $y = (int) ($offset % 65535); 
    403                         $regex .= ($x == 0) ? '' : '(?:.{65535}){'.$x.'}'; 
    404                         $regex .= ($y == 0) ? '' : '.{'.$y.'}'; 
    405                 } 
    406  
    407                 // Create a length expression 
    408                 if ($length === NULL) 
    409                 { 
    410                         $regex .= '(.*)'; // No length set, grab it all 
    411                 } 
    412                 else 
    413                 { 
    414                         // Find length from the left (positive length) 
    415                         if ($length > 0) 
    416                         { 
    417                                 // Reduce length so that it can't go beyond the end of the string 
    418                                 $length = min($strlen - $offset, $length); 
    419  
    420                                 $x = (int) ($length / 65535); 
    421                                 $y = (int) ($length % 65535); 
    422                                 $regex .= '('; 
    423                                 $regex .= ($x == 0) ? '' : '(?:.{65535}){'.$x.'}'; 
    424                                 $regex .= '.{'.$y.'})'; 
    425                         } 
    426                         // Find length from the right (negative length) 
    427                         else 
    428                         { 
    429                                 $x = (int) (-$length / 65535); 
    430                                 $y = (int) (-$length % 65535); 
    431                                 $regex .= '(.*)'; 
    432                                 $regex .= ($x == 0) ? '' : '(?:.{65535}){'.$x.'}'; 
    433                                 $regex .= '.{'.$y.'}'; 
    434                         } 
    435                 } 
    436  
    437                 preg_match('/'.$regex.'/us', $str, $matches); 
    438                 return $matches[1]; 
     256                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     257                return _substr($str, $offset, $length); 
    439258        } 
    440259 
     
    455274        public static function substr_replace($str, $replacement, $offset, $length = NULL) 
    456275        { 
    457                 if (self::is_ascii($str)) 
    458                 { 
    459                         return ($length === NULL) ? substr_replace($str, $replacement, $offset) : substr_replace($str, $replacement, $offset, $length); 
    460                 } 
    461  
    462                 $length = ($length === NULL) ? self::strlen($str) : (int) $length; 
    463                 preg_match_all('/./us', $str, $str_array); 
    464                 preg_match_all('/./us', $replacement, $replacement_array); 
    465  
    466                 array_splice($str_array[0], $offset, $length, $replacement_array[0]); 
    467                 return implode('', $str_array[0]); 
     276                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     277                return _substr_replace($str, $replacement, $offset, $length); 
    468278        } 
    469279 
     
    481291        public static function strtolower($str) 
    482292        { 
    483                 if (SERVER_UTF8) 
    484                 { 
    485                         return mb_strtolower($str); 
    486                 } 
    487                 if (self::is_ascii($str)) 
    488                 { 
    489                         return strtolower($str); 
    490                 } 
    491  
    492                 static $UTF8_UPPER_TO_LOWER = NULL; 
    493  
    494                 if ($UTF8_UPPER_TO_LOWER === NULL) 
    495                 { 
    496                         $UTF8_UPPER_TO_LOWER = array( 
    497                                 0x0041=>0x0061, 0x03A6=>0x03C6, 0x0162=>0x0163, 0x00C5=>0x00E5, 0x0042=>0x0062, 
    498                                 0x0139=>0x013A, 0x00C1=>0x00E1, 0x0141=>0x0142, 0x038E=>0x03CD, 0x0100=>0x0101, 
    499                                 0x0490=>0x0491, 0x0394=>0x03B4, 0x015A=>0x015B, 0x0044=>0x0064, 0x0393=>0x03B3, 
    500                                 0x00D4=>0x00F4, 0x042A=>0x044A, 0x0419=>0x0439, 0x0112=>0x0113, 0x041C=>0x043C, 
    501                                 0x015E=>0x015F, 0x0143=>0x0144, 0x00CE=>0x00EE, 0x040E=>0x045E, 0x042F=>0x044F, 
    502                                 0x039A=>0x03BA, 0x0154=>0x0155, 0x0049=>0x0069, 0x0053=>0x0073, 0x1E1E=>0x1E1F, 
    503                                 0x0134=>0x0135, 0x0427=>0x0447, 0x03A0=>0x03C0, 0x0418=>0x0438, 0x00D3=>0x00F3, 
    504                                 0x0420=>0x0440, 0x0404=>0x0454, 0x0415=>0x0435, 0x0429=>0x0449, 0x014A=>0x014B, 
    505                                 0x0411=>0x0431, 0x0409=>0x0459, 0x1E02=>0x1E03, 0x00D6=>0x00F6, 0x00D9=>0x00F9, 
    506                                 0x004E=>0x006E, 0x0401=>0x0451, 0x03A4=>0x03C4, 0x0423=>0x0443, 0x015C=>0x015D, 
    507                                 0x0403=>0x0453, 0x03A8=>0x03C8, 0x0158=>0x0159, 0x0047=>0x0067, 0x00C4=>0x00E4, 
    508                                 0x0386=>0x03AC, 0x0389=>0x03AE, 0x0166=>0x0167, 0x039E=>0x03BE, 0x0164=>0x0165, 
    509                                 0x0116=>0x0117, 0x0108=>0x0109, 0x0056=>0x0076, 0x00DE=>0x00FE, 0x0156=>0x0157, 
    510                                 0x00DA=>0x00FA, 0x1E60=>0x1E61, 0x1E82=>0x1E83, 0x00C2=>0x00E2, 0x0118=>0x0119, 
    511                                 0x0145=>0x0146, 0x0050=>0x0070, 0x0150=>0x0151, 0x042E=>0x044E, 0x0128=>0x0129, 
    512                                 0x03A7=>0x03C7, 0x013D=>0x013E, 0x0422=>0x0442, 0x005A=>0x007A, 0x0428=>0x0448, 
    513                                 0x03A1=>0x03C1, 0x1E80=>0x1E81, 0x016C=>0x016D, 0x00D5=>0x00F5, 0x0055=>0x0075, 
    514                                 0x0176=>0x0177, 0x00DC=>0x00FC, 0x1E56=>0x1E57, 0x03A3=>0x03C3, 0x041A=>0x043A, 
    515                                 0x004D=>0x006D, 0x016A=>0x016B, 0x0170=>0x0171, 0x0424=>0x0444, 0x00CC=>0x00EC, 
    516                                 0x0168=>0x0169, 0x039F=>0x03BF, 0x004B=>0x006B, 0x00D2=>0x00F2, 0x00C0=>0x00E0, 
    517                                 0x0414=>0x0434, 0x03A9=>0x03C9, 0x1E6A=>0x1E6B, 0x00C3=>0x00E3, 0x042D=>0x044D, 
    518                                 0x0416=>0x0436, 0x01A0=>0x01A1, 0x010C=>0x010D, 0x011C=>0x011D, 0x00D0=>0x00F0, 
    519                                 0x013B=>0x013C, 0x040F=>0x045F, 0x040A=>0x045A, 0x00C8=>0x00E8, 0x03A5=>0x03C5, 
    520                                 0x0046=>0x0066, 0x00DD=>0x00FD, 0x0043=>0x0063, 0x021A=>0x021B, 0x00CA=>0x00EA, 
    521                                 0x0399=>0x03B9, 0x0179=>0x017A, 0x00CF=>0x00EF, 0x01AF=>0x01B0, 0x0045=>0x0065, 
    522                                 0x039B=>0x03BB, 0x0398=>0x03B8, 0x039C=>0x03BC, 0x040C=>0x045C, 0x041F=>0x043F, 
    523                                 0x042C=>0x044C, 0x00DE=>0x00FE, 0x00D0=>0x00F0, 0x1EF2=>0x1EF3, 0x0048=>0x0068, 
    524                                 0x00CB=>0x00EB, 0x0110=>0x0111, 0x0413=>0x0433, 0x012E=>0x012F, 0x00C6=>0x00E6, 
    525                                 0x0058=>0x0078, 0x0160=>0x0161, 0x016E=>0x016F, 0x0391=>0x03B1, 0x0407=>0x0457, 
    526                                 0x0172=>0x0173, 0x0178=>0x00FF, 0x004F=>0x006F, 0x041B=>0x043B, 0x0395=>0x03B5, 
    527                                 0x0425=>0x0445, 0x0120=>0x0121, 0x017D=>0x017E, 0x017B=>0x017C, 0x0396=>0x03B6, 
    528                                 0x0392=>0x03B2, 0x0388=>0x03AD, 0x1E84=>0x1E85, 0x0174=>0x0175, 0x0051=>0x0071, 
    529                                 0x0417=>0x0437, 0x1E0A=>0x1E0B, 0x0147=>0x0148, 0x0104=>0x0105, 0x0408=>0x0458, 
    530                                 0x014C=>0x014D, 0x00CD=>0x00ED, 0x0059=>0x0079, 0x010A=>0x010B, 0x038F=>0x03CE, 
    531                                 0x0052=>0x0072, 0x0410=>0x0430, 0x0405=>0x0455, 0x0402=>0x0452, 0x0126=>0x0127, 
    532                                 0x0136=>0x0137, 0x012A=>0x012B, 0x038A=>0x03AF, 0x042B=>0x044B, 0x004C=>0x006C, 
    533                                 0x0397=>0x03B7, 0x0124=>0x0125, 0x0218=>0x0219, 0x00DB=>0x00FB, 0x011E=>0x011F, 
    534                                 0x041E=>0x043E, 0x1E40=>0x1E41, 0x039D=>0x03BD, 0x0106=>0x0107, 0x03AB=>0x03CB, 
    535                                 0x0426=>0x0446, 0x00DE=>0x00FE, 0x00C7=>0x00E7, 0x03AA=>0x03CA, 0x0421=>0x0441, 
    536                                 0x0412=>0x0432, 0x010E=>0x010F, 0x00D8=>0x00F8, 0x0057=>0x0077, 0x011A=>0x011B, 
    537                                 0x0054=>0x0074, 0x004A=>0x006A, 0x040B=>0x045B, 0x0406=>0x0456, 0x0102=>0x0103, 
    538                                 0x039B=>0x03BB, 0x00D1=>0x00F1, 0x041D=>0x043D, 0x038C=>0x03CC, 0x00C9=>0x00E9, 
    539                                 0x00D0=>0x00F0, 0x0407=>0x0457, 0x0122=>0x0123, 
    540                         ); 
    541                 } 
    542  
    543                 $uni = self::to_unicode($str); 
    544  
    545                 if ($uni === FALSE) 
    546                 { 
    547                         return FALSE; 
    548                 } 
    549  
    550                 for ($i = 0, $c = count($uni); $i < $c; $i++) 
    551                 { 
    552                         if (isset($UTF8_UPPER_TO_LOWER[$uni[$i]])) 
    553                         { 
    554                                 $uni[$i] = $UTF8_UPPER_TO_LOWER[$uni[$i]]; 
    555                         } 
    556                 } 
    557  
    558                 return self::from_unicode($uni); 
     293                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     294                return _strtolower($str); 
    559295        } 
    560296 
     
    572308        public static function strtoupper($str) 
    573309        { 
    574                 if (SERVER_UTF8) 
    575                 { 
    576                         return mb_strtoupper($str); 
    577                 } 
    578                 if (self::is_ascii($str)) 
    579                 { 
    580                         return strtoupper($str); 
    581                 } 
    582  
    583                 static $UTF8_LOWER_TO_UPPER = NULL; 
    584  
    585                 if ($UTF8_LOWER_TO_UPPER === NULL) 
    586                 { 
    587                         $UTF8_LOWER_TO_UPPER = array( 
    588                                 0x0061=>0x0041, 0x03C6=>0x03A6, 0x0163=>0x0162, 0x00E5=>0x00C5, 0x0062=>0x0042, 
    589                                 0x013A=>0x0139, 0x00E1=>0x00C1, 0x0142=>0x0141, 0x03CD=>0x038E, 0x0101=>0x0100, 
    590                                 0x0491=>0x0490, 0x03B4=>0x0394, 0x015B=>0x015A, 0x0064=>0x0044, 0x03B3=>0x0393, 
    591                                 0x00F4=>0x00D4, 0x044A=>0x042A, 0x0439=>0x0419, 0x0113=>0x0112, 0x043C=>0x041C, 
    592                                 0x015F=>0x015E, 0x0144=>0x0143, 0x00EE=>0x00CE, 0x045E=>0x040E, 0x044F=>0x042F, 
    593                                 0x03BA=>0x039A, 0x0155=>0x0154, 0x0069=>0x0049, 0x0073=>0x0053, 0x1E1F=>0x1E1E, 
    594                                 0x0135=>0x0134, 0x0447=>0x0427, 0x03C0=>0x03A0, 0x0438=>0x0418, 0x00F3=>0x00D3, 
    595                                 0x0440=>0x0420, 0x0454=>0x0404, 0x0435=>0x0415, 0x0449=>0x0429, 0x014B=>0x014A, 
    596                                 0x0431=>0x0411, 0x0459=>0x0409, 0x1E03=>0x1E02, 0x00F6=>0x00D6, 0x00F9=>0x00D9, 
    597                                 0x006E=>0x004E, 0x0451=>0x0401, 0x03C4=>0x03A4, 0x0443=>0x0423, 0x015D=>0x015C, 
    598                                 0x0453=>0x0403, 0x03C8=>0x03A8, 0x0159=>0x0158, 0x0067=>0x0047, 0x00E4=>0x00C4, 
    599                                 0x03AC=>0x0386, 0x03AE=>0x0389, 0x0167=>0x0166, 0x03BE=>0x039E, 0x0165=>0x0164, 
    600                                 0x0117=>0x0116, 0x0109=>0x0108, 0x0076=>0x0056, 0x00FE=>0x00DE, 0x0157=>0x0156, 
    601                                 0x00FA=>0x00DA, 0x1E61=>0x1E60, 0x1E83=>0x1E82, 0x00E2=>0x00C2, 0x0119=>0x0118, 
    602                                 0x0146=>0x0145, 0x0070=>0x0050, 0x0151=>0x0150, 0x044E=>0x042E, 0x0129=>0x0128, 
    603                                 0x03C7=>0x03A7, 0x013E=>0x013D, 0x0442=>0x0422, 0x007A=>0x005A, 0x0448=>0x0428, 
    604                                 0x03C1=>0x03A1, 0x1E81=>0x1E80, 0x016D=>0x016C, 0x00F5=>0x00D5, 0x0075=>0x0055, 
    605                                 0x0177=>0x0176, 0x00FC=>0x00DC, 0x1E57=>0x1E56, 0x03C3=>0x03A3, 0x043A=>0x041A, 
    606                                 0x006D=>0x004D, 0x016B=>0x016A, 0x0171=>0x0170, 0x0444=>0x0424, 0x00EC=>0x00CC, 
    607                                 0x0169=>0x0168, 0x03BF=>0x039F, 0x006B=>0x004B, 0x00F2=>0x00D2, 0x00E0=>0x00C0, 
    608                                 0x0434=>0x0414, 0x03C9=>0x03A9, 0x1E6B=>0x1E6A, 0x00E3=>0x00C3, 0x044D=>0x042D, 
    609                                 0x0436=>0x0416, 0x01A1=>0x01A0, 0x010D=>0x010C, 0x011D=>0x011C, 0x00F0=>0x00D0, 
    610                                 0x013C=>0x013B, 0x045F=>0x040F, 0x045A=>0x040A, 0x00E8=>0x00C8, 0x03C5=>0x03A5, 
    611                                 0x0066=>0x0046, 0x00FD=>0x00DD, 0x0063=>0x0043, 0x021B=>0x021A, 0x00EA=>0x00CA, 
    612                                 0x03B9=>0x0399, 0x017A=>0x0179, 0x00EF=>0x00CF, 0x01B0=>0x01AF, 0x0065=>0x0045, 
    613                                 0x03BB=>0x039B, 0x03B8=>0x0398, 0x03BC=>0x039C, 0x045C=>0x040C, 0x043F=>0x041F, 
    614                                 0x044C=>0x042C, 0x00FE=>0x00DE, 0x00F0=>0x00D0, 0x1EF3=>0x1EF2, 0x0068=>0x0048, 
    615                                 0x00EB=>0x00CB, 0x0111=>0x0110, 0x0433=>0x0413, 0x012F=>0x012E, 0x00E6=>0x00C6, 
    616                                 0x0078=>0x0058, 0x0161=>0x0160, 0x016F=>0x016E, 0x03B1=>0x0391, 0x0457=>0x0407, 
    617                                 0x0173=>0x0172, 0x00FF=>0x0178, 0x006F=>0x004F, 0x043B=>0x041B, 0x03B5=>0x0395, 
    618                                 0x0445=>0x0425, 0x0121=>0x0120, 0x017E=>0x017D, 0x017C=>0x017B, 0x03B6=>0x0396, 
    619                                 0x03B2=>0x0392, 0x03AD=>0x0388, 0x1E85=>0x1E84, 0x0175=>0x0174, 0x0071=>0x0051, 
    620                                 0x0437=>0x0417, 0x1E0B=>0x1E0A, 0x0148=>0x0147, 0x0105=>0x0104, 0x0458=>0x0408, 
    621                                 0x014D=>0x014C, 0x00ED=>0x00CD, 0x0079=>0x0059, 0x010B=>0x010A, 0x03CE=>0x038F, 
    622                                 0x0072=>0x0052, 0x0430=>0x0410, 0x0455=>0x0405, 0x0452=>0x0402, 0x0127=>0x0126, 
    623                                 0x0137=>0x0136, 0x012B=>0x012A, 0x03AF=>0x038A, 0x044B=>0x042B, 0x006C=>0x004C, 
    624                                 0x03B7=>0x0397, 0x0125=>0x0124, 0x0219=>0x0218, 0x00FB=>0x00DB, 0x011F=>0x011E, 
    625                                 0x043E=>0x041E, 0x1E41=>0x1E40, 0x03BD=>0x039D, 0x0107=>0x0106, 0x03CB=>0x03AB, 
    626                                 0x0446=>0x0426, 0x00FE=>0x00DE, 0x00E7=>0x00C7, 0x03CA=>0x03AA, 0x0441=>0x0421, 
    627                                 0x0432=>0x0412, 0x010F=>0x010E, 0x00F8=>0x00D8, 0x0077=>0x0057, 0x011B=>0x011A, 
    628                                 0x0074=>0x0054, 0x006A=>0x004A, 0x045B=>0x040B, 0x0456=>0x0406, 0x0103=>0x0102, 
    629                                 0x03BB=>0x039B, 0x00F1=>0x00D1, 0x043D=>0x041D, 0x03CC=>0x038C, 0x00E9=>0x00C9, 
    630                                 0x00F0=>0x00D0, 0x0457=>0x0407, 0x0123=>0x0122, 
    631                         ); 
    632                 } 
    633  
    634                 $uni = self::to_unicode($str); 
    635  
    636                 if ($uni === FALSE) 
    637                 { 
    638                         return FALSE; 
    639                 } 
    640  
    641                 for ($i = 0, $c = count($uni); $i < $c; $i++) 
    642                 { 
    643                         if (isset($UTF8_LOWER_TO_UPPER[$uni[$i]])) 
    644                         { 
    645                                 $uni[$i] = $UTF8_LOWER_TO_UPPER[$uni[$i]]; 
    646                         } 
    647                 } 
    648  
    649                 return self::from_unicode($uni); 
     310                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     311                return _strtoupper($str); 
    650312        } 
    651313 
     
    663325        public static function ucfirst($str) 
    664326        { 
    665                 if (self::is_ascii($str)) 
    666                 { 
    667                         return ucfirst($str); 
    668                 } 
    669  
    670                 preg_match('/^(.?)(.*)$/us', $str, $matches); 
    671                 return self::strtoupper($matches[1]).$matches[2]; 
     327                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     328                return _ucfirst($str); 
    672329        } 
    673330 
     
    685342        public static function ucwords($str) 
    686343        { 
    687                 if (SERVER_UTF8) 
    688                 { 
    689                         return mb_convert_case($str, MB_CASE_TITLE); 
    690                 } 
    691                 if (self::is_ascii($str)) 
    692                 { 
    693                         return ucwords($str); 
    694                 } 
    695  
    696                 // [\x0c\x09\x0b\x0a\x0d\x20] matches form feeds, horizontal tabs, vertical tabs, linefeeds and carriage returns. 
    697                 // This corresponds to the definition of a 'word' defined at http://php.net/ucwords 
    698                 return preg_replace( 
    699                         '/(?<=^|[\x0c\x09\x0b\x0a\x0d\x20])[^\x0c\x09\x0b\x0a\x0d\x20]/ue', 
    700                         'self::strtoupper(\'$0\')', 
    701                         $str 
    702                 ); 
     344                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     345                return _ucwords($str); 
    703346        } 
    704347 
     
    717360        public static function strcasecmp($str1, $str2) 
    718361        { 
    719                 if (self::is_ascii($str1) AND self::is_ascii($str2)) 
    720                 { 
    721                         return strcasecmp($str1, $str2); 
    722                 } 
    723  
    724                 $str1 = self::strtolower($str1); 
    725                 $str2 = self::strtolower($str2); 
    726                 return strcmp($str1, $str2); 
     362                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     363                return _strcasecmp($str1, $str2); 
    727364        } 
    728365 
     
    745382        public static function str_ireplace($search, $replace, $str, & $count = NULL) 
    746383        { 
    747                 if (self::is_ascii($search) AND self::is_ascii($replace) AND self::is_ascii($str)) 
    748                 { 
    749                         return str_ireplace($search, $replace, $str, $count); 
    750                 } 
    751  
    752                 if (is_array($str)) 
    753                 { 
    754                         foreach ($str as $key => $val) 
    755                         { 
    756                                 $str[$key] = self::str_ireplace($search, $replace, $val, $count); 
    757                         } 
    758                         return $str; 
    759                 } 
    760  
    761                 if (is_array($search)) 
    762                 { 
    763                         foreach (array_keys($search) as $k) 
    764                         { 
    765                                 if (is_array($replace)) 
    766                                 { 
    767                                         if (array_key_exists($k, $replace)) 
    768                                         { 
    769                                                 $str = self::str_ireplace($search[$k], $replace[$k], $str, $count); 
    770                                         } 
    771                                         else 
    772                                         { 
    773                                                 $str = self::str_ireplace($search[$k], '', $str, $count); 
    774                                         } 
    775                                 } 
    776                                 else 
    777                                 { 
    778                                         $str = self::str_ireplace($search[$k], $replace, $str, $count); 
    779                                 } 
    780                         } 
    781                         return $str; 
    782                 } 
    783  
    784                 $search = self::strtolower($search); 
    785                 $str_lower = self::strtolower($str); 
    786  
    787                 $total_matched_strlen = 0; 
    788                 $i = 0; 
    789  
    790                 while (preg_match('/(.*?)'.preg_quote($search, '/').'/s', $str_lower, $matches)) 
    791                 { 
    792                         $matched_strlen = strlen($matches[0]); 
    793                         $str_lower = substr($str_lower, $matched_strlen); 
    794  
    795                         $offset = $total_matched_strlen + strlen($matches[1]) + ($i * (strlen($replace) - 1)); 
    796                         $str = substr_replace($str, $replace, $offset, strlen($search)); 
    797  
    798                         $total_matched_strlen += $matched_strlen; 
    799                         $i++; 
    800                 } 
    801  
    802                 $count += $i; 
    803                 return $str; 
     384                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     385                return _str_ireplace($search, $replace, $str, $count); 
    804386        } 
    805387 
     
    819401        public static function stristr($str, $search) 
    820402        { 
    821                 if (self::is_ascii($str) AND self::is_ascii($search)) 
    822                 { 
    823                         return stristr($str, $search); 
    824                 } 
    825  
    826                 if ($search == '') 
    827                 { 
    828                         return $str; 
    829                 } 
    830  
    831                 $str_lower = self::strtolower($str); 
    832                 $search_lower = self::strtolower($search); 
    833  
    834                 preg_match('/^(.*?)'.preg_quote($search, '/').'/s', $str_lower, $matches); 
    835  
    836                 if (isset($matches[1])) 
    837                 { 
    838                         return substr($str, strlen($matches[1])); 
    839                 } 
    840  
    841                 return FALSE; 
     403                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     404                return _stristr($str, $search); 
    842405        } 
    843406 
     
    859422        public static function strspn($str, $mask, $offset = NULL, $length = NULL) 
    860423        { 
    861                 if ($str == '' OR $mask == '') 
    862                 { 
    863                         return 0; 
    864                 } 
    865  
    866                 if (self::is_ascii($str) AND self::is_ascii($mask)) 
    867                 { 
    868                         return ($offset === NULL) ? strspn($str, $mask) : (($length === NULL) ? strspn($str, $mask, $offset) : strspn($str, $mask, $offset, $length)); 
    869                 } 
    870  
    871                 if ($offset !== NULL OR $length !== NULL) 
    872                 { 
    873                         $str = self::substr($str, $offset, $length); 
    874                 } 
    875  
    876                 // Escape these characters:  - [ ] . : \ ^ / 
    877                 // The . and : are escaped to prevent possible warnings about POSIX regex elements 
    878                 $mask = preg_replace('#[-[\].:\\\\^/]#', '\\\\$0', $mask); 
    879                 preg_match('/^[^'.$mask.']+/u', $str, $matches); 
    880  
    881                 return (isset($matches[0])) ? self::strlen($matches[0]) : 0; 
     424                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     425                return _strspn($str, $mask, $offset, $length); 
    882426        } 
    883427 
     
    899443        public static function strcspn($str, $mask, $offset = NULL, $length = NULL) 
    900444        { 
    901                 if ($str == '' OR $mask == '') 
    902                 { 
    903                         return 0; 
    904                 } 
    905  
    906                 if (self::is_ascii($str) AND self::is_ascii($mask)) 
    907                 { 
    908                         return ($offset === NULL) ? strcspn($str, $mask) : (($length === NULL) ? strcspn($str, $mask, $offset) : strcspn($str, $mask, $offset, $length)); 
    909                 } 
    910  
    911                 if ($start !== NULL OR $length !== NULL) 
    912                 { 
    913                         $str = self::substr($str, $offset, $length); 
    914                 } 
    915  
    916                 // Escape these characters:  - [ ] . : \ ^ / 
    917                 // The . and : are escaped to prevent possible warnings about POSIX regex elements 
    918                 $mask = preg_replace('#[-[\].:\\\\^/]#', '\\\\$0', $mask); 
    919                 preg_match('/^[^'.$mask.']+/u', $str, $matches); 
    920  
    921                 return (isset($matches[0])) ? self::strlen($matches[0]) : 0; 
     445                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
     446                return _strcspn($str, $mask, $offset, $length); 
    922447        } 
    923448 
     
    938463        public static function str_pad($str, $final_str_length, $pad_str = ' ', $pad_type = STR_PAD_RIGHT) 
    939464        { 
    940                 if (self::is_ascii($str) AND self::is_ascii($pad_str)) 
    941                 { 
    942                         return str_pad($str, $final_str_length, $pad_str, $pad_type); 
    943                 } 
    944  
    945                 $str_length = self::strlen($str); 
    946  
    947                 if ($final_str_length <= 0 OR $final_str_length <= $str_length) 
    948                 { 
    949                         return $str; 
    950                 } 
    951  
    952                 $pad_str_length = self::strlen($pad_str); 
    953                 $pad_length = $final_str_length - $str_length; 
    954  
    955                 if ($pad_type == STR_PAD_RIGHT) 
    956                 { 
    957                         $repeat = ceil($pad_length / $pad_str_length); 
    958                         return self::substr($str.str_repeat($pad_str, $repeat), 0, $final_str_length); 
    959                 } 
    960  
    961                 if ($pad_type == STR_PAD_LEFT) 
    962                 { 
    963                         $repeat = ceil($pad_length / $pad_str_length); 
    964                         return self::substr(str_repeat($pad_str, $repeat), 0, floor($pad_length)).$str; 
    965                 } 
    966  
    967                 if ($pad_type == STR_PAD_BOTH) 
    968                 { 
    969                         $pad_length /= 2; 
    970                         $pad_length_left = floor($pad_length); 
    971                         $pad_length_right = ceil($pad_length); 
    972                         $repeat_left = ceil($pad_length_left / $pad_str_length); 
    973                         $repeat_right = ceil($pad_length_right / $pad_str_length); 
    974  
    975                         $pad_left = self::substr(str_repeat($pad_str, $repeat_left), 0, $pad_length_left); 
    976                         $pad_right = self::substr(str_repeat($pad_str, $repeat_right), 0, $pad_length_left); 
    977                         return $pad_left.$str.$pad_right; 
    978                 } 
    979  
    980                 trigger_error('utf8::str_pad: Unknown padding type (' . $type . ')', E_USER_ERROR); 
     465                require_once SYSPATH.'core/utf8/'.__FUNCTION__.EXT; 
    &n