/**
  * Multibyte wrapper for strftime.
  *
  * Handles utf8_encoding the result of strftime when necessary.
  *
  * @param string $format Format string.
  * @param int $date Timestamp to format.
  * @return string formatted string with correct encoding.
  */
 protected function _strftime($format, $date)
 {
     $format = strftime($format, $date);
     $encoding = Configure::read('App.encoding');
     if (!empty($encoding) && $encoding === 'UTF-8') {
         if (function_exists('mb_check_encoding')) {
             $valid = mb_check_encoding($format, $encoding);
         } else {
             $valid = !Multibyte::checkMultibyte($format);
         }
         if (!$valid) {
             $format = utf8_encode($format);
         }
     }
     return $format;
 }
Example #2
0
 /**
  * Auxiliary function to parse a symbol from a locale definition file
  *
  * @param string $string Symbol to be parsed
  * @return string parsed symbol
  */
 protected function _parseLiteralValue($string)
 {
     $string = $string[1];
     if (substr($string, 0, 2) === $this->_escape . 'x') {
         $delimiter = $this->_escape . 'x';
         return join('', array_map('chr', array_map('hexdec', array_filter(explode($delimiter, $string)))));
     }
     if (substr($string, 0, 2) === $this->_escape . 'd') {
         $delimiter = $this->_escape . 'd';
         return join('', array_map('chr', array_filter(explode($delimiter, $string))));
     }
     if ($string[0] === $this->_escape && isset($string[1]) && is_numeric($string[1])) {
         $delimiter = $this->_escape;
         return join('', array_map('chr', array_filter(explode($delimiter, $string))));
     }
     if (substr($string, 0, 3) === 'U00') {
         $delimiter = 'U00';
         return join('', array_map('chr', array_map('hexdec', array_filter(explode($delimiter, $string)))));
     }
     if (preg_match('/U([0-9a-fA-F]{4})/', $string, $match)) {
         return Multibyte::ascii(array(hexdec($match[1])));
     }
     return $string;
 }
Example #3
0
 /**
  * Encode a string into JSON.  Converts and escapes necessary characters.
  *
  * @param string $string The string that needs to be utf8->hex encoded
  * @return void
  * @access protected
  */
 function _utf8ToHex($string)
 {
     $length = strlen($string);
     $return = '';
     for ($i = 0; $i < $length; ++$i) {
         $ord = ord($string[$i]);
         switch (true) {
             case $ord == 0x8:
                 $return .= '\\b';
                 break;
             case $ord == 0x9:
                 $return .= '\\t';
                 break;
             case $ord == 0xa:
                 $return .= '\\n';
                 break;
             case $ord == 0xc:
                 $return .= '\\f';
                 break;
             case $ord == 0xd:
                 $return .= '\\r';
                 break;
             case $ord == 0x22:
             case $ord == 0x2f:
             case $ord == 0x5c:
                 $return .= '\\' . $string[$i];
                 break;
             case $ord >= 0x20 && $ord <= 0x7f:
                 $return .= $string[$i];
                 break;
             case ($ord & 0xe0) == 0xc0:
                 if ($i + 1 >= $length) {
                     $i += 1;
                     $return .= '?';
                     break;
                 }
                 $charbits = $string[$i] . $string[$i + 1];
                 $char = Multibyte::utf8($charbits);
                 $return .= sprintf('\\u%04s', dechex($char[0]));
                 $i += 1;
                 break;
             case ($ord & 0xf0) == 0xe0:
                 if ($i + 2 >= $length) {
                     $i += 2;
                     $return .= '?';
                     break;
                 }
                 $charbits = $string[$i] . $string[$i + 1] . $string[$i + 2];
                 $char = Multibyte::utf8($charbits);
                 $return .= sprintf('\\u%04s', dechex($char[0]));
                 $i += 2;
                 break;
             case ($ord & 0xf8) == 0xf0:
                 if ($i + 3 >= $length) {
                     $i += 3;
                     $return .= '?';
                     break;
                 }
                 $charbits = $string[$i] . $string[$i + 1] . $string[$i + 2] . $string[$i + 3];
                 $char = Multibyte::utf8($charbits);
                 $return .= sprintf('\\u%04s', dechex($char[0]));
                 $i += 3;
                 break;
             case ($ord & 0xfc) == 0xf8:
                 if ($i + 4 >= $length) {
                     $i += 4;
                     $return .= '?';
                     break;
                 }
                 $charbits = $string[$i] . $string[$i + 1] . $string[$i + 2] . $string[$i + 3] . $string[$i + 4];
                 $char = Multibyte::utf8($charbits);
                 $return .= sprintf('\\u%04s', dechex($char[0]));
                 $i += 4;
                 break;
             case ($ord & 0xfe) == 0xfc:
                 if ($i + 5 >= $length) {
                     $i += 5;
                     $return .= '?';
                     break;
                 }
                 $charbits = $string[$i] . $string[$i + 1] . $string[$i + 2] . $string[$i + 3] . $string[$i + 4] . $string[$i + 5];
                 $char = Multibyte::utf8($charbits);
                 $return .= sprintf('\\u%04s', dechex($char[0]));
                 $i += 5;
                 break;
         }
     }
     return $return;
 }
Example #4
0
 /**
  * Prepare a string for mail transport, using the provided encoding
  *
  * @param string $string value to encode
  * @param string $charset charset to use for encoding. defaults to UTF-8
  * @param string $newline
  * @return string
  * @access public
  * @static
  * @TODO: add support for 'Q'('Quoted Printable') encoding
  */
 function mimeEncode($string, $charset = null, $newline = "\r\n")
 {
     if (!Multibyte::checkMultibyte($string) && strlen($string) < 75) {
         return $string;
     }
     if (empty($charset)) {
         $charset = Configure::read('App.encoding');
     }
     $charset = strtoupper($charset);
     $start = '=?' . $charset . '?B?';
     $end = '?=';
     $spacer = $end . $newline . ' ' . $start;
     $length = 75 - strlen($start) - strlen($end);
     $length = $length - $length % 4;
     if ($charset == 'UTF-8') {
         $parts = array();
         $maxchars = floor($length * 3 / 4);
         while (strlen($string) > $maxchars) {
             $i = $maxchars;
             $test = ord($string[$i]);
             while ($test >= 128 && $test <= 191) {
                 $i--;
                 $test = ord($string[$i]);
             }
             $parts[] = base64_encode(substr($string, 0, $i));
             $string = substr($string, $i);
         }
         $parts[] = base64_encode($string);
         $string = implode($spacer, $parts);
     } else {
         $string = chunk_split(base64_encode($string), $length, $spacer);
         $string = preg_replace('/' . preg_quote($spacer) . '$/', '', $string);
     }
     return $start . $string . $end;
 }
Example #5
0
 /**
  * testMultibyteSubstr method
  *
  * @return void
  */
 public function testMultibyteMimeEncode()
 {
     $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
     $result = Multibyte::mimeEncode($string);
     $this->assertEquals($string, $result);
     $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?w4DDgcOCw4PDhMOFw4bDh8OIw4nDisOLw4zDjcOOw4/DkMORw5LDk8OUw5U=?=' . "\r\n" . ' =?UTF-8?B?w5bDmMOZw5rDm8Ocw53Dng==?=';
     $this->assertEquals($expected, $result);
     $result = Multibyte::mimeEncode($string, NULL, "\n");
     $expected = '=?UTF-8?B?w4DDgcOCw4PDhMOFw4bDh8OIw4nDisOLw4zDjcOOw4/DkMORw5LDk8OUw5U=?=' . "\n" . ' =?UTF-8?B?w5bDmMOZw5rDm8Ocw53Dng==?=';
     $this->assertEquals($expected, $result);
     $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?xIDEgsSExIbEiMSKxIzEjsSQxJLElMSWxJjEmsScxJ7EoMSixKTEpsSoxKo=?=' . "\r\n" . ' =?UTF-8?B?xKzErsSyxLTEtsS5xLvEvcS/xYHFg8WFxYfFisWMxY7FkMWSxZTFlsWYxZo=?=' . "\r\n" . ' =?UTF-8?B?xZzFnsWgxaLFpMWmxajFqsWsxa7FsMWyxbTFtsW5xbvFvQ==?=';
     $this->assertEquals($expected, $result);
     $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?ISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xN?=' . "\r\n" . ' =?UTF-8?B?Tk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6?=' . "\r\n" . ' =?UTF-8?B?e3x9fg==?=';
     $this->assertEquals($expected, $result);
     $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?wqHCosKjwqTCpcKmwqfCqMKpwqrCq8Kswq3CrsKvwrDCscKywrPCtMK1wrY=?=' . "\r\n" . ' =?UTF-8?B?wrfCuMK5wrrCu8K8wr3CvsK/w4DDgcOCw4PDhMOFw4bDh8OI?=';
     $this->assertEquals($expected, $result);
     $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?w4nDisOLw4zDjcOOw4/DkMORw5LDk8OUw5XDlsOXw5jDmcOaw5vDnMOdw54=?=' . "\r\n" . ' =?UTF-8?B?w5/DoMOhw6LDo8Okw6XDpsOnw6jDqcOqw6vDrMOtw67Dr8Oww7HDssOzw7Q=?=' . "\r\n" . ' =?UTF-8?B?w7XDtsO3w7jDucO6w7vDvMO9w77Dv8SAxIHEgsSDxITEhcSGxIfEiMSJxIo=?=' . "\r\n" . ' =?UTF-8?B?xIvEjMSNxI7Ej8SQxJHEksSTxJTElcSWxJfEmMSZxJrEm8ScxJ3EnsSfxKA=?=' . "\r\n" . ' =?UTF-8?B?xKHEosSjxKTEpcSmxKfEqMSpxKrEq8Ss?=';
     $this->assertEquals($expected, $result);
     $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?xK3ErsSvxLDEscSyxLPEtMS1xLbEt8S4xLnEusS7xLzEvcS+xL/FgMWBxYI=?=' . "\r\n" . ' =?UTF-8?B?xYPFhMWFxYbFh8WIxYnFisWLxYzFjcWOxY/FkMWRxZLFk8WUxZXFlsWXxZg=?=' . "\r\n" . ' =?UTF-8?B?xZnFmsWbxZzFncWexZ/FoMWhxaLFo8WkxaXFpsWnxajFqcWqxavFrMWtxa4=?=' . "\r\n" . ' =?UTF-8?B?xa/FsMWxxbLFs8W0xbXFtsW3xbjFucW6xbvFvMW9xb7Fv8aAxoHGgsaDxoQ=?=' . "\r\n" . ' =?UTF-8?B?xoXGhsaHxojGicaKxovGjMaNxo7Gj8aQ?=';
     $this->assertEquals($expected, $result);
     $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?xpHGksaTxpTGlcaWxpfGmMaZxprGm8acxp3GnsafxqDGocaixqPGpMalxqY=?=' . "\r\n" . ' =?UTF-8?B?xqfGqMapxqrGq8asxq3GrsavxrDGscayxrPGtMa1xrbGt8a4xrnGusa7xrw=?=' . "\r\n" . ' =?UTF-8?B?xr3Gvsa/x4DHgceCx4PHhMeFx4bHh8eIx4nHiseLx4zHjceOx4/HkMeRx5I=?=' . "\r\n" . ' =?UTF-8?B?x5PHlMeVx5bHl8eYx5nHmsebx5zHnceex5/HoMehx6LHo8ekx6XHpsenx6g=?=' . "\r\n" . ' =?UTF-8?B?x6nHqserx6zHrceux6/HsMexx7LHs8e0?=';
     $this->assertEquals($expected, $result);
     $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?yZnJmsmbyZzJncmeyZ/JoMmhyaLJo8mkyaXJpsmnyajJqcmqyavJrMmtya4=?=' . "\r\n" . ' =?UTF-8?B?ya/JsMmxybLJs8m0ybXJtsm3ybjJucm6ybvJvMm9yb7Jv8qAyoHKgsqDyoQ=?=' . "\r\n" . ' =?UTF-8?B?yoXKhsqHyojKicqKyovKjMqNyo7Kj8qQypHKksqTypTKlcqWypfKmMqZypo=?=' . "\r\n" . ' =?UTF-8?B?ypvKnMqdyp7Kn8qgyqHKosqjyqTKpcqmyqfKqMqpyqrKq8qsyq3KrsqvyrA=?=' . "\r\n" . ' =?UTF-8?B?yrHKssqzyrTKtcq2yrfKuMq5yrrKu8q8?=';
     $this->assertEquals($expected, $result);
     $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?0IDQgdCC0IPQhNCF0IbQh9CI0InQitCL0IzQjdCO0I/QkNCR0JLQk9CU0JU=?=' . "\r\n" . ' =?UTF-8?B?0JbQl9CY0JnQmtCb?=';
     $this->assertEquals($expected, $result);
     $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?0JzQndCe0J/QoNCh0KLQo9Ck0KXQptCn0KjQqdCq0KvQrNCt0K7Qr9Cw0LE=?=' . "\r\n" . ' =?UTF-8?B?0LLQs9C00LXQttC30LjQudC60LvQvNC90L7Qv9GA0YHRgtGD0YTRhdGG0Yc=?=' . "\r\n" . ' =?UTF-8?B?0YjRidGK0YvRjA==?=';
     $this->assertEquals($expected, $result);
     $string = 'فقكلمنهوىيًٌٍَُ';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?2YHZgtmD2YTZhdmG2YfZiNmJ2YrZi9mM2Y3ZjtmP?=';
     $this->assertEquals($expected, $result);
     $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?4pyw4pyx4pyy4pyz4py04py14py24py34py44py54py64py74py84py94py+?=' . "\r\n" . ' =?UTF-8?B?4py/4p2A4p2B4p2C4p2D4p2E4p2F4p2G4p2H4p2I4p2J4p2K4p2L4p2M4p2N?=' . "\r\n" . ' =?UTF-8?B?4p2O4p2P4p2Q4p2R4p2S4p2T4p2U4p2V4p2W4p2X4p2Y4p2Z4p2a4p2b4p2c?=' . "\r\n" . ' =?UTF-8?B?4p2d4p2e?=';
     $this->assertEquals($expected, $result);
     $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?4rqA4rqB4rqC4rqD4rqE4rqF4rqG4rqH4rqI4rqJ4rqK4rqL4rqM4rqN4rqO?=' . "\r\n" . ' =?UTF-8?B?4rqP4rqQ4rqR4rqS4rqT4rqU4rqV4rqW4rqX4rqY4rqZ4rqb4rqc4rqd4rqe?=' . "\r\n" . ' =?UTF-8?B?4rqf4rqg4rqh4rqi4rqj4rqk4rql4rqm4rqn4rqo4rqp4rqq4rqr4rqs4rqt?=' . "\r\n" . ' =?UTF-8?B?4rqu4rqv4rqw4rqx4rqy4rqz4rq04rq14rq24rq34rq44rq54rq64rq74rq8?=' . "\r\n" . ' =?UTF-8?B?4rq94rq+4rq/4ruA4ruB4ruC4ruD4ruE4ruF4ruG4ruH4ruI4ruJ4ruK4ruL?=' . "\r\n" . ' =?UTF-8?B?4ruM4ruN4ruO4ruP4ruQ4ruR4ruS4ruT4ruU4ruV4ruW4ruX4ruY4ruZ4rua?=' . "\r\n" . ' =?UTF-8?B?4rub4ruc4rud4rue4ruf4rug?=';
     $this->assertEquals($expected, $result);
     $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?4r2F4r2G4r2H4r2I4r2J4r2K4r2L4r2M4r2N4r2O4r2P4r2Q4r2R4r2S4r2T?=' . "\r\n" . ' =?UTF-8?B?4r2U4r2V4r2W4r2X4r2Y4r2Z4r2a4r2b4r2c4r2d4r2e4r2f4r2g4r2h4r2i?=' . "\r\n" . ' =?UTF-8?B?4r2j4r2k4r2l4r2m4r2n4r2o4r2p4r2q4r2r4r2s4r2t4r2u4r2v4r2w4r2x?=' . "\r\n" . ' =?UTF-8?B?4r2y4r2z4r204r214r224r234r244r254r264r274r284r294r2+4r2/?=';
     $this->assertEquals($expected, $result);
     $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?64ih64ii64ij64ik64il64im64in64io64ip64iq64ir64is64it64iu64iv?=' . "\r\n" . ' =?UTF-8?B?64iw64ix64iy64iz64i064i164i264i364i464i564i664i764i864i964i+?=' . "\r\n" . ' =?UTF-8?B?64i/64mA64mB64mC64mD64mE64mF64mG64mH64mI64mJ64mK64mL64mM64mN?=' . "\r\n" . ' =?UTF-8?B?64mO64mP64mQ64mR64mS64mT64mU64mV64mW64mX64mY64mZ64ma64mb64mc?=' . "\r\n" . ' =?UTF-8?B?64md64me64mf64mg64mh64mi64mj64mk64ml64mm64mn64mo64mp64mq64mr?=' . "\r\n" . ' =?UTF-8?B?64ms64mt64mu64mv64mw64mx64my64mz64m064m164m264m364m464m564m6?=' . "\r\n" . ' =?UTF-8?B?64m764m864m964m+64m/64qA64qB64qC64qD64qE?=';
     $this->assertEquals($expected, $result);
     $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?77mw77mx77my77mz77m077m177m277m377m477m577m677m777m877m977m+?=' . "\r\n" . ' =?UTF-8?B?77m/77qA77qB77qC77qD77qE77qF77qG77qH77qI77qJ77qK77qL77qM77qN?=' . "\r\n" . ' =?UTF-8?B?77qO77qP77qQ77qR77qS77qT77qU77qV77qW77qX77qY77qZ77qa77qb77qc?=' . "\r\n" . ' =?UTF-8?B?77qd77qe77qf77qg77qh77qi77qj77qk77ql77qm77qn77qo77qp77qq77qr?=' . "\r\n" . ' =?UTF-8?B?77qs77qt77qu77qv77qw?=';
     $this->assertEquals($expected, $result);
     $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?77qx77qy77qz77q077q177q277q377q477q577q677q777q877q977q+77q/?=' . "\r\n" . ' =?UTF-8?B?77uA77uB77uC77uD77uE77uF77uG77uH77uI77uJ77uK77uL77uM77uN77uO?=' . "\r\n" . ' =?UTF-8?B?77uP77uQ77uR77uS77uT77uU77uV77uW77uX77uY77uZ77ua77ub77uc77ud?=' . "\r\n" . ' =?UTF-8?B?77ue77uf77ug77uh77ui77uj77uk77ul77um77un77uo77up77uq77ur77us?=' . "\r\n" . ' =?UTF-8?B?77ut77uu77uv77uw77ux77uy77uz77u077u177u277u377u477u577u677u7?=' . "\r\n" . ' =?UTF-8?B?77u8?=';
     $this->assertEquals($expected, $result);
     $string = 'abcdefghijklmnopqrstuvwxyz';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?772B772C772D772E772F772G772H772I772J772K772L772M772N772O772P?=' . "\r\n" . ' =?UTF-8?B?772Q772R772S772T772U772V772W772X772Y772Z772a?=';
     $this->assertEquals($expected, $result);
     $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?772h772i772j772k772l772m772n772o772p772q772r772s772t772u772v?=' . "\r\n" . ' =?UTF-8?B?772w772x772y772z77207721772277237724?=';
     $this->assertEquals($expected, $result);
     $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?77257726772777287729772+772/776A776B776C776D776E776F776G776H?=' . "\r\n" . ' =?UTF-8?B?776I776J776K776L776M776N776O776P776Q776R776S776T776U776V776W?=' . "\r\n" . ' =?UTF-8?B?776X776Y776Z776a776b776c776d776e?=';
     $this->assertEquals($expected, $result);
     $string = 'Ĥēĺļŏ, Ŵőřļď!';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?xKTEk8S6xLzFjywgxbTFkcWZxLzEjyE=?=';
     $this->assertEquals($expected, $result);
     $string = 'Hello, World!';
     $result = Multibyte::mimeEncode($string);
     $this->assertEquals($string, $result);
     $string = 'čini';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?xI1pbmk=?=';
     $this->assertEquals($expected, $result);
     $string = 'moći';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?bW/Eh2k=?=';
     $this->assertEquals($expected, $result);
     $string = 'državni';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?ZHLFvmF2bmk=?=';
     $this->assertEquals($expected, $result);
     $string = '把百度设为首页';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?5oqK55m+5bqm6K6+5Li66aaW6aG1?=';
     $this->assertEquals($expected, $result);
     $string = '一二三周永龍';
     $result = Multibyte::mimeEncode($string);
     $expected = '=?UTF-8?B?5LiA5LqM5LiJ5ZGo5rC46b6N?=';
     $this->assertEquals($expected, $result);
 }
 /**
  * Encode string for MIME header
  *
  * @param string $str The string being encoded
  * @param string $charset specifies the name of the character set in which str is represented in.
  *    The default value is determined by the current NLS setting (mbstring.language).
  * @param string $transfer_encoding specifies the scheme of MIME encoding.
  *    It should be either "B" (Base64) or "Q" (Quoted-Printable). Falls back to "B" if not given.
  * @param string $linefeed specifies the EOL (end-of-line) marker with which
  *    mb_encode_mimeheader() performs line-folding
  *    (a » RFC term, the act of breaking a line longer than a certain length into multiple lines.
  *    The length is currently hard-coded to 74 characters). Falls back to "\r\n" (CRLF) if not given.
  * @param integer $indent [definition unknown and appears to have no affect]
  * @return string A converted version of the string represented in ASCII.
  */
 function mb_encode_mimeheader($str, $charset = 'UTF-8', $transferEncoding = 'B', $linefeed = "\r\n", $indent = 1)
 {
     return Multibyte::mimeEncode($str, $charset, $linefeed);
 }
Example #7
0
 /**
  * Find the related code folding values for $char
  *
  * @param int $char decimal value of character
  * @param string $type Type 'lower' or 'upper'. Defaults to 'lower'.
  * @return array|null
  */
 protected static function _find($char, $type = 'lower')
 {
     $found = array();
     if (!isset(self::$_codeRange[$char])) {
         $range = self::_codepoint($char);
         if ($range === false) {
             return null;
         }
         if (!Configure::configured('_cake_core_')) {
             App::uses('PhpReader', 'Configure');
             Configure::config('_cake_core_', new PhpReader(CAKE . 'Config' . DS));
         }
         Configure::load('unicode' . DS . 'casefolding' . DS . $range, '_cake_core_');
         self::$_caseFold[$range] = Configure::read($range);
         Configure::delete($range);
     }
     if (!self::$_codeRange[$char]) {
         return null;
     }
     self::$_table = self::$_codeRange[$char];
     $count = count(self::$_caseFold[self::$_table]);
     for ($i = 0; $i < $count; $i++) {
         if ($type === 'lower' && self::$_caseFold[self::$_table][$i][$type][0] === $char) {
             $found[] = self::$_caseFold[self::$_table][$i];
         } elseif ($type === 'upper' && self::$_caseFold[self::$_table][$i][$type] === $char) {
             $found[] = self::$_caseFold[self::$_table][$i];
         }
     }
     return $found;
 }
Example #8
0
 /**
  * resets the utf8 map array
  *
  * @access private
  */
 function __reset()
 {
     $_this =& Multibyte::getInstance();
     $_this->__utf8Map = array();
 }
Example #9
0
	/**
	 * Returns date formatted according to given format.
	 *
	 * @see DateTime::format()
	 * @param string $format Format accepted by {@link http://php.net/date date()}.
	 * @return string The formatted date, false on failure.
	 */
	public function format( $format = null )
	{
		$day_months = array(
			'January' => _t( 'January' ),
			'February' => _t( 'February' ),
			'March' => _t( 'March' ),
			'April' => _t( 'April' ),
			'May' => _t( 'May' ),
			'June' => _t( 'June' ),
			'July' => _t( 'July' ),
			'August' => _t( 'August' ),
			'September' => _t( 'September' ),
			'October' => _t( 'October' ),
			'November' => _t( 'November' ),
			'December' => _t( 'December' ),
			'Jan' => _t( 'Jan' ),
			'Feb' => _t( 'Feb' ),
			'Mar' => _t( 'Mar' ),
			'Apr' => _t( 'Apr' ),
			'May' => _t( 'May' ),
			'Jun' => _t( 'Jun' ),
			'Jul' => _t( 'Jul' ),
			'Aug' => _t( 'Aug' ),
			'Sep' => _t( 'Sep' ),
			'Oct' => _t( 'Oct' ),
			'Nov' => _t( 'Nov' ),
			'Dec' => _t( 'Dec' ),
			'Sunday' => _t( 'Sunday' ),
			'Monday' => _t( 'Monday' ),
			'Tuesday' => _t( 'Tuesday' ),
			'Wednesday' => _t( 'Wednesday' ),
			'Thursday' => _t( 'Thursday' ),
			'Friday' => _t( 'Friday' ),
			'Saturday' => _t( 'Saturday' ),
			'Sun' => _t( 'Sun' ),
			'Mon' => _t( 'Mon' ),
			'Tue' => _t( 'Tue' ),
			'Wed' => _t( 'Wed' ),
			'Thu' => _t( 'Thu' ),
			'Fri' => _t( 'Fri' ),
			'Sat' => _t( 'Sat' ),
			'am' => _t( 'am' ),
			'pm' => _t( 'pm' ),
			'AM' => _t( 'AM' ),
			'PM' => _t( 'PM' ),
		);

		if ( $format === null ) {
			$format = self::$default_datetime_format;
		}
		
		$result = parent::format( $format );
		
		if ( ! $result ) {
			return false;
		}
		
		$result = Multibyte::str_replace( array_keys( $day_months ), array_values( $day_months ), $result );
		
		return $result;
	}
Example #10
0
 /**
  * Find the related code folding values for $char
  *
  * @param integer $char decimal value of character
  * @param string $type
  * @return array
  * @access private
  */
 private static function __find($char, $type = 'lower')
 {
     $value = false;
     $found = array();
     if (!isset(self::$__codeRange[$char])) {
         $range = self::__codepoint($char);
         if ($range === false) {
             return null;
         }
         Configure::load('unicode' . DS . 'casefolding' . DS . $range);
         self::$__caseFold[$range] = Configure::read($range);
         Configure::delete($range);
     }
     if (!self::$__codeRange[$char]) {
         return null;
     }
     self::$__table = self::$__codeRange[$char];
     $count = count(self::$__caseFold[self::$__table]);
     for ($i = 0; $i < $count; $i++) {
         if ($type === 'lower' && self::$__caseFold[self::$__table][$i][$type][0] === $char) {
             $found[] = self::$__caseFold[self::$__table][$i];
         } elseif ($type === 'upper' && self::$__caseFold[self::$__table][$i][$type] === $char) {
             $found[] = self::$__caseFold[self::$__table][$i];
         }
     }
     return $found;
 }
Example #11
0
	/**
	 * Encode a string into JSON.  Converts and escapes necessary characters.
	 *
	 * @param string $string The string that needs to be utf8->hex encoded
	 * @return void
	 * @access protected
	 */
	function _utf8ToHex($string) {
		$length = strlen($string);
		$return = '';
		for ($i = 0; $i < $length; ++$i) {
			$ord = ord($string{$i});
			switch (true) {
				case $ord == 0x08:
					$return .= '\b';
					break;
				case $ord == 0x09:
					$return .= '\t';
					break;
				case $ord == 0x0A:
					$return .= '\n';
					break;
				case $ord == 0x0C:
					$return .= '\f';
					break;
				case $ord == 0x0D:
					$return .= '\r';
					break;
				case $ord == 0x22:
				case $ord == 0x2F:
				case $ord == 0x5C:
					$return .= '\\' . $string{$i};
					break;
				case (($ord >= 0x20) && ($ord <= 0x7F)):
					$return .= $string{$i};
					break;
				case (($ord & 0xE0) == 0xC0):
					if ($i + 1 >= $length) {
						$i += 1;
						$return .= '?';
						break;
					}
					$charbits = $string{$i} . $string{$i + 1};
					$char = Multibyte::utf8($charbits);
					$return .= sprintf('\u%04s', dechex($char[0]));
					$i += 1;
					break;
				case (($ord & 0xF0) == 0xE0):
					if ($i + 2 >= $length) {
						$i += 2;
						$return .= '?';
						break;
					}
					$charbits = $string{$i} . $string{$i + 1} . $string{$i + 2};
					$char = Multibyte::utf8($charbits);
					$return .= sprintf('\u%04s', dechex($char[0]));
					$i += 2;
					break;
				case (($ord & 0xF8) == 0xF0):
					if ($i + 3 >= $length) {
						$i += 3;
						$return .= '?';
						break;
					}
					$charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3};
					$char = Multibyte::utf8($charbits);
					$return .= sprintf('\u%04s', dechex($char[0]));
					$i += 3;
					break;
				case (($ord & 0xFC) == 0xF8):
					if ($i + 4 >= $length) {
						$i += 4;
						$return .= '?';
						break;
					}
					$charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3} . $string{$i + 4};
					$char = Multibyte::utf8($charbits);
					$return .= sprintf('\u%04s', dechex($char[0]));
					$i += 4;
					break;
				case (($ord & 0xFE) == 0xFC):
					if ($i + 5 >= $length) {
						$i += 5;
						$return .= '?';
						break;
					}
					$charbits = $string{$i} . $string{$i + 1} . $string{$i + 2} . $string{$i + 3} . $string{$i + 4} . $string{$i + 5};
					$char = Multibyte::utf8($charbits);
					$return .= sprintf('\u%04s', dechex($char[0]));
					$i += 5;
					break;
			}
		}
		return $return;
	}
 /**
  * testMultibyteSubstr method
  * 
  * @access public
  * @return void
  */
 function testMultibyteSubstr()
 {
     $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
     $result = Multibyte::substr($string, 4, 7);
     $expected = 'EFGHIJK';
     $this->assertEqual($result, $expected);
     $string = 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ';
     $result = Multibyte::substr($string, 4, 7);
     $expected = 'ÄÅÆÇÈÉÊ';
     $this->assertEqual($result, $expected);
     $string = 'ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮIJĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŹŻŽ';
     $find = 'Ċ';
     $result = Multibyte::substr($string, 4, 7);
     $expected = 'ĈĊČĎĐĒĔ';
     $this->assertEqual($result, $expected);
     $string = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
     $result = Multibyte::substr($string, 4, 7);
     $expected = '%&\'()*+';
     $this->assertEqual($result, $expected);
     $string = '¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
     $result = Multibyte::substr($string, 4);
     $expected = '¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈ';
     $this->assertEqual($result, $expected);
     $string = 'ÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬ';
     $result = Multibyte::substr($string, 4, 7);
     $expected = 'ÍÎÏÐÑÒÓ';
     $this->assertEqual($result, $expected);
     $string = 'ĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſƀƁƂƃƄƅƆƇƈƉƊƋƌƍƎƏƐ';
     $result = Multibyte::substr($string, 4, 7);
     $expected = 'ıIJijĴĵĶķ';
     $this->assertEqual($result, $expected);
     $string = 'ƑƒƓƔƕƖƗƘƙƚƛƜƝƞƟƠơƢƣƤƥƦƧƨƩƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
     $result = Multibyte::substr($string, 25);
     $expected = 'ƪƫƬƭƮƯưƱƲƳƴƵƶƷƸƹƺƻƼƽƾƿǀǁǂǃDŽDždžLJLjljNJNjnjǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜǝǞǟǠǡǢǣǤǥǦǧǨǩǪǫǬǭǮǯǰDZDzdzǴ';
     $this->assertEqual($result, $expected);
     $string = 'əɚɛɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
     $result = Multibyte::substr($string, 3);
     $expected = 'ɜɝɞɟɠɡɢɣɤɥɦɧɨɩɪɫɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʂʃʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯʰʱʲʳʴʵʶʷʸʹʺʻʼ';
     $this->assertEqual($result, $expected);
     $string = 'ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
     $result = Multibyte::substr($string, 3);
     $expected = 'ЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛ';
     $this->assertEqual($result, $expected);
     $string = 'МНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
     $result = Multibyte::substr($string, 3, 16);
     $expected = 'ПРСТУФХЦЧШЩЪЫЬЭЮ';
     $this->assertEqual($result, $expected);
     $string = 'فقكلمنهوىيًٌٍَُ';
     $result = Multibyte::substr($string, 3, 6);
     $expected = 'لمنهوى';
     $this->assertEqual($result, $expected);
     $string = '✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞';
     $result = Multibyte::substr($string, 6, 14);
     $expected = '✶✷✸✹✺✻✼✽✾✿❀❁❂❃';
     $this->assertEqual($result, $expected);
     $string = '⺀⺁⺂⺃⺄⺅⺆⺇⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔⺕⺖⺗⺘⺙⺛⺜⺝⺞⺟⺠⺡⺢⺣⺤⺥⺦⺧⺨⺩⺪⺫⺬⺭⺮⺯⺰⺱⺲⺳⺴⺵⺶⺷⺸⺹⺺⺻⺼⺽⺾⺿⻀⻁⻂⻃⻄⻅⻆⻇⻈⻉⻊⻋⻌⻍⻎⻏⻐⻑⻒⻓⻔⻕⻖⻗⻘⻙⻚⻛⻜⻝⻞⻟⻠';
     $result = Multibyte::substr($string, 8, 13);
     $expected = '⺈⺉⺊⺋⺌⺍⺎⺏⺐⺑⺒⺓⺔';
     $this->assertEqual($result, $expected);
     $string = '⽅⽆⽇⽈⽉⽊⽋⽌⽍⽎⽏⽐⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨⽩⽪⽫⽬⽭⽮⽯⽰⽱⽲⽳⽴⽵⽶⽷⽸⽹⽺⽻⽼⽽⽾⽿';
     $result = Multibyte::substr($string, 12, 24);
     $expected = '⽑⽒⽓⽔⽕⽖⽗⽘⽙⽚⽛⽜⽝⽞⽟⽠⽡⽢⽣⽤⽥⽦⽧⽨';
     $this->assertEqual($result, $expected);
     $string = '눡눢눣눤눥눦눧눨눩눪눫눬눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄뉅뉆뉇뉈뉉뉊뉋뉌뉍뉎뉏뉐뉑뉒뉓뉔뉕뉖뉗뉘뉙뉚뉛뉜뉝뉞뉟뉠뉡뉢뉣뉤뉥뉦뉧뉨뉩뉪뉫뉬뉭뉮뉯뉰뉱뉲뉳뉴뉵뉶뉷뉸뉹뉺뉻뉼뉽뉾뉿늀늁늂늃늄';
     $result = Multibyte::substr($string, 12, 24);
     $expected = '눭눮눯눰눱눲눳눴눵눶눷눸눹눺눻눼눽눾눿뉀뉁뉂뉃뉄';
     $this->assertEqual($result, $expected);
     $string = 'ﹰﹱﹲﹳﹴ﹵ﹶﹷﹸﹹﹺﹻﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
     $result = Multibyte::substr($string, 12);
     $expected = 'ﹼﹽﹾﹿﺀﺁﺂﺃﺄﺅﺆﺇﺈﺉﺊﺋﺌﺍﺎﺏﺐﺑﺒﺓﺔﺕﺖﺗﺘﺙﺚﺛﺜﺝﺞﺟﺠﺡﺢﺣﺤﺥﺦﺧﺨﺩﺪﺫﺬﺭﺮﺯﺰ';
     $this->assertEqual($result, $expected);
     $string = 'ﺱﺲﺳﺴﺵﺶﺷﺸﺹﺺﺻﺼﺽﺾﺿﻀﻁﻂﻃﻄﻅﻆﻇﻈﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔﻕﻖﻗﻘﻙﻚﻛﻜﻝﻞﻟﻠﻡﻢﻣﻤﻥﻦﻧﻨﻩﻪﻫﻬﻭﻮﻯﻰﻱﻲﻳﻴﻵﻶﻷﻸﻹﻺﻻﻼ';
     $result = Multibyte::substr($string, 24, 12);
     $expected = 'ﻉﻊﻋﻌﻍﻎﻏﻐﻑﻒﻓﻔ';
     $this->assertEqual($result, $expected);
     $string = 'abcdefghijklmnopqrstuvwxyz';
     $result = Multibyte::substr($string, 11, 2);
     $expected = 'lm';
     $this->assertEqual($result, $expected);
     $string = '。「」、・ヲァィゥェォャュョッーアイウエオカキク';
     $result = Multibyte::substr($string, 7, 11);
     $expected = 'ィゥェォャュョッーアイ';
     $this->assertEqual($result, $expected);
     $string = 'ケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙';
     $result = Multibyte::substr($string, 13, 13);
     $expected = 'ニヌネノハヒフヘホマミムメ';
     $this->assertEqual($result, $expected);
     $string = 'Ĥēĺļŏ, Ŵőřļď!';
     $result = Multibyte::substr($string, 3, 4);
     $expected = 'ļŏ, ';
     $this->assertEqual($result, $expected);
     $string = 'Hello, World!';
     $result = Multibyte::substr($string, 3, 4);
     $expected = 'lo, ';
     $this->assertEqual($result, $expected);
     $string = 'čini';
     $result = Multibyte::substr($string, 3);
     $expected = 'i';
     $this->assertEqual($result, $expected);
     $string = 'moći';
     $result = Multibyte::substr($string, 1);
     $expected = 'oći';
     $this->assertEqual($result, $expected);
     $string = 'državni';
     $result = Multibyte::substr($string, 0, 2);
     $expected = 'dr';
     $this->assertEqual($result, $expected);
     $string = '把百度设为首页';
     $result = Multibyte::substr($string, 3, 3);
     $expected = '设为首';
     $this->assertEqual($result, $expected);
     $string = '一二三周永龍';
     $result = Multibyte::substr($string, 0, 1);
     $expected = '一';
     $this->assertEqual($result, $expected);
     $string = '一二三周永龍';
     $result = Multibyte::substr($string, 6);
     $expected = false;
     $this->assertEqual($result, $expected);
     $string = '一二三周永龍';
     $result = Multibyte::substr($string, 0);
     $expected = '一二三周永龍';
     $this->assertEqual($result, $expected);
 }