<?php

/*
	[DISCUZ!] wap/include/chinese.class.php - chinese multi-byte convertion
	This is NOT a freeware, use is subject to license terms

	Version: 1.5.0
	Web: http://www.comsenz.com
	Copyright: 2003 Hessian / NETiS, 2005 Comsenz Technology Ltd.
	Last Modified: 2005-2-28 10:15
*/

if(!defined('IN_DISCUZ')) {
        exit('Access Denied');
}

class Chinese {

	var $table = '';
	var $unicode_table = array();
	var $config  =  array
		(
		'SourceLang'            => '',                    //  字符的原编码
		'TargetLang'            => '',                    //  转换后的编码
		'codetable_dir'         => './tables/',           //  存放各种语言互换表的目录
		'GBtoUnicode_table'     => 'gb-unicode.table',    //  简体中文转换为UNICODE的对照表
		'BIG5toUnicode_table'   => 'big5-unicode.table'   //  繁体中文转换为UNICODE的对照表
		);

	function Chinese($SourceLang, $TargetLang) {
		$this->config['SourceLang'] = $this->_lang($SourceLang);
		$this->config['TargetLang'] = $this->_lang($TargetLang);
		$this->OpenTable();
	}

	function _lang($LangCode) {
		if(strtoupper(substr($LangCode, 0, 2)) == 'GB') {
			return 'GB2312';
		} elseif(strtoupper(substr($LangCode, 0, 3)) == 'BIG') {
			return 'BIG5';
		} elseif(strtoupper(substr($LangCode, 0, 3)) == 'UTF') {
			return 'UTF8';
		} elseif(strtoupper(substr($LangCode, 0, 3)) == 'UNI') {
			return 'UNICODE';
		}
	}

	function _hex2bin($hexdata) {
		for($i=0; $i < strlen($hexdata); $i += 2) {
			$bindata .= chr(hexdec(substr($hexdata, $i, 2)));
		}
		return $bindata;
	}

	function OpenTable() {
		$this->unicode_table = array();
		$this->table = $this->config['codetable_dir'];
		if($this->config['SourceLang'] == 'GB2312' || $this->config['TargetLang'] == 'GB2312') {
			$this->table .= $this->config['GBtoUnicode_table'];
		} elseif($this->config['SourceLang'] == 'BIG5' || $this->config['TargetLang'] == 'BIG5') {
			$this->table .= $this->config['BIG5toUnicode_table'];
		}
		$fp = fopen($this->table, 'rb');
		$tabletmp = fread($fp, filesize($this->table));
		for($i = 0; $i < strlen($tabletmp); $i += 4) {
			$tmp = unpack('nkey/nvalue', substr($tabletmp, $i, 4));
			if($this->config['TargetLang'] == 'UTF8') {
				$this->unicode_table[$tmp['key']] = '0x'.dechex($tmp['value']);
			} elseif($this->config['SourceLang'] == 'UTF8') {
				$this->unicode_table[$tmp['value']] = '0x'.dechex($tmp['key']);
			} elseif($this->config['TargetLang'] == 'UNICODE') {
				$this->unicode_table[$tmp['key']] = dechex($tmp['value']);
			}
		}
	}

	function CHSUtoUTF8($c) {
		$str = '';
		if($c < 0x80) {
			$str .= $c;
		} elseif($c < 0x800) {
			$str .= (0xC0 | $c >> 6);
			$str .= (0x80 | $c & 0x3F);
		} elseif($c < 0x10000) {
			$str .= (0xE0 | $c >> 12);
			$str .= (0x80 | $c >> 6 & 0x3F);
			$str .=( 0x80 | $c & 0x3F);
		} elseif ($c < 0x200000) {
			$str .= (0xF0 | $c >> 18);
			$str .= (0x80 | $c >> 12 & 0x3F);
			$str .= (0x80 | $c >> 6 & 0x3F);
			$str .= (0x80 | $c & 0x3F);
		}
		return $str;
	}

	function Convert($SourceText) {
		if($this->config['SourceLang'] == $this->config['TargetLang']) {
			return $SourceText;
		} elseif($this->config['TargetLang'] == 'UNICODE') {
			$utf = '';
			while($SourceText) {
				if(ord(substr($SourceText, 0, 1)) > 127) {
					if ($this->config['SourceLang'] == 'GB2312') {
						$utf .= '&#x'.$this->unicode_table[hexdec(bin2hex(substr($SourceText, 0, 2))) - 0x8080].';';
					} elseif($this->config['SourceLang'] == 'BIG5') {
						$utf .= '&#x'.$this->unicode_table[hexdec(bin2hex(substr($SourceText, 0, 2)))].';';
					}
					$SourceText = substr($SourceText, 2, strlen($SourceText));
				} else {
					$utf .= substr($SourceText, 0, 1);
					$SourceText = substr($SourceText, 1, strlen($SourceText));
				}
			}
			return $utf;
		} else {
			$ret = '';
			if($this->config['SourceLang'] == 'UTF8') {
				$out = '';
				$len = strlen($SourceText);
				$i = 0;
				while($i < $len) {
					$c = ord(substr($SourceText, $i++, 1));
					switch($c >> 4) {
						case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
							$out .= substr($SourceText, $i - 1, 1);
							break;
						case 12: case 13:
							$char2 = ord(substr($SourceText, $i++, 1));
							$char3 = $this->unicode_table[(($c & 0x1F) << 6) | ($char2 & 0x3F)];
							if($this->config['TargetLang'] == 'GB2312') {
								$out .= $this->_hex2bin(dechex($char3 + 0x8080));
							} elseif($this->config['TargetLang'] == 'BIG5') {
								$out .= $this->_hex2bin($char3);
							}
							break;
						case 14:
							$char2 = ord(substr($SourceText, $i++, 1));
							$char3 = ord(substr($SourceText, $i++, 1));
							$char4 = $this->unicode_table[(($c & 0x0F) << 12) | (($char2 & 0x3F) << 6) | (($char3 & 0x3F) << 0)];
							if ($this->config['TargetLang'] == 'GB2312') {
								$out .= $this->_hex2bin(dechex($char4 + 0x8080));
							} elseif($this->config['TargetLang'] == 'BIG5') {
								$out .= $this->_hex2bin($char4);
							}
							break;
					}
				}
				return $out;
			} else {
				while($SourceText) {
					if(ord(substr($SourceText, 0, 1)) > 127){
						if($this->config['SourceLang'] == 'BIG5') {
							$utf8 = $this->CHSUtoUTF8(hexdec($this->unicode_table[hexdec(bin2hex(substr($SourceText, 0, 2)))]));
						} elseif($this->config['SourceLang'] == 'GB2312') {
							$utf8=$this->CHSUtoUTF8(hexdec($this->unicode_table[hexdec(bin2hex(substr($SourceText, 0, 2))) - 0x8080]));
						}
						for($i = 0; $i < strlen($utf8); $i += 3) {
							$ret .= chr(substr($utf8, $i, 3));
						}
						$SourceText = substr($SourceText, 2, strlen($SourceText));
					} else {
						$ret .= substr($SourceText, 0, 1);
						$SourceText = substr($SourceText, 1, strlen($SourceText));
					}
				}
				$this->unicode_table = array();
				$SourceText = '';
				return $ret;
			}
		}
	}
}

?>
