public static function Utf8ToUtf7Imap($str, $force = true)
{
if ($str instanceof Horde_Imap_Client_Mailbox) {
return $str->utf7imap;
}
$str = strval($str);
/* No need to do conversion if all chars are in US-ASCII range or if
* no ampersand is present. But will assume that an already encoded
* ampersand means string is in UTF7-IMAP already. */
if (!$force && !preg_match('/[\\x80-\\xff]|&$|&(?![,+A-Za-z0-9]*-)/', $str)) {
return $str;
}
/* Try mbstring, if available, which should be faster. Don't use the
* IMAP utf7_* functions because they are known to be buggy. */
if (is_null(self::$_mbstring)) {
self::$_mbstring = extension_loaded('mbstring');
}
if (self::$_mbstring) {
return @mb_convert_encoding($str, 'UTF7-IMAP', 'UTF-8');
}
$u8len = strlen($str);
$i = 0;
$base64 = false;
$p = '';
$ptr =& self::$_base64;
while ($u8len) {
$u8 = $str[$i];
$c = ord($u8);
if ($c < 0x80) {
$ch = $c;
$n = 0;
} elseif ($c < 0xc2) {
throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION);
} elseif ($c < 0xe0) {
$ch = $c & 0x1f;
$n = 1;
} elseif ($c < 0xf0) {
$ch = $c & 0xf;
$n = 2;
} elseif ($c < 0xf8) {
$ch = $c & 0x7;
$n = 3;
} elseif ($c < 0xfc) {
$ch = $c & 0x3;
$n = 4;
} elseif ($c < 0xfe) {
$ch = $c & 0x1;
$n = 5;
} else {
throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION);
}
if ($n > --$u8len) {
throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION);
}
++$i;
for ($j = 0; $j < $n; ++$j) {
$o = ord($str[$i + $j]);
if (($o & 0xc0) !== 0x80) {
throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION);
}
$ch = $ch << 6 | $o & 0x3f;
}
if ($n > 1 && !($ch >> $n * 5 + 1)) {
throw new Horde_Imap_Client_Exception(Horde_Imap_Client_Translation::r("Error converting UTF7-IMAP string."), Horde_Imap_Client_Exception::UTF7IMAP_CONVERSION);
}
$i += $n;
$u8len -= $n;
if ($ch < 0x20 || $ch >= 0x7f) {
if (!$base64) {
$p .= '&';
$base64 = true;
$b = 0;
$k = 10;
}
if ($ch & ~0xffff) {
$ch = 0xfffe;
}
$p .= $ptr[$b | $ch >> $k];
$k -= 6;
for (; $k >= 0; $k -= 6) {
$p .= $ptr[$ch >> $k & 0x3f];
}
$b = $ch << -$k & 0x3f;
$k += 16;
} else {
if ($base64) {
if ($k > 10) {
$p .= $ptr[$b];
}
$p .= '-';
$base64 = false;
}
$p .= chr($ch);
if (chr($ch) === '&') {
$p .= '-';
}
}
}
if ($base64) {
if ($k > 10) {
$p .= $ptr[$b];
}
$p .= '-';
}
return $p;
}