1170 | | $encoded = trim(chunk_split($encoded, $maxlen, "\n")); |
| 1169 | |
| 1170 | if ('UTF-8' == $this->CharSet) { |
| 1171 | $chunks = array(); |
| 1172 | $start = 0; |
| 1173 | $i = 0; |
| 1174 | while ($i < strlen($str)) { |
| 1175 | if (ord($str[$i]) < 0x80) $n = 0; # 0bbbbbbb; equal to US-ASCII; one octet only. |
| 1176 | elseif ((ord($str[$i]) & 0xE0) == 0xC0) $n = 1; # 110bbbbb; followed by 1 octet. |
| 1177 | elseif ((ord($str[$i]) & 0xF0) == 0xE0) $n = 2; # 1110bbbb; followed by 2 octet. |
| 1178 | elseif ((ord($str[$i]) & 0xF8) == 0xF0) $n = 3; # 11110bbb; followed by 3 octet. |
| 1179 | elseif ((ord($str[$i]) & 0xFC) == 0xF8) $n = 4; # 111110bb; followed by 4 octet. |
| 1180 | elseif ((ord($str[$i]) & 0xFE) == 0xFC) $n = 5; # 1111110b; followed by 5 octet. |
| 1181 | else { # second or later octet. |
| 1182 | $i++; |
| 1183 | continue; |
| 1184 | } |
| 1185 | |
| 1186 | // Base64 encoded size |
| 1187 | $encoded_length = ceil(($i + $n - $start) * 8 / 6); |
| 1188 | $encoded_length = ceil($encoded_length / 4) * 4; // padding |
| 1189 | |
| 1190 | if ($maxlen < $encoded_length) { |
| 1191 | $chunks[] = substr($str, $start, $i - $start); // get one octet back. |
| 1192 | $start = $i; |
| 1193 | } else { |
| 1194 | $i = $i + $n + 1; |
| 1195 | } |
| 1196 | } |
| 1197 | $chunks[] = substr($str, $start); // rest |
| 1198 | |
| 1199 | $encoded = "\n"; |
| 1200 | foreach ($chunks as $chunk) { |
| 1201 | $encoded .= base64_encode($chunk) . "\n"; |
| 1202 | } |
| 1203 | $encoded = trim($encoded); |
| 1204 | |
| 1205 | } else { |
| 1206 | $encoded = base64_encode($str); |
| 1207 | $encoded = trim(chunk_split($encoded, $maxlen, "\n")); |
| 1208 | } |
1174 | | $encoded = $this->WrapText($encoded, $maxlen, true); |
1175 | | $encoded = str_replace("=".$this->LE, "\n", trim($encoded)); |
| 1212 | |
| 1213 | if ('UTF-8' == $this->CharSet) { |
| 1214 | $chunks = array(); |
| 1215 | $pos = 0; |
| 1216 | while (strlen($encoded) - $pos > $maxlen) { |
| 1217 | $len = $maxlen; |
| 1218 | $part = substr($encoded, $pos, $len); |
| 1219 | |
| 1220 | if (substr($part, $len - 1, 1) == "=") |
| 1221 | $len -= 1; |
| 1222 | elseif (substr($part, $len - 2, 1) == "=") |
| 1223 | $len -= 2; |
| 1224 | $part = substr($encoded, $pos, $len); |
| 1225 | |
| 1226 | if (preg_match('/=[0-9A-F]{2}$/', $part) |
| 1227 | && preg_match('/=([0-9A-F]{2})/', substr($encoded, $pos + $len, 3), $matches) |
| 1228 | && (hexdec($matches[1]) & 0xC0) == 0x80) { # 10bbbbbb; following octet |
| 1229 | |
| 1230 | while (preg_match('/=([0-9A-F]{2})$/', $part, $matches)) { |
| 1231 | $len -= 3; |
| 1232 | $part = substr($encoded, $pos, $len); |
| 1233 | if ((hexdec($matches[1]) & 0xC0) != 0x80) |
| 1234 | break; |
| 1235 | } |
| 1236 | } |
| 1237 | |
| 1238 | $chunks[] = $part; |
| 1239 | $pos += $len; |
| 1240 | } |
| 1241 | |
| 1242 | $chunks[] = substr($encoded, $pos); // rest |
| 1243 | $encoded = trim(join($chunks, "\n")); |
| 1244 | } else { |
| 1245 | $encoded = $this->WrapText($encoded, $maxlen, true); |
| 1246 | $encoded = str_replace("=".$this->LE, "\n", trim($encoded)); |
| 1247 | } |