package io.vertx.ext.mail.mailencoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicInteger;
public class Utils {
private Utils() {
}
public static String encodeQP(String text) {
byte[] utf8 = text.getBytes(StandardCharsets.UTF_8);
StringBuilder sb = new StringBuilder();
int column = 0;
for (int i = 0; i < utf8.length; i++) {
char ch = (char) utf8[i];
if (ch == '\n') {
sb.append(ch);
column = 0;
} else {
boolean nextIsEOL = i == utf8.length - 1 || utf8[i + 1] == '\n';
String encChar;
if (mustEncode(ch) || nextIsEOL && ch == ' ') {
encChar = encodeChar(ch);
} else {
encChar = String.valueOf(ch);
}
int newColumn = column + encChar.length();
if (newColumn <= 75 || nextIsEOL && newColumn == 76) {
sb.append(encChar);
column = newColumn;
} else {
sb.append("=\n").append(encChar);
column = encChar.length();
}
}
}
return sb.toString();
}
private static String encodeChar(char ch) {
if (ch < 16) {
return "=0" + Integer.toHexString(ch).toUpperCase(Locale.ENGLISH);
} else {
return '=' + Integer.toHexString(ch & 0xff).toUpperCase(Locale.ENGLISH);
}
}
static boolean mustEncode(char ch) {
return ch >= 128 || ch < 10 || ch >= 11 && ch < 32 || ch == '=';
}
static boolean mustEncode(String s) {
for (int i = 0; i < s.length(); i++) {
final char ch = s.charAt(i);
if (ch != '=' && ch != '\t' && mustEncode(ch)) {
return true;
}
}
return false;
}
private static final AtomicInteger count = new AtomicInteger(0);
private static String nomaliseUserAgent(String userAgent) {
return userAgent.replace(" ", "_");
}
static String generateBoundary(String userAgent) {
return "=--" +
nomaliseUserAgent(userAgent) + "_" +
Thread.currentThread().hashCode() + "_" +
System.currentTimeMillis() + "_" +
count.getAndIncrement();
}
static String generateMessageID(String hostname, String userAgent) {
return "<msg." +
System.currentTimeMillis() + "." +
nomaliseUserAgent(userAgent) + "." +
count.getAndIncrement() +
"@" + hostname +
">";
}
static String (String subject, int index) {
if (mustEncode(subject)) {
byte[] utf8 = subject.getBytes(StandardCharsets.UTF_8);
StringBuilder sb = new StringBuilder();
sb.append("=?UTF-8?Q?");
int column = 10 + index;
for (byte b : utf8) {
char ch = (char) b;
if (ch == '\n') {
column = 1;
} else {
String encChar;
if (mustEncode(ch) || ch == '_' || ch == '?') {
encChar = encodeChar(ch);
} else if (ch == ' ') {
encChar = "_";
} else {
encChar = String.valueOf(ch);
}
int newColumn = column + encChar.length();
if (newColumn <= 74) {
sb.append(encChar);
column = newColumn;
} else {
sb.append("?=\n =?UTF-8?Q?").append(encChar);
column = 11 + encChar.length();
}
}
}
sb.append("?=");
return sb.toString();
} else {
return subject;
}
}
static String (String address, int index) {
EmailAddress adr = new EmailAddress(address);
if (mustEncode(adr.getName())) {
return adr.getEmail() + " (" + encodeHeader(adr.getName(), index + adr.getEmail().length() + 2) + ")";
} else {
return address;
}
}
static String encodeEmailList(List<String> addresses, int index) {
StringBuilder sb = new StringBuilder();
boolean firstAddress = true;
for (String addr : addresses) {
if (firstAddress) {
firstAddress = false;
} else {
sb.append(',');
index++;
}
final String email, name;
if (EmailAddress.POSTMASTER.equalsIgnoreCase(addr)) {
email = addr;
name = "";
} else {
EmailAddress adr = new EmailAddress(addr);
email = adr.getEmail();
name = adr.getName();
}
if (index + email.length() >= 76) {
sb.append("\n ");
index = 1;
}
sb.append(email);
index += email.length();
if (!name.isEmpty()) {
if (mustEncode(name)) {
boolean hadSpace = false;
if (index + 12 >= 71) {
sb.append("\n ");
index = 1;
hadSpace = true;
}
if (!hadSpace) {
sb.append(' ');
index++;
}
sb.append('(');
index++;
String encoded = encodeHeader(name, index);
sb.append(encoded);
if (encoded.contains("\n")) {
index = encoded.length() - encoded.lastIndexOf('\n');
} else {
index += encoded.length();
}
sb.append(')');
index++;
} else {
boolean hadSpace = false;
if (index + name.length() + 3 >= 76) {
sb.append("\n ");
index = 1;
hadSpace = true;
}
if (!hadSpace) {
sb.append(' ');
index++;
}
sb.append('(');
index++;
sb.append(name);
sb.append(')');
index += email.length() + 3;
}
}
}
return sb.toString();
}
static String generateDate() {
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z (z)", Locale.ENGLISH);
return format.format(new Date());
}
private final static byte[] lf = { 10 };
public static String base64(byte[] bytes) {
return Base64.getMimeEncoder(76, lf).encodeToString(bytes);
}
}