OSDN Git Service

Revert "4.0のtrunkを展開するためにmasterディレクトリを作成しファイル群を移動した。"
[nucleus-jp/nucleus-jp-ancient.git] / nucleus / libs / mb_emulator / mb-emulator.php
1 <?php
2 /* mbstring emulator for Japanese by Andy
3  * email : webmaster@matsubarafamily.com
4  *
5  * license based on GPL(GNU General Public License)
6  *
7  * Ver.0.84 (2006/1/20)
8  */
9
10
11 define('MB_CASE_UPPER', 0);
12 define('MB_CASE_LOWER', 1);
13 define('MB_CASE_TITLE', 2);
14
15 include dirname(__FILE__).'/convert.table';
16 // include dirname(__FILE__).'/sjistouni.table';
17 // include dirname(__FILE__).'/unitosjis.table';
18
19
20 $mbemu_internals['ini_file'] = parse_ini_file(dirname(__FILE__).'/mb-emulator.ini');
21
22 $mbemu_internals['language'] = $mbemu_internals['ini_file']['language'];
23 $mbemu_internals['internal_encoding'] = $mbemu_internals['ini_file']['internal_encoding'];
24 $mbemu_internals['lang_array'] = array (
25         'Japanese', 'ja','jp', 'English', 'en', 'uni'
26         );
27
28 $mbemu_internals['encoding'] = array (
29         'AUTO' => 0xFF,
30         'ASCII' => 0,
31         'EUC-JP' => 1,
32         'EUC' => 1,
33         'SJIS' => 2,
34         'SHIFT-JIS' => 2,
35         'SHIFT_JIS' => 2,
36         'SJIS-WIN' => 2,
37         'JIS' => 3,
38         'ISO-2022-JP' => 3,
39         'UTF-8' => 4,
40         'UTF8' => 4,
41         'UTF-16'=>5,
42         'ISO-8859-1' => 6
43         );
44
45
46 function mb_detect_order($encoding_list = '')
47 {
48         global $mbemu_internals;
49         
50         if ($encoding_list) {
51                 if (is_string($encoding_list)) {
52                         $encoding_list = strtoupper($encoding_list);
53                         $encoding_list = split(', *', $encoding_list);
54                 }
55                 foreach($encoding_list as $encode)
56                         if (!array_key_exists($encode, $mbemu_internals['encoding'])) return FALSE;
57                 $mbemu_internals['detect_order'] = $encoding_list;
58                 return TRUE;
59         }
60         return $mbemu_internals['detect_order'];
61 }
62
63 if (!(mb_detect_order($mbemu_internals['ini_file']['detect_order'])))
64         $mbemu_internals['detect_order'] = array ("ASCII", "JIS", "UTF-8", "EUC-JP", "SJIS");
65
66 $mbemu_internals['substitute_character'] = $mbemu_internals['ini_file']['substitute_character'];
67
68 $mbemu_internals['regex'] = array(
69         0 => "[\x01-\x7F]", // for ASCII
70         1 => "[\xA1-\xFE]([\xA1-\xFE])|[\x01-\x7F]|\x8E([\xA0-\xDF])", // for EUC-JP
71         2 => "[\x81-\x9F\xE0-\xFC]([\x40-\xFC])|[\x01-\x7F]|[\xA0-\xDF]", // for Shift_JIS
72         3 => "(?:^|\x1B\(\x42)([\x01-\x1A,\x1C-\x7F]*)|(?:\x1B\\$\x42([\x01-\x1A,\x1C-\x7F]*))|(?:\x1B\(I([\x01-\x1A,\x1C-\x7F]*))", // for JIS
73         4 => "[\x01-\x7F]|[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF][\x80-\xBF]", // for UTF-8
74         5 => "..", // for UTF-16
75         6 => "." // for ISO-8859-1
76         );
77
78
79
80 function mb_language($language='')
81 {
82   global $mbemu_internals;
83
84   if ($language =='') {
85     if ($mbemu_internals['language'] == '') return FALSE;
86     else return $mbemu_internals['language'];
87   } else {
88         foreach ($mbemu_internals['lang_array'] as $element) {
89                 if ($element == $language) {
90                         $mbemu_internals['language'] = $language;
91                         return TRUE;
92                 }
93         }
94         return FALSE;
95   }
96 }
97
98
99 function mb_internal_encoding($encoding = '')
100 {
101         global $mbemu_internals;
102
103   if ($encoding =='') {
104     if ($mbemu_internals['internal_encoding'] == '') return FALSE;
105     else return $mbemu_internals['internal_encoding'];
106   } else {
107                 $mbemu_internals['internal_encoding'] = $encoding;
108                 return TRUE;
109   }
110 }
111
112 function mb_get_info($type = 'all')
113 {
114         switch(strtolower($type)) {
115                 case 'all' :
116                         $a['internal_encoding'] = mb_internal_encoding();
117                         $a['http_output'] = mb_http_output();
118                         $a['http_input'] = 'pass';
119                         $a['func_overload'] = 'pass';
120                         return $a;
121                 case 'internal_encoding' :
122                         return mb_internal_encoding();
123                 case 'http_output' :
124                         return mb_http_output();
125                 case 'http_input' :
126                         return 'pass';
127                 case 'func_overloard' :
128                         return 'pass';
129         }
130 }
131
132 function mb_substitute_character($subchar='')
133 {
134         global $mbemu_internals;
135         
136         if (!$subchar) return $mbemu_internals['substitute_character'];
137         if (is_int($subchar)) {
138                 $mbemu_internals['substitute_character'] = $subchar;
139         } else {
140                 $subchar = strtolower($subchar);
141                 switch ($subchar) {
142                         case 'none' :
143                         case 'long' :
144                                 $mbemu_internals['substitute_character'] = $subchar;
145                 }
146         }
147 }
148
149
150 function mb_convert_encoding( $str, $to_encoding, $from_encoding = '')
151 {
152         global $mbemu_internals;
153
154         $to_encoding = strtoupper($to_encoding);
155         $from_encoding = mb_detect_encoding($str, $from_encoding);
156         
157         switch ($mbemu_internals['encoding'][$from_encoding]) {
158                 case 1: //euc-jp
159                         switch($mbemu_internals['encoding'][$to_encoding]) {
160                                 case 2: //sjis
161                                         return _euctosjis($str);
162                                 case 3: //jis
163                                         $str = _euctosjis($str);
164                                         return _sjistojis($str);
165                                 case 4: //utf8
166                                         return _euctoutf8($str);
167                                 case 5: //utf16
168                                         $str = _euctoutf8($str);
169                                         return _utf8toutf16($str);
170                                 default:
171                                         return $str;
172                         }
173                 case 2: //sjis
174                         switch($mbemu_internals['encoding'][$to_encoding]) {
175                                 case 1: //euc-jp
176                                         return _sjistoeuc($str);
177                                 case 3: //jis
178                                         return _sjistojis($str);
179                                 case 4: //utf8
180                                         return _sjistoutf8($str);
181                                 case 5: //utf16
182                                         $str = _sjistoutf8($str);
183                                         return _utf8toutf16($str);
184                                 default:
185                                         return $str;
186                         }
187                 case 3: //jis
188                         switch($mbemu_internals['encoding'][$to_encoding]) {
189                                 case 1: //euc-jp
190                                         $str = _jistosjis($str);
191                                         return _sjistoeuc($str);
192                                 case 2: //sjis
193                                         return _jistosjis($str);
194                                 case 4: //utf8
195                                         $str = _jistosjis($str);
196                                         return _sjistoutf8($str);
197                                 case 5: //utf16
198                                         $str = _jistosjis($str);
199                                         $str = _sjistoutf8($str);
200                                         return _utf8toutf16($str);
201                                 default:
202                                         return $str;
203                         }
204                 case 4: //utf8
205                         switch($mbemu_internals['encoding'][$to_encoding]) {
206                                 case 1: //euc-jp
207                                         return _utf8toeuc($str);
208                                 case 2: //sjis
209                                         return _utf8tosjis($str);
210                                 case 3: //jis
211                                         $str = _utf8tosjis($str);
212                                         return _sjistojis($str);
213                                 case 5: //utf16
214                                         return _utf8toutf16($str);
215                                 default:
216                                         return $str;
217                         }
218                 case 5: //utf16
219                         $str = _utf16toutf8($str);
220                         switch($mbemu_internals['encoding'][$to_encoding]) {
221                                 case 1: //euc-jp
222                                         return _utf8toeuc($str);
223                                 case 2: //sjis
224                                         return _utf8tosjis($str);
225                                 case 3: //jis
226                                         $str = _utf8tosjis($str);
227                                         return _sjistojis($str);
228                                 case 4: //utf8
229                                         return $str;
230                                 default:
231                                         return _utf8toutf16($str);
232                         }
233                 default:
234                         return $str;
235         }
236 }
237
238
239
240 function _sjistoeuc(&$str)
241 {
242         global $mbemu_internals;
243         
244         $max = preg_match_all('/'.$mbemu_internals['regex'][2].'/', $str, $allchars);  // \95\8e\9a\82Ì\94z\97ñ\82É\95ª\89ð
245         $str_EUC = '';
246         for ($i = 0; $i < $max; ++$i) {
247                 $num = ord($allchars[0][$i]);  // \8ae\95\8e\9a\82Ì1\83o\83C\83g\96Ú\82ð\90\94\92l\82Æ\82µ\82Ä\8eæ\82è\8fo\82·
248                 if ($num2 = ord($allchars[1][$i])) { // 2\83o\83C\83g\96Ú\82ª\82 \82é\8fê\8d\87
249                         $shift = $mbemu_internals['sjistoeuc_byte1_shift'][$num2];
250                         $str_EUC .= chr($mbemu_internals['sjistoeuc_byte1'][$num] + $shift)
251                                            .chr($mbemu_internals['sjistoeuc_byte2'][$shift][$num2]);
252                 } elseif ($num <= 0x7F) {//\89p\90\94\8e\9a
253                         $str_EUC .= chr($num);
254                 } else { //\94¼\8ap\83J\83i
255                         $str_EUC .= chr(0x8E).chr($num);
256                 }
257         }
258         return $str_EUC;
259 }
260
261
262 function _euctosjis(&$str)
263 {
264         global $mbemu_internals;
265         $max = preg_match_all('/'.$mbemu_internals['regex'][1].'/', $str, $allchars);  // \95\8e\9a\82Ì\94z\97ñ\82É\95ª\89ð
266         $str_SJIS = '';
267         for ($i = 0; $i < $max; ++$i) {
268                 $num = ord($allchars[0][$i]);  // \8ae\95\8e\9a\82Ì1\83o\83C\83g\96Ú\82ð\90\94\92l\82Æ\82µ\82Ä\8eæ\82è\8fo\82·
269                 if ($num2 = ord($allchars[1][$i])) { // \8a¿\8e\9a\82Ì\8fê\8d\87
270                         $str_SJIS .= chr($mbemu_internals['euctosjis_byte1'][$num]);
271                         if ($num & 1)
272                                 $str_SJIS .= chr($mbemu_internals['euctosjis_byte2'][0][$num2]);
273                         else
274                                 $str_SJIS .= chr($mbemu_internals['euctosjis_byte2'][1][$num2]);
275                 } elseif ($num3 = ord($allchars[2][$i])) {//\94¼\8ap\83J\83i
276                         $str_SJIS .= chr($num3);
277                 } else { //\89p\90\94\8e\9a
278                         $str_SJIS .= chr($num);
279                 }
280         }
281         return $str_SJIS;
282 }
283
284 function _sjistojis(&$str)
285 {
286         global $mbemu_internals;
287         
288         $max = preg_match_all('/'.$mbemu_internals['regex'][2].'/', $str, $allchars);  // \95\8e\9a\82Ì\94z\97ñ\82É\95ª\89ð
289         $str_JIS = '';
290         $mode = 0; // \89p\90\94
291         for ($i = 0; $i < $max; ++$i) {
292                 $num = ord($allchars[0][$i]);  // \8ae\95\8e\9a\82Ì1\83o\83C\83g\96Ú\82ð\90\94\92l\82Æ\82µ\82Ä\8eæ\82è\8fo\82·
293                 if ($num2 = ord($allchars[1][$i])) { // 2\83o\83C\83g\96Ú\82ª\82 \82é\8fê\8d\87
294                         if ($mode != 1) {
295                                 $mode = 1;
296                                 $str_JIS .= chr(0x1b).'$B';
297                         }
298                         $shift = $mbemu_internals['sjistoeuc_byte1_shift'][$num2];
299                         $str_JIS .= chr(($mbemu_internals['sjistoeuc_byte1'][$num] + $shift) & 0x7F)
300                                            .chr($mbemu_internals['sjistoeuc_byte2'][$shift][$num2] & 0x7F);
301                 } elseif ($num > 0x80) {//\94¼\8ap\83J\83i
302                         if ($mode != 2) {
303                                 $mode = 2;
304                                 $str_JIS .= chr(0x1B).'(I';
305                         }
306                         $str_JIS .= chr($num & 0x7F);
307                 } else {//\94¼\8ap\89p\90\94
308                         if ($mode != 0) {
309                                 $mode = 0;
310                                 $str_JIS .= chr(0x1B).'(B';
311                         }
312                         $str_JIS .= chr($num);
313                 }
314         }
315         if ($mode != 0) {
316                 $str_JIS .= chr(0x1B).'(B';
317         }
318         return $str_JIS;
319 }
320
321 function _sub_jtosj($match)
322 {
323         global $mbemu_internals;
324         $num = ord($match[0]);
325         $num2 = ord($match[1]);
326         $s = chr($mbemu_internals['euctosjis_byte1'][$num | 0x80]);
327         if ($num & 1) {
328                 $s .= chr($mbemu_internals['euctosjis_byte2'][0][$num2 | 0x80]);
329         } else {
330                 $s .= chr($mbemu_internals['euctosjis_byte2'][1][$num2 | 0x80]);
331         }
332         return $s;
333 }
334
335 function _jistosjis(&$str)
336 {
337         global $mbemu_internals;
338         
339         $max = preg_match_all('/'.$mbemu_internals['regex'][3].'/', $str, $allchunks, PREG_SET_ORDER);  // \95\8e\9a\8eí\82²\82Æ\82Ì\94z\97ñ\82É\95ª\89ð
340         $st = '';
341         for ($i = 0; $i < $max; ++$i) {
342                 if (ord($allchunks[$i][1])) { //\89p\90\94\82É\83}\83b\83`
343                         $st .= $allchunks[$i][1];
344                 } elseif (ord($allchunks[$i][2])) { //\8a¿\8e\9a\82É\83}\83b\83`
345                         $tmp = substr($allchunks[$i][0], 3, strlen($allchunks[$i][0]));
346                         $st .= preg_replace_callback("/.(.)/","_sub_jtosj", $tmp);
347                 } elseif (ord($allchunks[$i][3])) { //\94¼\8ap\83J\83i\82É\83}\83b\83`
348                         $st .= preg_replace("/./e","chr(ord['$1'] | 0x80);",$allchunks[$i][3]);
349                 }
350         }
351         return $st;
352 }
353
354
355 function _ucs2utf8($uni)
356 {
357         if ($uni <= 0x7f)
358                 return chr($uni);
359         elseif ($uni <= 0x7ff) {
360                 $y = ($uni >> 6) & 0x1f;
361                 $x = $uni & 0x3f;
362                 return chr(0xc0 | $y).chr(0x80 | $x);
363         } else {
364                 $z = ($uni >> 12) & 0x0f;
365                 $y = ($uni >> 6) & 0x3f;
366                 $x = $uni & 0x3f;
367                 return chr(0xe0 | $z).chr(0x80 | $y).chr(0x80 | $x);
368         }
369 }
370
371 function _sjistoutf8(&$str)
372 {
373         global $mbemu_internals;
374         include_once(dirname(__FILE__).'/sjistouni.table');
375         $st = '';
376         $max = preg_match_all('/'.$mbemu_internals['regex'][2].'/', $str, $allchars);  // \95\8e\9a\82Ì\94z\97ñ\82É\95ª\89ð
377         for ($i = 0; $i < $max; ++$i) {
378                 $num = ord($allchars[0][$i]);  // \8ae\95\8e\9a\82Ì1\83o\83C\83g\96Ú\82ð\90\94\92l\82Æ\82µ\82Ä\8eæ\82è\8fo\82·
379                 if ($num2 = ord($allchars[1][$i])) { // 2\83o\83C\83g\96Ú\82ª\82 \82é\8fê\8d\87
380                         $ucs2 = $mbemu_internals['sjistoucs2'][($num << 8) | $num2];
381                         $st .= _ucs2utf8($ucs2);
382                 } elseif ($num > 0x80) {//\94¼\8ap\83J\83i
383                         $st .= _ucs2utf8(0xfec0 + $num);
384                 } else {//\94¼\8ap\89p\90\94
385                         $st .= chr($num);
386                 }
387         }
388         return $st;
389 }
390
391 function _utf8ucs2($st)
392 {
393         $num = ord($st);
394         if (!($num & 0x80)) //1byte
395                 return $num;
396         elseif (($num & 0xe0) == 0xc0) {//2bytes
397                 $num2 = ord(substr($st, 1,1));
398                 return (($num & 0x1f) << 6) | ($num2 & 0x3f);
399         } else  { //3bytes
400                 $num2 = ord(substr($st, 1,1));
401                 $num3 = ord(substr($st, 2,1));
402                 return (($num & 0x0f) << 12) | (($num2 & 0x3f) << 6) | ($num3 & 0x3f);
403         }
404 }
405
406 function _utf8tosjis(&$str)
407 {
408         global $mbemu_internals;
409         include_once(dirname(__FILE__).'/unitosjis.table');
410         $st = '';
411         $max = preg_match_all('/'.$mbemu_internals['regex'][4].'/', $str, $allchars);  // \95\8e\9a\82Ì\94z\97ñ\82É\95ª\89ð
412         for ($i = 0; $i < $max; ++$i) {
413                 $num = _utf8ucs2($allchars[0][$i]); //ucs2\82Ì\92l\82ð\8eæ\82è\8fo\82·
414                 if ($num < 0x80)
415                         $st .= chr($num);
416                 elseif ((0xff61 <= $num) && ($num <= 0xff9f))
417                         $st .= chr($num - 0xfec0);
418                 else {
419                         $sjis = $mbemu_internals['ucs2tosjis'][$num];
420                         $st .= chr($sjis >> 8) . chr($sjis & 0xff);
421                 }
422         }
423         return $st;
424 }
425
426 function _euctoutf8(&$str)
427 {
428         global $mbemu_internals;
429         include_once(dirname(__FILE__).'/sjistouni.table');
430         $st = '';
431         $max = preg_match_all('/'.$mbemu_internals['regex'][1].'/', $str, $allchars);  // \95\8e\9a\82Ì\94z\97ñ\82É\95ª\89ð
432         for ($i = 0; $i < $max; ++$i) {
433                 $num = ord($allchars[0][$i]);  // \8ae\95\8e\9a\82Ì1\83o\83C\83g\96Ú\82ð\90\94\92l\82Æ\82µ\82Ä\8eæ\82è\8fo\82·
434                 if ($num2 = ord($allchars[1][$i])) { // 2\83o\83C\83g\96Ú\82ª\82 \82é\8fê\8d\87
435                         if ($num & 1)
436                                 $sjis = ($mbemu_internals['euctosjis_byte1'][$num] << 8) | $mbemu_internals['euctosjis_byte2'][0][$num2];
437                         else
438                                 $sjis = ($mbemu_internals['euctosjis_byte1'][$num] << 8) | $mbemu_internals['euctosjis_byte2'][1][$num2];
439                         $st .= _ucs2utf8($mbemu_internals['sjistoucs2'][$sjis]);
440                 } elseif ($num3 = ord($allchars[2][$i])) {
441                         $st .= _ucs2utf8(0xfec0 + $num3);
442                 } else {//\94¼\8ap\89p\90\94
443                         $st .= chr($num);
444                 }
445         }
446         return $st;
447 }
448
449 function _utf8toeuc(&$str)
450 {
451         global $mbemu_internals;
452         include_once(dirname(__FILE__).'/unitosjis.table');
453         $st = '';
454         $max = preg_match_all('/'.$mbemu_internals['regex'][4].'/', $str, $allchars);  // \95\8e\9a\82Ì\94z\97ñ\82É\95ª\89ð
455         for ($i = 0; $i < $max; ++$i) {
456                 $num = _utf8ucs2($allchars[0][$i]); //ucs2\82Ì\92l\82ð\8eæ\82è\8fo\82·
457                 if ($num < 0x80)
458                         $st .= chr($num);
459                 elseif ((0xff61 <= $num) && ($num <= 0xff9f)) //\94¼\8ap\83J\83i
460                         $st .= chr(0x8e) . chr($num - 0xfec0);
461                 else {
462                         $sjis = $mbemu_internals['ucs2tosjis'][$num];
463                         $upper = $sjis >> 8;
464                         $lower = $sjis & 0xff;
465                         $shift = $mbemu_internals['sjistoeuc_byte1_shift'][$lower];
466                         $st .= chr($mbemu_internals['sjistoeuc_byte1'][$upper] + $shift)
467                                    .chr($mbemu_internals['sjistoeuc_byte2'][$shift][$lower]);
468                 }
469         }
470         return $st;
471 }
472
473 function _utf8toutf16(&$str)
474 {
475         global $mbemu_internals;
476         $st = '';
477         $max = preg_match_all('/'.$mbemu_internals['regex'][4].'/', $str, $allchars);  // \95\8e\9a\82Ì\94z\97ñ\82É\95ª\89ð
478         for ($i = 0; $i < $max; ++$i) {
479                 $num = _utf8ucs2($allchars[0][$i]); //ucs2\82Ì\92l\82ð\8eæ\82è\8fo\82·
480                 $st .= chr(($num >> 8) & 0xff).chr($num & 0xff);
481         }
482         return $st;
483 }
484
485 function _utf16toutf8(&$str)
486 {
487         global $mbemu_internals;
488         $st = '';
489         $ar = unpack("n*", $str);
490         foreach($ar as $char) {
491                 $st .= _ucs2utf8($char);
492         }
493         return $st;
494 }
495
496         
497 function sub_zenhan_EUC(&$str, $match) {
498         global $mbemu_internals;
499
500         $match = $match . "|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e[\xa0-\xdf]";
501         $max = preg_match_all("/$match/", $str, $chars);
502         $str = '';
503         for ($i = 0; $i < $max; ++$i) {
504                 if ($num = ord($chars[1][$i])) //\91S\8ap\82É\83}\83b\83`\83\93\83O\82µ\82½\8fê\8d\87
505                         $str .= chr(array_search($chars[1][$i], $mbemu_internals['alphanumeric_convert']));
506                 //      $str .= chr($num & 0x7F);
507                 else
508                         $str .= $chars[0][$i];
509         }
510 }
511
512 function sub_hanzen_EUC(&$str, $match) {
513         global $mbemu_internals;
514
515         $match = $match . "|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e[\xa0-\xdf]";
516         $max = preg_match_all("/$match/", $str, $chars);
517         $str = '';
518         for ($i = 0; $i < $max; ++$i) {
519                 if ($num = ord($chars[1][$i])) //\94¼\8ap\82É\83}\83b\83`\83\93\83O\82µ\82½\8fê\8d\87
520                         $str .= $mbemu_internals['alphanumeric_convert'][$num];
521                 else
522                         $str .= $chars[0][$i];
523         }
524 }
525
526 function alpha_zenhan_EUC(&$str) {
527         sub_zenhan_EUC($str, "(\xA3[\xC1-\xFA])");
528 }
529
530 function alpha_hanzen_EUC(&$str) {
531         sub_hanzen_EUC($str, "([\x41-\x5A,\x61-\x7A])");
532 }
533
534
535 function num_zenhan_EUC(&$str) {
536         sub_zenhan_EUC($str, "(\xA3[\xB0-\xB9])");
537 }
538
539 function num_hanzen_EUC(&$str) {
540         sub_hanzen_EUC($str, "([\x30-\x39])");
541 }
542
543 function alphanum_zenhan_EUC(&$str) {
544         sub_zenhan_EUC($str, "(\xa1[\xa4,\xa5,\xa7-\xaa,\xb0,\xb2,\xbf,\xc3,\xca,\xcb,\xce-\xd1,\xdc,\xdd,\xe1,\xe3,\xe4,\xf0,\xf3-\xf7]|\xA3[\xC1-\xFA]|\xA3[\xB0-\xB9])");
545 }
546
547 function alphanum_hanzen_EUC(&$str) {
548         sub_hanzen_EUC($str, "([\\\x21,\\\x23-\\\x26,\\\x28-\\\x5B,\\\x5D-\\\x7D])");
549 }
550
551
552 function space_zenhan_EUC(&$str) {
553         sub_zenhan_EUC($str, "(\xA1\xA1)");
554 }
555
556 function space_hanzen_EUC(&$str) {
557         sub_hanzen_EUC($str, "(\x20)");
558 }
559
560 function katakana_zenhan_EUC(&$str) {
561         global $mbemu_internals;
562
563         $match = "\xa5([\xa1-\xf4])|\xa1([\xa2,\xa3,\xa6,\xab,\xac,\xbc,\xd6,\xd7])|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e[\xa0-\xdf]";
564         $max = preg_match_all("/$match/", $str, $chars);
565         $str = '';
566         for ($i = 0; $i < $max; ++$i) {
567                 if ($num = ord($chars[1][$i])) //\83J\83i\82É\83}\83b\83`\83\93\83O\82µ\82½\8fê\8d\87
568                         $str .= chr(0x8e) . $mbemu_internals['kana_zenhan_convert'][$num];
569                 elseif ($num = ord($chars[2][$i])) //\94¼\8ap\95Ï\8a·\89Â\94\\82È\93Á\8eê\95\8e\9a\82É\83}\83b\83`\82µ\82½\8fê\8d\87
570                         $str .= chr(0x8e) . $mbemu_internals['special_zenhan_convert'][$num];
571                 else
572                         $str .= $chars[0][$i];
573         }
574 }
575
576 function hiragana_zenhan_EUC(&$str) {
577         global $mbemu_internals;
578
579         $match = "\xa4([\xa1-\xf4])|\xa1([\xa2,\xa3,\xa6,\xab,\xac,\xbc,\xd6,\xd7])|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e[\xa0-\xdf]";
580         $max = preg_match_all("/$match/", $str, $chars);
581         $str = '';
582         for ($i = 0; $i < $max; ++$i) {
583                 if ($num = ord($chars[1][$i])) //\82©\82È\82É\83}\83b\83`\83\93\83O\82µ\82½\8fê\8d\87
584                         $str .= chr(0x8e) . $mbemu_internals['kana_zenhan_convert'][$num];
585                 elseif ($num = ord($chars[2][$i])) //\94¼\8ap\95Ï\8a·\89Â\94\\82È\93Á\8eê\95\8e\9a\82É\83}\83b\83`\82µ\82½\8fê\8d\87
586                         $str .= chr(0x8e) . $mbemu_internals['special_zenhan_convert'][$num];
587                 else
588                         $str .= $chars[0][$i];
589         }
590 }
591
592 function katakana_hanzen1_EUC(&$str) {  //\91÷\93_\82Ì\93\9d\8d\87\82ð\82·\82é\95û
593         global $mbemu_internals;
594
595         $match = "\x8e((?:[\xb3,\xb6-\xc4,\xca-\xce]\x8e\xde)|(?:[\xca-\xce]\x8e\xdf))|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e([\xa1-\xdf])";
596                 //\91÷\93_\82â\94¼\91÷\93_\82Í\88ê\8f\8f\82É\83}\83b\83`\83\93\83O
597         $max = preg_match_all("/$match/", $str, $chars);
598         $str = '';
599         for ($i = 0; $i < $max; ++$i) {
600                 if ($chars[1][$i]) //\91÷\89¹\81C\94¼\91÷\89¹\82É\83}\83b\83`\83\93\83O\82µ\82½\8fê\8d\87
601                         $str .= chr(0xa5).chr(array_search($chars[1][$i], $mbemu_internals['kana_zenhan_convert']));
602                 elseif ($chars[2][$i]) //\82»\82Ì\91¼\82Ì\94¼\8ap\83J\83i\82É\83}\83b\83`
603                         if ($num = array_search($chars[2][$i], $mbemu_internals['kana_zenhan_convert']))
604                                 $str .= chr(0xa5).chr($num);
605                         else
606                                 $str .= chr(0xa1).chr(array_search($chars[2][$i], $mbemu_internals['special_zenhan_convert']));
607                 else
608                         $str .= $chars[0][$i];
609         }
610 }
611
612 function hiragana_hanzen1_EUC(&$str) {  //\91÷\93_\82Ì\93\9d\8d\87\82ð\82·\82é\95û
613         global $mbemu_internals;
614
615         $match = "\x8e((?:[\xb6-\xc4,\xca-\xce]\x8e\xde)|(?:[\xca-\xce]\x8e\xdf))|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e([\xa1-\xdf])";
616                 //\91÷\93_\82â\94¼\91÷\93_\82Í\88ê\8f\8f\82É\83}\83b\83`\83\93\83O
617         $max = preg_match_all("/$match/", $str, $chars);
618         $str = '';
619         for ($i = 0; $i < $max; ++$i) {
620                 if ($chars[1][$i]) //\91÷\89¹\81C\94¼\91÷\89¹\82É\83}\83b\83`\83\93\83O\82µ\82½\8fê\8d\87
621                         $str .= chr(0xa4).chr(array_search($chars[1][$i], $mbemu_internals['kana_zenhan_convert']));
622                 elseif ($chars[2][$i]) //\82»\82Ì\91¼\82Ì\94¼\8ap\83J\83i\82É\83}\83b\83`
623                         if ($num = array_search($chars[2][$i], $mbemu_internals['kana_zenhan_convert']))
624                                 $str .= chr(0xa4).chr($num);
625                         else
626                                 $str .= chr(0xa1).chr(array_search($chars[2][$i], $mbemu_internals['special_zenhan_convert']));
627                 else
628                         $str .= $chars[0][$i];
629         }
630 }
631
632 function katakana_hanzen2_EUC(&$str) {  //\91÷\93_\82Ì\93\9d\8d\87\82ð\82µ\82È\82¢\95û
633         global $mbemu_internals;
634
635         $match = "[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e([\xa1-\xdf])";
636         $max = preg_match_all("/$match/", $str, $chars);
637         $str = '';
638         for ($i = 0; $i < $max; ++$i) {
639                 if ($chars[1][$i]) //\94¼\8ap\83J\83i\82É\83}\83b\83`
640                         if ($num = array_search($chars[1][$i], $mbemu_internals['kana_zenhan_convert']))
641                                 $str .= chr(0xa5).chr($num);
642                         else
643                                 $str .= chr(0xa1).chr(array_search($chars[1][$i], $mbemu_internals['special_zenhan_convert']));
644                 else
645                         $str .= $chars[0][$i];
646         }
647 }
648
649 function hiragana_hanzen2_EUC(&$str) {  //\91÷\93_\82Ì\93\9d\8d\87\82ð\82µ\82È\82¢\95û
650         global $mbemu_internals;
651
652         $match = "[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e([\xa1-\xdf])";
653         $max = preg_match_all("/$match/", $str, $chars);
654         $str = '';
655         for ($i = 0; $i < $max; ++$i) {
656                 if ($chars[1][$i]) //\94¼\8ap\83J\83i\82É\83}\83b\83`
657                         if ($num = array_search($chars[1][$i], $mbemu_internals['kana_zenhan_convert']))
658                                 $str .= chr(0xa4).chr($num);
659                         else
660                                 $str .= chr(0xa1).chr(array_search($chars[1][$i], $mbemu_internals['special_zenhan_convert']));
661                 else
662                         $str .= $chars[0][$i];
663         }
664 }
665
666 function katakana_hiragana_EUC(&$str) {
667
668         $match = "\xa5([\xa1-\xf3])|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e[\xa0-\xdf]";
669         $max = preg_match_all("/$match/", $str, $chars);
670         $str = '';
671         for ($i = 0; $i < $max; ++$i) {
672                 if ($num = ord($chars[1][$i])) //\83J\83i\82É\83}\83b\83`\83\93\83O\82µ\82½\8fê\8d\87
673                         $str .= chr(0xa4) . chr($num);
674                 else
675                         $str .= $chars[0][$i];
676         }
677 }
678
679 function hiragana_katakana_EUC(&$str) {
680
681         $match = "\xa4([\xa1-\xf4])|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e[\xa0-\xdf]";
682         $max = preg_match_all("/$match/", $str, $chars);
683         $str = '';
684         for ($i = 0; $i < $max; ++$i) {
685                 if ($num = ord($chars[1][$i])) //\83J\83i\82É\83}\83b\83`\83\93\83O\82µ\82½\8fê\8d\87
686                         $str .= chr(0xa5) . chr($num);
687                 else
688                         $str .= $chars[0][$i];
689         }
690 }
691
692 function mb_convert_kana( $str, $option='KV', $encoding = '')
693 {
694         if (!$encoding) $encoding = mb_internal_encoding();
695         $str = mb_convert_encoding($str, 'EUC-JP', $encoding);
696
697         if (strstr($option, "r")) alpha_zenhan_EUC($str);
698         if (strstr($option, "R")) alpha_hanzen_EUC($str);
699         if (strstr($option, "n")) num_zenhan_EUC($str);
700         if (strstr($option, "N")) num_hanzen_EUC($str);
701         if (strstr($option, "a")) alphanum_zenhan_EUC($str);
702         if (strstr($option, "A")) alphanum_hanzen_EUC($str);
703         if (strstr($option, "s")) space_zenhan_EUC($str);
704         if (strstr($option, "S")) space_hanzen_EUC($str);
705         if (strstr($option, "k")) katakana_zenhan_EUC($str);
706         if (strstr($option, "K")) {
707                 if (strstr($option, "V"))
708                         katakana_hanzen1_EUC($str);
709                 else
710                         katakana_hanzen2_EUC($str);
711         }
712         if (strstr($option, "H")) {
713                 if (strstr($option, "V"))
714                         hiragana_hanzen1_EUC($str);
715                 else
716                         hiragana_hanzen2_EUC($str);
717         }
718         if (strstr($option, "h")) hiragana_zenhan_EUC($str);
719         if (strstr($option, "c")) katakana_hiragana_EUC($str);
720         if (strstr($option, "C")) hiragana_katakana_EUC($str);
721
722         $str = mb_convert_encoding($str, $encoding, 'EUC-JP');
723         return $str;
724 }
725
726 // if mb_language is uni this function send mail using UTF-8/Base64
727 // if English or en this function send mail using ISO-8859-1/quoted printable
728 // if Japanese this function send mail using ISO-2022-JP
729 function mb_send_mail($to, $subject, $message , $additional_headers='', $additional_parameter='')
730 {
731         switch (mb_language()) {
732                 case 'jp' :
733                 case 'ja' :
734                 case 'Japanese' :
735                         if (!_check_encoding($subject, 3)) //if not JIS encoded
736                                 $subject =mb_encode_mimeheader($subject);
737                         else {
738                                 $tmp = mb_internal_encoding();
739                                 mb_internal_encoding('iso-2022-jp');
740                                 $subject =mb_encode_mimeheader($subject);
741                                 mb_internal_encoding($tmp);
742                         }
743                         if (!_check_encoding($message, 3))
744                                 $message = mb_convert_encoding($message, "iso-2022-jp", mb_internal_encoding());
745                         $additional_headers .= 
746                         "\r\nMime-Version: 1.0\r\nContent-Type: text/plain; charset=ISO-2022-JP\r\nContent-Transfer-Encoding: 7bit";
747                         mail($to, $subject, $message, $additional_headers, $additional_parameter);
748                         break;
749                 case 'en' :
750                 case 'English' :
751                         $subject =mb_encode_mimeheader($subject, mb_internal_encoding(), 'Q');
752                         $message = _sub_encode_base64($message, mb_internal_encoding(), 76 , "\r\n");
753                         $additional_headers .= 
754                         "\r\nMime-Version: 1.0\r\nContent-Type: text/plain; charset=".
755                         mb_preferred_mime_name(mb_internal_encoding()).
756                         "\r\nContent-Transfer-Encoding: BASE64";
757                         mail($to, $subject, $message, $additional_headers, $additional_parameter); 
758                         break;
759                 case 'uni' :
760                         $subject =mb_encode_mimeheader($subject, mb_internal_encoding(), 'B');
761                         $message = _sub_encode_base64($message, mb_internal_encoding(), 76 , "\r\n");
762                         $additional_headers .= 
763                         "\r\nMime-Version: 1.0\r\nContent-Type: text/plain; charset=".
764                         mb_preferred_mime_name(mb_internal_encoding()).
765                         "\r\nContent-Transfer-Encoding: BASE64";
766                         mail($to, $subject, $message, $additional_headers, $additional_parameter); 
767                         break;
768         }
769         
770 }
771
772
773
774 function _check_encoding($str, $encoding_number)
775 {
776         global $mbemu_internals;
777         return (preg_match('/^('.$mbemu_internals['regex'][$encoding_number].')+$/', $str) == 1);
778 }
779
780 function mb_detect_encoding( $str , $encoding_list = '')
781 {
782         global $mbemu_internals;
783
784         if ($encoding_list == '') 
785                         $encoding_list = mb_detect_order();
786         if (!is_array($encoding_list)) {
787                 $encoding_list = strtoupper($encoding_list);
788                 if ($encoding_list == 'AUTO') {
789                         $encoding_list = mb_detect_order();
790                 } else {
791                         $encoding_list = split(', *', $encoding_list);
792                 }
793         }
794         foreach($encoding_list as $encode) {
795                 if (_check_encoding($str, $mbemu_internals['encoding'][$encode]))
796                         return $encode;
797         }
798         return $encode;
799 }
800
801 function mb_strlen ( $str , $encoding='')
802 {
803         global $mbemu_internals;
804
805         $encoding = mb_detect_encoding($str, $encoding);
806
807         switch ($e = $mbemu_internals['encoding'][$encoding]) {
808                 case 1 : //euc-jp
809                 case 2 : //shift-jis
810                 case 4 : //utf-8
811                         return preg_match_all('/'.$mbemu_internals['regex'][$e].'/', $str, $arr);
812                 case 5 : //utf-16
813                         return strlen($str) >> 1;
814                 case 0 : //ascii
815                 case 6 : //iso8859-1
816                         return strlen($str);
817                 case 3 : //jis
818                         $str = mb_convert_encoding($str, 'SJIS', 'JIS');
819                         return preg_match_all('/'.$mbemu_internals['regex'][2].'/', $str, $arr);
820         }
821 }
822
823 function mb_strwidth( $str, $encoding='')
824 {
825         global $mbemu_internals;
826
827         $encoding = mb_detect_encoding($str, $encoding);
828         switch ($e = $mbemu_internals['encoding'][$encoding]) {
829                 case 4 : //utf-8
830                         $max = $len = preg_match_all('/'.$mbemu_internals['regex'][4].'/', $str, $arr);
831                         for ($i=0; $i < $max; ++$i) {
832                                 $ucs2 = _utf8ucs2($arr[0][$i]);
833                                 if (((0x2000 <= $ucs2) && ($ucs2 <= 0xff60)) || (0xffa0 <= $ucs2))
834                                         ++$len;
835                         }
836                         return $len;
837                 case 1 : //euc-jp
838                 case 2 : //shift-jis
839                         $max = $len = preg_match_all('/'.$mbemu_internals['regex'][$e].'/', $str, $arr);
840                         for ($i=0; $i < $max; ++$i)
841                                 if ($arr[1][$i]) ++$len;
842                         return $len;
843                 case 5 : //utf-16
844                         $max = $len = preg_match_all('/'.$mbemu_internals['regex'][5].'/', $str, $arr);
845                         for ($i=0; $i < $max; ++$i) {
846                                 $ucs2 = (ord($arr[0][$i]) << 8) | ord(substr($arr[0][$i],1,1));
847                                 if (((0x2000 <= $ucs2) && ($ucs2 <= 0xff60)) || (0xffa0 <= $ucs2))
848                                         ++$len;
849                         }
850                         return $len;
851                 case 0 : //ascii
852                 case 6 : //iso8859-1
853                         return strlen($str);
854                 case 3 : //jis
855                         $str = mb_convert_encoding($str, 'SJIS', 'JIS');
856                         $max = $len = preg_match_all('/'.$mbemu_internals['regex'][2].'/', $str, $arr);
857                         for ($i=0; $i < $max; ++$i)
858                                 if ($arr[1][$i]) ++$len;
859                         return $len;
860         }
861 }
862
863 function mb_strimwidth( $str, $start, $width, $trimmarker , $encoding = '')
864 {
865         global $mbemu_internals;
866
867         $encoding = mb_detect_encoding($str, $encoding);
868         $str = mb_substr($str, $start, 'notnumber', $encoding);
869         if (($len = mb_strwidth($str,$encoding)) <= $width)
870                 return $str;
871         $trimwidth = mb_strwidth($trimmarker,$encoding);
872         $width -= $trimwidth;
873         if ($width <= 0) return $trimmarker;
874         
875         switch ($e = $mbemu_internals['encoding'][$encoding]) {
876                 case 0 : //ascii
877                 case 6 : //iso8859-1
878                         return substr($str, 0, $width).$trimmarker;
879                 case 4 : //utf-8
880                         preg_match_all('/'.$mbemu_internals['regex'][4].'/', $str, $arr);
881                         $i = 0;
882                         while(TRUE) {
883                                 $ucs2 = _utf8ucs2($arr[0][$i]);
884                                 if (((0x2000 <= $ucs2) && ($ucs2 <= 0xff60)) || (0xffa0 <= $ucs2))
885                                         $width -= 2;
886                                 else
887                                         --$width;
888                                 if ($width<0) break;
889                                 ++$i;
890                         }
891                         $arr[0] = array_slice($arr[0], 0, $i);
892                         return implode("", $arr[0]).$trimmarker;
893                 case 5 : //utf-16
894                         $arr = unpack("n*", $str);
895                         $i = 0;
896                         foreach($arr as $ucs2) {
897                                 if (((0x2000 <= $ucs2) && ($ucs2 <= 0xff60)) || (0xffa0 <= $ucs2))
898                                         $width -= 2;
899                                 else
900                                         --$width;
901                                 if ($width<0) break;
902                                 ++$i;
903                         }
904                         $arr[0] = array_slice($arr[0], 0, $i);
905                         return implode("", $arr[0]).$trimmarker;
906                 case 1 : //euc-jp
907                 case 2 : //shift-jis
908                         preg_match_all('/'.$mbemu_internals['regex'][$e].'/', $str, $arr);
909                         $i = 0;
910                         while(TRUE) {
911                                 if ($arr[1][$i])
912                                         $width -= 2;
913                                 else
914                                         --$width;
915                                 if ($width<0) break;
916                                 ++$i;
917                         }
918                         $arr[0] = array_slice($arr[0], 0, $i);
919                         return implode("", $arr[0]).$trimmarker;
920                 case 3 : //jis
921                         $str = mb_convert_encoding($str, 'SJIS', 'JIS');
922                         $trimmarker = mb_convert_encoding($trimmarker, 'SJIS', 'JIS');
923                         preg_match_all('/'.$mbemu_internals['regex'][2].'/', $str, $arr);
924                         $i = 0;
925                         while(TRUE) {
926                                 if ($arr[1][$i])
927                                         $width -= 2;
928                                 else
929                                         --$width;
930                                 if ($width<0) break;
931                                 ++$i;
932                         }
933                         $arr[0] = array_slice($arr[0], 0, $i);
934                         return mb_convert_encoding(implode("", $arr[0]).$trimmarker,'JIS','SJIS');
935         }
936 }
937
938
939 function mb_substr ( $str, $start , $length='notnumber' , $encoding='')
940 {
941         global $mbemu_internals;
942
943         $encoding = mb_detect_encoding($str, $encoding);
944
945         switch ($e = $mbemu_internals['encoding'][$encoding]) {
946                 case 0 : //ascii
947                 case 1 : //euc-jp
948                 case 2 : //shift-jis
949                 case 4 : //utf-8
950                 case 5 : //utf-16
951                 case 6 : //iso-8859-1
952                         preg_match_all('/'.$mbemu_internals['regex'][$e].'/', $str, $arr);
953                         break;
954                 case 3 : //jis
955                         $str = mb_convert_encoding($str, 'SJIS', 'JIS');
956                         preg_match_all('/'.$mbemu_internals['regex'][2].'/', $str, $arr);
957         }
958         if (is_int($length))
959                 $arr[0] = array_slice($arr[0], $start, $length);
960         else
961                 $arr[0] = array_slice($arr[0], $start);
962         $str = implode("", $arr[0]);
963         if ($mbemu_internals['encoding'][$encoding] == 3)
964                 $str = mb_convert_encoding($str, 'JIS', 'SJIS');
965         return $str;
966 }
967
968 function _sub_strcut($arr, $start, $length) {
969         $max = count($arr[0]);
970         $s = ''; $counter = 0;
971         for ($i = 0; $i < $max; ++$i) {
972                 $counter += strlen($arr[0][$i]);
973                 if ($counter > $start) {
974                         if ($length == 0) {
975                                 for ($j = $i; $j < $max; ++$j)
976                                         $s .= $arr[0][$j];
977                                 return $s;
978                         }
979                         for ($j = $i, $len = 0; $j < $max; ++$j) {
980                                 $len += strlen($arr[0][$j]);
981                                 if ($len <= $length)
982                                         $s .= $arr[0][$j];
983                         }
984                         return $s;
985                 }
986         }
987         return $s;
988 }
989
990
991 function mb_strcut ( $str, $start , $length=0 , $encoding = '')
992 {
993         global $mbemu_internals;
994         
995         $encoding = mb_detect_encoding($str, $encoding);
996
997         switch ($e = $mbemu_internals['encoding'][$encoding]) {
998                 case 0 : //ascii
999                 case 1 : //euc-jp
1000                 case 2 : //shift-jis
1001                 case 4 : //utf-8
1002                 case 5 : //utf-16
1003                 case 6 : //iso-8859-1
1004                         preg_match_all('/'.$mbemu_internals['regex'][$e].'/', $str, $arr);
1005                         return _sub_strcut($arr, $start, $length);
1006                 case 3 : //jis
1007                         $str = mb_convert_encoding($str, 'SJIS', 'JIS');
1008                         preg_match_all('/'.$mbemu_internals['regex'][2].'/', $str, $arr);
1009                         $sub = _sub_strcut($arr, $start, $length);
1010                         return mb_convert_encoding($sub, 'JIS', 'SJIS');
1011         }
1012 }
1013
1014 function _sub_strrpos($ar_haystack, $ar_needle)
1015 {
1016         $max_h = count($ar_haystack) - 1;
1017         $max_n = count($ar_needle) - 1;
1018         for ($i = $max_h; $i >= $max_n; --$i) {
1019                 if ($ar_haystack[$i] == $ar_needle[$max_n]) {
1020                         $match = TRUE;
1021                         for ($j = 1; $j <= $max_n; ++$j)
1022                                 if ($ar_haystack[$i-$j] != $ar_needle[$max_n-$j]) {
1023                                         $match = FALSE;
1024                                         break;
1025                                 }
1026                         if ($match) return $i - $max_n;
1027                 }
1028         }
1029         return FALSE;
1030 }
1031
1032 function mb_strrpos ( $haystack, $needle , $encoding = '')
1033 {
1034         
1035         global $mbemu_internals;
1036         
1037         $encoding = mb_detect_encoding($haystack, $encoding);
1038
1039         switch ($e = $mbemu_internals['encoding'][$encoding]) {
1040                 case 0 : //ascii
1041                 case 1 : //euc-jp
1042                 case 2 : //shift-jis
1043                 case 4 : //utf-8
1044                 case 5 : //utf-16
1045                 case 6 : //iso-8859-1
1046                         preg_match_all('/'.$mbemu_internals['regex'][$e].'/', $haystack, $ar_h);
1047                         preg_match_all('/'.$mbemu_internals['regex'][$e].'/', $needle, $ar_n);
1048                         return _sub_strrpos($ar_h[0], $ar_n[0]);
1049                 case 3 : //jis
1050                         $haystack = mb_convert_encoding($haystack, 'SJIS', 'JIS');
1051                         $needle = mb_convert_encoding($needle, 'SJIS', 'JIS');
1052                         preg_match_all('/'.$mbemu_internals['regex'][2].'/', $haystack, $ar_h);
1053                         preg_match_all('/'.$mbemu_internals['regex'][2].'/', $needle, $ar_n);
1054                         return _sub_strrpos($ar_h[0], $ar_n[0]);
1055         }
1056 }
1057
1058 function _sub_strpos($ar_haystack, $ar_needle, $offset)
1059 {
1060         $max_n = count($ar_needle) - 1;
1061         $max_h = count($ar_haystack) - count($ar_needle);
1062         for ($i = $offset; $i <= $max_h; ++$i) {
1063                 for ($j = 0; $j <= $max_n; ++$j) {
1064                         $match = TRUE;
1065                         if ($ar_haystack[$i+$j] != $ar_needle[$j]) {
1066                                 $match = FALSE;
1067                                 break;
1068                         }
1069                 }
1070                 if ($match) return $i;
1071         }
1072         return FALSE;
1073 }
1074
1075 function mb_strpos ( $haystack, $needle , $offset = 0, $encoding = '')
1076 {
1077         
1078         global $mbemu_internals;
1079         
1080         $encoding = mb_detect_encoding($haystack, $encoding);
1081
1082         switch ($e = $mbemu_internals['encoding'][$encoding]) {
1083                 case 0 : //ascii
1084                 case 1 : //euc-jp
1085                 case 2 : //shift-jis
1086                 case 4 : //utf-8
1087                 case 5 : //utf-16
1088                 case 6 : //iso-8859-1
1089                         preg_match_all('/'.$mbemu_internals['regex'][$e].'/', $haystack, $ar_h);
1090                         preg_match_all('/'.$mbemu_internals['regex'][$e].'/', $needle, $ar_n);
1091                         return _sub_strpos($ar_h[0], $ar_n[0], $offset);
1092                 case 3 : //jis
1093                         $haystack = mb_convert_encoding($haystack, 'SJIS', 'JIS');
1094                         $needle = mb_convert_encoding($needle, 'SJIS', 'JIS');
1095                         preg_match_all('/'.$mbemu_internals['regex'][2].'/', $haystack, $ar_h);
1096                         preg_match_all('/'.$mbemu_internals['regex'][2].'/', $needle, $ar_n);
1097                         return _sub_strpos($ar_h[0], $ar_n[0], $offset);
1098         }
1099 }
1100
1101 function _sub_substr_count($ar_haystack, $ar_needle)
1102 {
1103         $matches = 0;
1104         $max_n = count($ar_needle) - 1;
1105         $max_h = count($ar_haystack) - count($ar_needle);
1106         for ($i = 0; $i <= $max_h; ++$i) {
1107                 for ($j = 0; $j <= $max_n; ++$j) {
1108                         $match = TRUE;
1109                         if ($ar_haystack[$i+$j] != $ar_needle[$j]) {
1110                                 $match = FALSE;
1111                                 break;
1112                         }
1113                 }
1114                 if ($match) ++$matches;
1115         }
1116         return $matches;
1117 }
1118
1119 function mb_substr_count($haystack, $needle , $encoding = '')
1120 {
1121         
1122         global $mbemu_internals;
1123         
1124         $encoding = mb_detect_encoding($haystack, $encoding);
1125
1126         switch ($e = $mbemu_internals['encoding'][$encoding]) {
1127                 case 0 : //ascii
1128                 case 1 : //euc-jp
1129                 case 2 : //shift-jis
1130                 case 4 : //utf-8
1131                 case 5 : //utf-16
1132                 case 6 : //iso-8859-1
1133                         preg_match_all('/'.$mbemu_internals['regex'][$e].'/', $haystack, $ar_h);
1134                         preg_match_all('/'.$mbemu_internals['regex'][$e].'/', $needle, $ar_n);
1135                         return _sub_substr_count($ar_h[0], $ar_n[0]);
1136                 case 3 : //jis
1137                         $haystack = mb_convert_encoding($haystack, 'SJIS', 'JIS');
1138                         $needle = mb_convert_encoding($needle, 'SJIS', 'JIS');
1139                         preg_match_all('/'.$mbemu_internals['regex'][2].'/', $haystack, $ar_h);
1140                         preg_match_all('/'.$mbemu_internals['regex'][2].'/', $needle, $ar_n);
1141                         return _sub_substr_count($ar_h[0], $ar_n[0]);
1142         }
1143 }
1144
1145
1146 /******************
1147 mb_convert_variables
1148 *******************/
1149 if (!$mbemu_internals['ini_file']['convert_variables_arrayonly']) {
1150         function mb_convert_variables($to_encoding, $from_encoding, $s1, $s2='',$s3='',$s4='',$s5='',$s6='',$s7='', $s8='',$s9='', $s10='')
1151         {
1152                 if (is_array($s1)) {
1153                         $st = '';
1154                         foreach($s1 as $s) $st .= $s;
1155                         if (!($encode = mb_detect_encoding($st, $from_encoding)))
1156                                 return FALSE;
1157                         reset($s1);
1158                         while (list ($key, $val) = each ($s1)) {
1159                                 $s1[$key] = mb_convert_encoding($val, $to_encoding, $encode);
1160                         }
1161                         return $encode;
1162                 }
1163             $st = $s1.$s2.$s3.$s4.$s5.$s6.$s7.$s8.$s9.$s10;
1164             if (!($encode = mb_detect_encoding($st, $from_encoding)))
1165                 return FALSE;
1166             $s1 = mb_convert_encoding($s1, $to_encoding, $encode);
1167             $s2 = mb_convert_encoding($s2, $to_encoding, $encode);
1168             $s3 = mb_convert_encoding($s3, $to_encoding, $encode);
1169             $s4 = mb_convert_encoding($s4, $to_encoding, $encode);
1170             $s5 = mb_convert_encoding($s5, $to_encoding, $encode);
1171             $s6 = mb_convert_encoding($s6, $to_encoding, $encode);
1172             $s7 = mb_convert_encoding($s7, $to_encoding, $encode);
1173             $s8 = mb_convert_encoding($s8, $to_encoding, $encode);
1174             $s9 = mb_convert_encoding($s9, $to_encoding, $encode);
1175             $s10 = mb_convert_encoding($s10, $to_encoding, $encode);
1176             return $encode;
1177         }
1178 } else {
1179         function mb_convert_variables($to_encoding, $from_encoding, &$arr)
1180         {
1181                 $st = '';
1182                 foreach($arr as $s) $st .= $s;
1183                 if (!($encode = mb_detect_encoding($st, $from_encoding)))
1184                         return FALSE;
1185                 reset($arr);
1186                 while (list ($key, $val) = each ($arr)) {
1187                         $arr[$key] = mb_convert_encoding($val, $to_encoding, $encode);
1188                 }
1189                 return $encode;
1190         }
1191 }
1192
1193 function mb_preferred_mime_name ($encoding)
1194 {
1195         global $mbemu_internals;
1196         
1197         $encoding = strtoupper($encoding);
1198         
1199         switch ($mbemu_internals['encoding'][$encoding]) {
1200                 case 0 : //ascii
1201                         return 'US-ASCII';
1202                 case 1 : //euc-jp
1203                         return 'EUC-JP';
1204                 case 2 : //shift-jis
1205                         return 'Shift_JIS';
1206                 case 3 : //jis
1207                         return 'ISO-2022-JP';
1208                 case 4 : //utf-8
1209                         return 'UTF-8';
1210                 case 5 : 
1211                         return 'UTF-16';
1212                 case 6 :
1213                         return 'ISO-8859-1';
1214         }
1215 }
1216
1217 function mb_decode_mimeheader($str)
1218 {
1219         $lines = preg_split("/(\r\n|\r|\n)( *)/", $str);
1220         $s = '';
1221         foreach ($lines as $line) {
1222                 if ($line != "") {
1223                         $line = preg_replace("/<[\w\-+\.]+\@[\w\-+\.]+>/","", $line); //\83\81\81[\83\8b\81E\83A\83h\83\8c\83X\95\94\82ð\8fÁ\82·
1224                         $matches = preg_split("/=\?([^?]+)\?(B|Q)\?([^?]+)\?=/", $line, -1, PREG_SPLIT_DELIM_CAPTURE);
1225                         for ($i = 0; $i < count($matches)-1; $i+=4) {
1226                                 if (!preg_match("/^[ \t\r\n]*$/", $matches[$i]))
1227                                         $s .= $matches[$i];
1228                                 if ($matches[$i+2] == 'B')
1229                                         $s .= mb_convert_encoding(base64_decode($matches[$i+3]), 
1230                                                                                         mb_internal_encoding(), $matches[$i+1]);
1231                                 else
1232                                         $s .= mb_convert_encoding(quoted_printable_decode($matches[$i+3]), 
1233                                                                                         mb_internal_encoding(), $matches[$i+1]);
1234                         }
1235                         if (!preg_match("/^[ \t\r\n]*$/", $matches[$i]))
1236                                         $s .= $matches[$i];
1237                 }
1238         }
1239         return $s;
1240 }
1241
1242 function _sub_qponechar($str, &$len)
1243 {
1244         $all = unpack("C*", $str);
1245         $s = ''; $len = 0;
1246         foreach($all as $char) {
1247                 if (((ord('A') <= $char) && ($char <= ord('Z'))) ||
1248                         ((ord('a') <= $char) && ($char <= ord('z')))) {
1249                         $s .= chr($char);
1250                         ++$len;
1251                 } else {
1252                         $s .= '='.sprintf("%2X",$char);
1253                         $len += 3;
1254                 }
1255         }
1256         return $s;
1257 }
1258
1259 function _sub_quoted_printable_encode($str, $encoding, $maxline, $linefeed)
1260 {
1261         global $mbemu_internals;
1262         switch ($e = $mbemu_internals['encoding'][$encoding]) {
1263                 case 0 : //ascii
1264                 case 1 : //euc-jp
1265                 case 2 : //shift-jis
1266                 case 4 : //utf-8
1267                         $max = preg_match_all('/'.$mbemu_internals['regex'][$e].'/', $str, $allchars);
1268                         break;
1269                 case 3 : //jis
1270                         $max = preg_match_all('/'.$mbemu_internals['regex'][3].'/', $str, $allchunks, PREG_SET_ORDER);  // \95\8e\9a\8eí\82²\82Æ\82Ì\94z\97ñ\82É\95ª\89ð
1271                         $st = ''; // quoted printable\95Ï\8a·\8cã\82Ì\95\8e\9a\97ñ
1272                         $len = $maxline;  // \82»\82Ì\8ds\82É\92Ç\89Á\89Â\94\\82È\83o\83C\83g\90\94
1273                         $needterminate = FALSE; //\8dÅ\8cã\82É\83G\83X\83P\81[\83v\83V\81[\83P\83\93\83X\82ª\95K\97v\82©\82Ç\82¤\82©
1274                         for ($i = 0; $i < $max; ++$i) {
1275                                 if (ord($allchunks[$i][1])) { //\89p\90\94\82É\83}\83b\83`
1276                                         if ($needterminate) {
1277                                                 $st .= '=1B=28B';
1278                                                 $len -= 7;
1279                                         }
1280                                         $tmparr = unpack("C*", $allchunks[$i][1]);
1281                                         foreach ($tmparr as $char) {
1282                                                 $tmp = _sub_qponechar(chr($char), $l);
1283                                                 if ($len < $l) {
1284                                                         $st .= $linefeed;
1285                                                         $len = $maxline;
1286                                                 }
1287                                                 $st .= $tmp;
1288                                                 $len -= $l;
1289                                         } 
1290                                         $needterminate = FALSE;
1291                                 } elseif (ord($allchunks[$i][2])) { //\8a¿\8e\9a\82É\83}\83b\83`
1292                                         $maxchars = preg_match_all("/../",substr($allchunks[$i][0], 3),$allchars);
1293                                         $tmp = _sub_qponechar($allchars[0][0], $l);
1294                                         if ($len < 14 + $l) {
1295                                                 if ($needterminate)
1296                                                         $st .= '=1B=28B';
1297                                                 $st .= $linefeed;
1298                                                 $len = $maxline;
1299                                         }
1300                                         $st .= '=1B=24B';
1301                                         $len -= 7;
1302                                         for ($j = 0; $j < $maxchars; ++$j) {
1303                                                 $tmp = _sub_qponechar($allchars[0][$j], $l);
1304                                                 if ($len < $l + 7) {
1305                                                         $st .= '=1B=28B'.$linefeed.'=1B=24B';
1306                                                         $len = $maxline-7;
1307                                                 }
1308                                                 $st .= $tmp;
1309                                                 $len -= $l;
1310                                         }
1311                                         $needterminate = TRUE;
1312                                         
1313                                 } elseif (ord($allchunks[$i][3])) { //\94¼\8ap\83J\83i\82É\83}\83b\83`
1314                                         $max = preg_match_all("/./",$allchunks[$i][3],$allchars);
1315                                         $tmp = _sub_qponechar($allchars[0][0], $l);
1316                                         if ($len < 14 + $l) {
1317                                                 if ($needterminate)
1318                                                         $st .= '=1B=28B';
1319                                                 $st .= $linefeed;
1320                                                 $len = $maxline;
1321                                         }
1322                                         $st .= '=1B=28I';
1323                                         $len -= 7;
1324                                         for ($j == 0; $j < $max; ++$j) {
1325                                                 $tmp = _sub_qponechar($allchars[0][$j], $l);
1326                                                 if ($len < $l + 7) {
1327                                                         $st .= '=1B=28B'.$linefeed.'=1B=28I';
1328                                                         $len = $maxline-7;
1329                                                 }
1330                                                 $st .= $tmp;
1331                                                 $len -= $l;
1332                                         }
1333                                         $needterminate = TRUE;
1334                                 }
1335                         }
1336                         if ($needterminate) $st .= '=1B=28B';
1337                         $st .= $linefeed;
1338                         return $st;
1339         }
1340         $st = ''; // quoted printable\95Ï\8a·\8cã\82Ì\95\8e\9a\97ñ
1341         $len = $maxline;  // \82»\82Ì\8ds\82É\92Ç\89Á\89Â\94\\82È\83o\83C\83g\90\94
1342         for ($i = 0; $i < $max; ++$i) {
1343                 $tmp = _sub_qponechar($allchars[0][$i], $l);
1344                 if ($l > $len) {
1345                         $st .= $linefeed;
1346                         $len = $maxline;
1347                 }
1348                 $st .= $tmp;
1349                 $len -= $l;
1350         }
1351         $st .= $linefeed;
1352         return $st;
1353 }
1354
1355 function _sub_encode_base64($str, $encoding, $maxline , $linefeed)
1356 {
1357         global $mbemu_internals;
1358         switch ($e = $mbemu_internals['encoding'][$encoding]) {
1359                 case 0 : //ascii
1360                 case 6 : //iso-8859-1
1361                         return chunk_split( base64_encode($str) , $maxline, $linefeed);
1362                 case 1 : //euc-jp
1363                 case 2 : //shift-jis
1364                 case 4 : //utf-8
1365                 case 5 : //utf-16
1366                         $max = preg_match_all('/'.$mbemu_internals['regex'][$e].'/', $str, $allchars);
1367                         break;
1368                 case 3 : //jis
1369                         $max = preg_match_all('/'.$mbemu_internals['regex'][3].'/', $str, $allchunks);  // \95\8e\9a\8eí\82²\82Æ\82Ì\94z\97ñ\82É\95ª\89ð
1370                         $st = ''; // BASE64\95Ï\8a·\8cã\82Ì\95\8e\9a\97ñ
1371                         $maxbytes = floor($maxline * 3 / 4);  //1\8ds\82É\95Ï\8a·\89Â\94\\82È\83o\83C\83g\90\94
1372                         $len = $maxbytes;  // \82»\82Ì\8ds\82É\92Ç\89Á\89Â\94\\82È\83o\83C\83g\90\94
1373                         $line = '';  //1\8ds\95ª\82Ì\95Ï\8a·\91O\82Ì\95\8e\9a\97ñ
1374                         $needterminate = FALSE; //\8dÅ\8cã\82É\83G\83X\83P\81[\83v\83V\81[\83P\83\93\83X\82ª\95K\97v\82©\82Ç\82¤\82©
1375                         for ($i = 0; $i < $max; ++$i) {
1376                                 if (ord($allchunks[1][$i])) { //\89p\90\94\82É\83}\83b\83`
1377                                         if ($needterminate) {
1378                                                 $line .= chr(0x1B).'(B';
1379                                                 $len -= 3;
1380                                         }
1381                                         $tmpstr = $allchunks[1][$i];  //\92Ç\89Á\82·\82é\95\8e\9a\97ñ
1382                                         $l = strlen($tmpstr);  //\92Ç\89Á\82·\82é\95\8e\9a\97ñ\82Ì\92·\82³
1383                                         while ($l > $len) {
1384                                                 $line .= substr($tmpstr, 0, $len);
1385                                                 $st .= base64_encode($line).$linefeed;
1386                                                 $l -= $len;
1387                                                 $tmpstr = substr($tmpstr, $len);
1388                                                 $len = $maxbytes;
1389                                                 $line = '';
1390                                         } 
1391                                         $line .= $tmpstr;
1392                                         $len -= $l;
1393                                         $needterminate = FALSE;
1394                                 } elseif (ord($allchunks[2][$i])) { //\8a¿\8e\9a\82É\83}\83b\83`
1395                                         $tmpstr = substr($allchunks[0][$i], 3);
1396                                         if ($len < 8) { //\95\8e\9a\82ð\92Ç\89Á\82·\82é\82Ì\82É\8dÅ\92á8\83o\83C\83g\95K\97v\82È\82Ì\82Å
1397                                                 if ($needterminate)
1398                                                         $line .= chr(0x1B).'(B';
1399                                                 $st .= base64_encode($line).$linefeed;
1400                                                 $len = $maxbytes;
1401                                                 $line = '';
1402                                         }
1403                                         $l = strlen($tmpstr);
1404                                         $line .= chr(0x1B).'$B';
1405                                         $len -= 3; 
1406                                         while ($l > $len-3) {
1407                                                 $add = floor(($len-3) / 2) * 2;
1408                                                 if ($add == 0) break;
1409                                                 $line .= substr($tmpstr, 0, $add).chr(0x1B).'(B';
1410                                                 $st .= base64_encode($line).$linefeed;
1411                                                 $l -= $add;
1412                                                 $tmpstr = substr($tmpstr, $add);
1413                                                 $len = $maxbytes-3;
1414                                                 $line = chr(0x1B).'$B';
1415                                         } 
1416                                         $line .= $tmpstr;
1417                                         $len -= $l;
1418                                         $needterminate = TRUE;
1419                                         
1420                                 } elseif (ord($allchunks[3][$i])) { //\94¼\8ap\83J\83i\82É\83}\83b\83`
1421                                         $tmpstr = $allchunks[3][$i];
1422                                         if ($len < 7) { //\95\8e\9a\82ð\92Ç\89Á\82·\82é\82Ì\82É\8dÅ\92á7\83o\83C\83g\95K\97v\82È\82Ì\82Å
1423                                                 if ($needterminate)
1424                                                         $line .= chr(0x1B).'(B';
1425                                                 $st .= base64_encode($line).$linefeed;
1426                                                 $len = $maxbytes;
1427                                                 $line = '';
1428                                         }
1429                                         $l = strlen($tmpstr);
1430                                         $line .= chr(0x1B).'(I';
1431                                         $len -= 3; 
1432                                         while ($l > $len-3) {
1433                                                 $line .= substr($tmpstr, 0, $len-3).chr(0x1B).'(B';
1434                                                 $st .= base64_encode($line).$linefeed;
1435                                                 $l -= $len;
1436                                                 $tmpstr = substr($tmpstr, $len-3);
1437                                                 $len = $maxbytes-3;
1438                                                 $line = chr(0x1B).'(I';
1439                                         } 
1440                                         $line .= $tmpstr;
1441                                         $len -= $l;
1442                                         $needterminate = TRUE;
1443                                 }
1444                         }
1445                         if ($needterminate) $line .= chr(0x1B).'(B';
1446                         $st .= base64_encode($line).$linefeed;
1447                         return $st;
1448         }
1449         $st = ''; // BASE64\95Ï\8a·\8cã\82Ì\95\8e\9a\97ñ
1450         $maxbytes = floor($maxline * 3 / 4);  //1\8ds\82É\95Ï\8a·\89Â\94\\82È\83o\83C\83g\90\94
1451         $len = $maxbytes;  // \82»\82Ì\8ds\82É\92Ç\89Á\89Â\94\\82È\83o\83C\83g\90\94
1452         $line = '';  //1\8ds\95ª\82Ì\95Ï\8a·\91O\82Ì\95\8e\9a\97ñ
1453         for ($i = 0; $i < $max; ++$i) {
1454                 $l = strlen($allchars[0][$i]);
1455                 if ($l > $len) {
1456                         $st .= base64_encode($line).$linefeed;
1457                         $len = $maxbytes;
1458                         $line = '';
1459                 }
1460                 $line .= $allchars[0][$i];
1461                 $len -= $l;
1462         }
1463         $st .= base64_encode($line).$linefeed;
1464         return $st;
1465 }
1466
1467 function mb_encode_mimeheader( $str, $encoding = "ISO-2022-JP", $transfer_encoding = "B", $linefeed = "\r\n")
1468 {
1469         global $mbemu_internals;
1470         if ($transfer_encoding == "b") $transfer_encoding = "B";
1471         if ($transfer_encoding <> "B") $transfer_encoding = "Q";
1472         $encoding = strtoupper($encoding);
1473         
1474         $head = '=?' . mb_preferred_mime_name ($encoding) . '?'.$transfer_encoding.'?';
1475         $str = mb_convert_encoding($str, $encoding, mb_internal_encoding());
1476         $length = 76 - strlen($head) - 4;
1477         if ($transfer_encoding == "B") {
1478         $str = _sub_encode_base64( $str , $encoding, $length, $linefeed);
1479         } else {
1480                 $str = _sub_quoted_printable_encode($str, $encoding, $length, $linefeed);
1481         }
1482         $ar = explode($linefeed, $str);
1483         $s = '';
1484         foreach ($ar as $element) {
1485                 if ($element <> '')
1486                         $s .= $head . $element . '?=' .$linefeed;
1487         }
1488         return $s;
1489 }
1490
1491 function mb_http_input($type = '')
1492 {
1493         return FALSE;
1494 }
1495
1496 function mb_http_output($encoding = '')
1497 {
1498         global $mbemu_internals;
1499         
1500         if ($encoding == '') return $mbemu_internals['ini_file']['http_output'];
1501         if (strtolower($encoding) == 'pass') {
1502                 $mbemu_internals['ini_file']['http_output'] = 'pass';
1503                 return TRUE;
1504         }
1505         $mbemu_internals['ini_file']['http_output'] = mb_preferred_mime_name($encoding);
1506         return TRUE;
1507 }
1508
1509
1510 function mb_output_handler ( $buffer, $status='')
1511 {
1512         global $mbemu_internals;
1513         if ($mbemu_internals['ini_file']['http_output'] == 'pass')
1514                 return $buffer;
1515         return mb_convert_encoding($buffer, $mbemu_internals['ini_file']['http_output'], mb_internal_encoding());
1516 }
1517
1518
1519 function mb_encode_numericentity($str, $convmap, $encoding="")
1520 {
1521         if (!$encoding) $encoding = mb_internal_encoding();
1522         $str = mb_convert_encoding($str, "utf-16", $encoding);
1523         $ar = unpack("n*", $str);
1524         $s = "";
1525         foreach($ar as $char) {
1526                 $max = count($convmap);
1527                 for ($i = 0; $i < $max; $i += 4) {
1528                         if (($convmap[$i] <= $char) && ($char <= $convmap[$i+1])) {
1529                                 $char += $convmap[$i+2];
1530                                 $char &= $convmap[$i+3];
1531                                 $s .= sprintf("&#%u;", $char);
1532                                 break;
1533                         }
1534                 }
1535                 if ($i >= $max) $s .= pack("n*", $char);
1536         }
1537         return $s;
1538 }
1539
1540 function mb_decode_numericentity ($str, $convmap, $encoding="")
1541 {
1542         if (!$encoding) $encoding = mb_internal_encoding();
1543         $ar = preg_split('/(&#[0-9]+;)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
1544         $s = '';
1545         $max = count($convmap);
1546         foreach($ar as $chunk) {
1547                 if (preg_match('/&#([0-9]+);/', $chunk, $match)) {
1548                         for ($i = 0; $i < $max; $i += 4) {
1549                                 $num = $match[1] - $convmap[$i+2];
1550                                 if (($convmap[$i] <= $num) && ($num <= $convmap[$i+1])) {
1551                                         $ucs2 = pack('n*', $num);
1552                                         $s .= mb_convert_encoding($ucs2, $encoding, 'UTF-16');
1553                                         break;
1554                                 }
1555                         }
1556                         if ($i >= $max) $s .= $chunk;
1557                 } else {
1558                         $s .= $chunk;
1559                 }
1560         }
1561         return $s;
1562 }
1563
1564 function mb_strtoupper($str, $encoding='')
1565 {
1566         global $mbemu_internals;
1567
1568         include_once(dirname(__FILE__).'/upper.table');
1569         $encoding = mb_detect_encoding($str, $encoding);
1570         $str = mb_convert_encoding($str, 'UTF-8', $encoding);
1571
1572         $max = preg_match_all('/'.$mbemu_internals['regex'][4].'/', $str, $allchars);  // make array of chars
1573         $newst = '';
1574         for ($i = 0; $i < $max; ++$i) {
1575                 $val = _utf8ucs2($allchars[0][$i]); //get ucs2 value
1576                 if ((0x61 <= $val) && ($val <= 0x7a)) {
1577                         $val -= 0x20;
1578                         $newst .= _ucs2utf8($val);
1579                 } elseif ($upper = $mbemu_internals['upperarray'][$val]) {
1580                         $newst .= _ucs2utf8($upper);
1581                 } else {
1582                         $newst .= $allchars[0][$i];
1583                 }
1584         }
1585         return mb_convert_encoding($newst, $encoding, 'UTF-8');
1586 }
1587
1588 function mb_strtolower($str, $encoding='')
1589 {
1590         global $mbemu_internals;
1591
1592         include_once(dirname(__FILE__).'/lower.table');
1593         $encoding = mb_detect_encoding($str, $encoding);
1594         $str = mb_convert_encoding($str, 'UTF-8', $encoding);
1595
1596         $max = preg_match_all('/'.$mbemu_internals['regex'][4].'/', $str, $allchars);  // make array of chars
1597         $newst = '';
1598         for ($i = 0; $i < $max; ++$i) {
1599                 $val = _utf8ucs2($allchars[0][$i]); //get ucs2 value
1600                 if ((0x41 <= $val) && ($val <= 0x5a)) {
1601                         $val += 0x20;
1602                         $newst .= _ucs2utf8($val);
1603                 } elseif ($lower = $mbemu_internals['lowerarray'][$val]) {
1604                         $newst .= _ucs2utf8($lower);
1605                 } else {
1606                         $newst .= $allchars[0][$i];
1607                 }
1608         }
1609         return mb_convert_encoding($newst, $encoding, 'UTF-8');
1610 }
1611
1612 function mb_convert_case($str, $case, $encoding='')
1613 {
1614         global $mbemu_internals;
1615         
1616         switch($case) {
1617                 case MB_CASE_UPPER :
1618                         return mb_strtoupper($str, $encoding);
1619                 case MB_CASE_LOWER :
1620                         return mb_strtolower($str, $encoding);
1621                 case MB_CASE_TITLE :
1622                         include_once(dirname(__FILE__).'/upper.table');
1623                         include_once(dirname(__FILE__).'/lower.table');
1624                         $encoding = mb_detect_encoding($str, $encoding);
1625                         $str = mb_convert_encoding($str, 'UTF-8', $encoding);
1626
1627                         $max = preg_match_all('/'.$mbemu_internals['regex'][4].'/', $str, $allchars);  // make array of chars
1628                         $newst = '';
1629                         $isalpha = FALSE;
1630                         for ($i = 0; $i < $max; ++$i) {
1631                                 $val = _utf8ucs2($allchars[0][$i]); //get ucs2 value
1632                                 if ((0x41 <= $val) && ($val <= 0x5a)) {
1633                                         if ($isalpha) {
1634                                                 $val += 0x20; // to lower;
1635                                         } else {
1636                                                 $isalpha = TRUE;
1637                                         }
1638                                         $newst .= _ucs2utf8($val);
1639                                 } elseif ((0x61 <= $val) && ($val <= 0x7a)){
1640                                         if (!$isalpha) {
1641                                                 $val -= 0x20; // to upper
1642                                                 $isalpha = TRUE;
1643                                         }
1644                                         $newst .= _ucs2utf8($val);
1645                                 } elseif ($upper = $mbemu_internals['upperarray'][$val]) { // this char is lower
1646                                         if ($isalpha) {
1647                                                 $newst .= _ucs2utf8($val);
1648                                         } else {
1649                                                 $isalpha = TRUE;
1650                                                 $newst .= _ucs2utf8($upper);
1651                                         }
1652                                 } elseif ($lower = $mbemu_internals['lowerarray'][$val]) { // this char is upper
1653                                         if ($isalpha) {
1654                                                 $newst .= _ucs2utf8($lower);
1655                                         } else {
1656                                                 $isalpha = TRUE;
1657                                                 $newst .= _ucs2utf8($val);
1658                                         }
1659                                 } else {
1660                                         $isalpha = FALSE;
1661                                         $newst .= $allchars[0][$i];
1662                                 }
1663                         }
1664                         return mb_convert_encoding($newst, $encoding, 'UTF-8');
1665         }
1666 }
1667
1668
1669 function _print_str($str) {
1670         $all = unpack("C*", $str);
1671         $s = '';
1672         foreach($all as $char) {
1673                 $s .= sprintf(" %2X",$char);
1674         }
1675         print $s."\n";
1676 }
1677
1678 ?>