package io.vertx.ext.mail.impl;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.impl.logging.Logger;
import io.vertx.core.impl.logging.LoggerFactory;
import io.vertx.core.parsetools.RecordParser;
import java.util.regex.Pattern;
class MultilineParser implements Handler<Buffer> {
private static final Pattern STATUS_LINE_CONTINUE = Pattern.compile("^\\d{3}-.*");
private static final Logger log = LoggerFactory.getLogger(MultilineParser.class);
private boolean initialized = false;
private Buffer result;
private final RecordParser rp;
private int expected = 1;
private int actual = 0;
public MultilineParser(Handler<Buffer> output) {
Handler<Buffer> mlp = new Handler<Buffer>() {
@Override
public void handle(final Buffer buffer) {
if (!initialized) {
initialized = true;
final String line = buffer.toString();
if (line.endsWith("\r")) {
log.debug("setting crlf line mode");
rp.delimitedMode("\r\n");
appendOrHandle(Buffer.buffer(line.substring(0, line.length() - 1)));
} else {
appendOrHandle(buffer);
}
} else {
appendOrHandle(buffer);
}
}
private void appendOrHandle(final Buffer buffer) {
if (result == null) {
result = Buffer.buffer();
}
result.appendBuffer(buffer);
if (isFinalLine(buffer)) {
actual ++;
if (actual < expected) {
result.appendString("\r\n");
} else if (actual == expected) {
try {
output.handle(result);
} finally {
result = null;
actual = 0;
}
}
} else {
result.appendString("\n");
}
}
};
rp = RecordParser.newDelimited("\n", mlp);
}
boolean isFinalLine(final Buffer buffer) {
String line = buffer.toString();
if (line.contains("\n")) {
String[] lines = line.split("\n");
line = lines[lines.length - 1];
}
return !STATUS_LINE_CONTINUE.matcher(line).matches();
}
@Override
public void handle(final Buffer event) {
rp.handle(event);
}
MultilineParser setExpected(int expected) {
this.expected = expected;
return this;
}
}