summaryrefslogtreecommitdiff
path: root/program/lib/utf8.class.php
diff options
context:
space:
mode:
Diffstat (limited to 'program/lib/utf8.class.php')
-rw-r--r--program/lib/utf8.class.php173
1 files changed, 173 insertions, 0 deletions
diff --git a/program/lib/utf8.class.php b/program/lib/utf8.class.php
new file mode 100644
index 000000000..57126a78a
--- /dev/null
+++ b/program/lib/utf8.class.php
@@ -0,0 +1,173 @@
+<?
+/*
+utf8 1.0
+Copyright: Left
+---------------------------------------------------------------------------------
+Version: 1.0
+Date: 23 November 2004
+---------------------------------------------------------------------------------
+Author: Alexander Minkovsky (a_minkovsky@hotmail.com)
+---------------------------------------------------------------------------------
+License: Choose the more appropriated for You - I don't care.
+---------------------------------------------------------------------------------
+Description:
+ Class provides functionality to convert single byte strings, such as CP1251
+ ti UTF-8 multibyte format and vice versa.
+ Class loads a concrete charset map, for example CP1251.
+ (Refer to ftp://ftp.unicode.org/Public/MAPPINGS/ for map files)
+ Directory containing MAP files is predefined as constant.
+ Each charset is also predefined as constant pointing to the MAP file.
+---------------------------------------------------------------------------------
+Example usage:
+ Pass the desired charset in the class constructor:
+ $utfConverter = new utf8(CP1251); //defaults to CP1250.
+ or load the charset MAP using loadCharset method like this:
+ $utfConverter->loadCharset(CP1252);
+ Then call
+ $res = $utfConverter->strToUtf8($str);
+ or
+ $res = $utfConverter->utf8ToStr($utf);
+ to get the needed encoding.
+---------------------------------------------------------------------------------
+Note:
+ Rewrite or Override the onError method if needed. It's the error handler used from everywhere and takes 2 parameters:
+ err_code and err_text. By default it just prints out a message about the error.
+*/
+
+// Charset maps
+// Adapted to fit RoundCube
+define("UTF8_MAP_DIR", "program/lib/encoding");
+$utf8_maps = array(
+ "CP1250" => UTF8_MAP_DIR . "/CP1250.map",
+ "CP1251" => UTF8_MAP_DIR . "/CP1251.map",
+ "CP1252" => UTF8_MAP_DIR . "/CP1252.map",
+ "CP1253" => UTF8_MAP_DIR . "/CP1253.map",
+ "CP1254" => UTF8_MAP_DIR . "/CP1254.map",
+ "CP1255" => UTF8_MAP_DIR . "/CP1255.map",
+ "CP1256" => UTF8_MAP_DIR . "/CP1256.map",
+ "CP1257" => UTF8_MAP_DIR . "/CP1257.map",
+ "CP1258" => UTF8_MAP_DIR . "/CP1258.map",
+ "ISO-8859-1" => UTF8_MAP_DIR . "/ISO-8859-1.map",
+ "ISO-8859-2" => UTF8_MAP_DIR . "/ISO-8859-2.map",
+ "ISO-8859-3" => UTF8_MAP_DIR . "/ISO-8859-3.map",
+ "ISO-8859-4" => UTF8_MAP_DIR . "/ISO-8859-4.map");
+
+//Error constants
+define("ERR_OPEN_MAP_FILE","ERR_OPEN_MAP_FILE");
+
+//Class definition
+Class utf8{
+
+ var $charset = CP1250;
+ var $ascMap = array();
+ var $utfMap = array();
+
+ // made PHP5 capable by RoundCube
+ function __construct($charset="ISO-8859-1"){
+ $this->loadCharset($charset);
+ }
+
+ //Constructor
+ function utf8($charset="ISO-8859-1"){
+ $this->__construct($charset);
+ }
+
+ //Load charset
+ function loadCharset($charset){
+ global $utf8_maps;
+
+ if (!is_file($utf8_maps[$charset]))
+ {
+ $this->onError(ERR_OPEN_MAP_FILE, "Failed to open map file for $charset");
+ return;
+ }
+
+ if (empty($this->ascMap[$charset]))
+ {
+ $lines = file_get_contents($utf8_maps[$charset]);
+ $lines = preg_replace("/#.*$/m","",$lines);
+ $lines = preg_replace("/\n\n/","",$lines);
+ $lines = explode("\n",$lines);
+ foreach($lines as $line){
+ $parts = explode('0x',$line);
+ if(count($parts)==3){
+ $asc=hexdec(substr($parts[1],0,2));
+ $utf=hexdec(substr($parts[2],0,4));
+ $this->ascMap[$charset][$asc]=$utf;
+ }
+ }
+ }
+
+ $this->charset = $charset;
+ $this->utfMap = array_flip($this->ascMap[$charset]);
+ }
+
+ //Error handler
+ function onError($err_code,$err_text){
+ //print($err_code . " : " . $err_text . "<hr>\n");
+ raise_error(array('code' => 500,
+ 'file' => __FILE__,
+ 'message' => $err_text), TRUE, FALSE);
+ }
+
+ //Translate string ($str) to UTF-8 from given charset
+ function strToUtf8($str){
+ $chars = unpack('C*', $str);
+ $cnt = count($chars);
+ for($i=1;$i<=$cnt;$i++) $this->_charToUtf8($chars[$i]);
+ return implode("",$chars);
+ }
+
+ //Translate UTF-8 string to single byte string in the given charset
+ function utf8ToStr($utf){
+ $chars = unpack('C*', $utf);
+ $cnt = count($chars);
+ $res = ""; //No simple way to do it in place... concatenate char by char
+ for ($i=1;$i<=$cnt;$i++){
+ $res .= $this->_utf8ToChar($chars, $i);
+ }
+ return $res;
+ }
+
+ //Char to UTF-8 sequence
+ function _charToUtf8(&$char){
+ $c = (int)$this->ascMap[$this->charset][$char];
+ if ($c < 0x80){
+ $char = chr($c);
+ }
+ else if($c<0x800) // 2 bytes
+ $char = (chr(0xC0 | $c>>6) . chr(0x80 | $c & 0x3F));
+ else if($c<0x10000) // 3 bytes
+ $char = (chr(0xE0 | $c>>12) . chr(0x80 | $c>>6 & 0x3F) . chr(0x80 | $c & 0x3F));
+ else if($c<0x200000) // 4 bytes
+ $char = (chr(0xF0 | $c>>18) . chr(0x80 | $c>>12 & 0x3F) . chr(0x80 | $c>>6 & 0x3F) . chr(0x80 | $c & 0x3F));
+ }
+
+ //UTF-8 sequence to single byte character
+ function _utf8ToChar(&$chars, &$idx){
+ if(($chars[$idx] >= 240) && ($chars[$idx] <= 255)){ // 4 bytes
+ $utf = (intval($chars[$idx]-240) << 18) +
+ (intval($chars[++$idx]-128) << 12) +
+ (intval($chars[++$idx]-128) << 6) +
+ (intval($chars[++$idx]-128) << 0);
+ }
+ else if (($chars[$idx] >= 224) && ($chars[$idx] <= 239)){ // 3 bytes
+ $utf = (intval($chars[$idx]-224) << 12) +
+ (intval($chars[++$idx]-128) << 6) +
+ (intval($chars[++$idx]-128) << 0);
+ }
+ else if (($chars[$idx] >= 192) && ($chars[$idx] <= 223)){ // 2 bytes
+ $utf = (intval($chars[$idx]-192) << 6) +
+ (intval($chars[++$idx]-128) << 0);
+ }
+ else{ // 1 byte
+ $utf = $chars[$idx];
+ }
+ if(array_key_exists($utf,$this->utfMap))
+ return chr($this->utfMap[$utf]);
+ else
+ return "?";
+ }
+
+}
+?>