7#include "imapparser_p.h" 
   16class Akonadi::ImapParserPrivate
 
   20    QByteArray dataBuffer;
 
   27    bool checkLiteralStart(
const QByteArray &readBuffer, 
int pos = 0)
 
   39            literalSize = readBuffer.
mid(begin + 1, end - begin - 1).
toLongLong();
 
   42            if (literalSize == 0) {
 
   47            dataBuffer.reserve(dataBuffer.size() + 
static_cast<int>(literalSize) + 1);
 
   57int parseParenthesizedListHelper(
const QByteArray &data, T &result, 
int start)
 
   72    int sublistBegin = 
start;
 
   73    bool insideQuote = 
false;
 
   74    for (
int i = begin + 1; i < data.
length(); ++i) {
 
   75        const char currentChar = data[i];
 
   76        if (currentChar == 
'(' && !insideQuote) {
 
   85        if (currentChar == 
')' && !insideQuote) {
 
   91                result.append(data.
mid(sublistBegin, i - sublistBegin + 1));
 
   98        if (currentChar == 
' ' || currentChar == 
'\n' || currentChar == 
'\r') {
 
  104            const int consumed = ImapParser::parseString(data, ba, i);
 
  107        } 
else if (count > 0) {
 
  108            if (currentChar == 
'"') {
 
  109                insideQuote = !insideQuote;
 
  110            } 
else if (currentChar == 
'\\' && insideQuote) {
 
  124    return parseParenthesizedListHelper(data, result, 
start);
 
  129    return parseParenthesizedListHelper(data, result, 
start);
 
  136    if (begin >= data.
length()) {
 
  142    if (data[begin] == 
'{') {
 
  144        Q_ASSERT(end > begin);
 
  145        int size = data.
mid(begin + 1, end - begin - 1).
toInt();
 
  149        if (begin < data.
length() && data[begin] == 
'\r') {
 
  152        if (begin < data.
length() && data[begin] == 
'\n') {
 
  157        result = data.
mid(begin, end - begin);
 
  162    return parseQuotedString(data, result, begin);
 
  170    if (begin >= data.
length()) {
 
  174    bool foundSlash = 
false;
 
  176    if (data[begin] == 
'"') {
 
  179        for (
int i = begin; i < data.
length(); ++i) {
 
  180            const char ch = data.
at(i);
 
  185                } 
else if (ch == 
'n') {
 
  187                } 
else if (ch == 
'\\') {
 
  189                } 
else if (ch == 
'\"') {
 
  209        bool reachedInputEnd = 
true;
 
  210        for (
int i = begin; i < data.
length(); ++i) {
 
  211            const char ch = data.
at(i);
 
  212            if (ch == 
' ' || ch == 
'(' || ch == 
')' || ch == 
'\n' || ch == 
'\r') {
 
  214                reachedInputEnd = 
false;
 
  221        if (reachedInputEnd) {
 
  224        result = data.
mid(begin, end - begin);
 
  227        if (result == 
"NIL") {
 
  248        if (data[i] != 
' ') {
 
  259    bool insideQuote = 
false;
 
  261        const char ch = data[i];
 
  263            insideQuote = !insideQuote;
 
  266        if (ch == 
'\\' && insideQuote) {
 
  270        if (ch == 
'(' && !insideQuote) {
 
  274        if (ch == 
')' && !insideQuote) {
 
  296    for (; it != endIt; ++it) {
 
  297        resultSize += (*it).size();
 
  305    for (; it != endIt; ++it) {
 
  317    return ImapParser::join(list, separator);
 
  323    const int end = parseString(data, tmp, 
start);
 
  328int ImapParser::parseNumber(
const QByteArray &data, qint64 &result, 
bool *ok, 
int start)
 
  334    int pos = stripLeadingSpaces(data, 
start);
 
  335    if (pos >= data.
length()) {
 
  340    for (; pos < data.
length(); ++pos) {
 
  341        if (!isdigit(data.
at(pos))) {
 
  359    const int inputLength = data.
length();
 
  360    int stuffToQuote = 0;
 
  361    for (
int i = 0; i < inputLength; ++i) {
 
  362        const char ch = data.
at(i);
 
  363        if (ch == 
'"' || ch == 
'\\' || ch == 
'\n' || ch == 
'\r') {
 
  369    result.
reserve(inputLength + stuffToQuote + 2);
 
  373    if (stuffToQuote == 0) {
 
  376        for (
int i = 0; i < inputLength; ++i) {
 
  377            const char ch = data.
at(i);
 
  388            if (ch == 
'"' || ch == 
'\\') {
 
  400int ImapParser::parseSequenceSet(
const QByteArray &data, ImapSet &result, 
int start)
 
  406    for (
int i = begin; i < data.
length(); ++i) {
 
  407        if (data[i] == 
'*') {
 
  409        } 
else if (data[i] == 
':') {
 
  411        } 
else if (isdigit(data[i])) {
 
  413            i = parseNumber(data, value, &ok, i);
 
  421            result.add(ImapInterval(lower, upper));
 
  425            if (data[i] != 
',') {
 
  436    if (lower >= 0 && upper >= 0) {
 
  437        result.add(ImapInterval(lower, upper));
 
  466    int pos = stripLeadingSpaces(data, 
start);
 
  467    if (data.
length() <= pos) {
 
  472    if (data[pos] == 
'"') {
 
  476        if (data.
length() <= pos + 26) {
 
  480        if (data.
length() < pos + 26) {
 
  486    const int day = (data[pos] == 
' ' ? data[pos + 1] - 
'0'  
  487                                      : data.
mid(pos, 2).toInt(&ok));
 
  493    static const QByteArray shortMonthNames(
"janfebmaraprmayjunjulaugsepoctnovdec");
 
  494    int month = shortMonthNames.indexOf(data.
mid(pos, 3).
toLower());
 
  499    month = month / 3 + 1;
 
  501    const int year = data.
mid(pos, 4).
toInt(&ok);
 
  507    const int hours = data.
mid(pos, 2).
toInt(&ok);
 
  513    const int minutes = data.
mid(pos, 2).
toInt(&ok);
 
  519    const int seconds = data.
mid(pos, 2).
toInt(&ok);
 
  525    const int tzhh = data.
mid(pos, 2).
toInt(&ok);
 
  531    const int tzmm = data.
mid(pos, 2).
toInt(&ok);
 
  536    int tzsecs = tzhh * 60 * 60 + tzmm * 60;
 
  537    if (data[pos - 3] == 
'-') {
 
  541    const QDate date(year, month, day);
 
  542    const QTime time(hours, minutes, seconds);
 
  548    dateTime = dateTime.
addSecs(-tzsecs);
 
  551    if (data.
length() <= pos || !quoted) {
 
  555    if (data[pos] == 
'"') {
 
  564    const int startPos = data.
indexOf(
'[');
 
  565    const int endPos = data.
indexOf(
']');
 
  566    if (startPos != -1 && endPos != -1) {
 
  567        if (endPos > startPos) {
 
  575            key = data.
left(startPos);
 
  583ImapParser::ImapParser()
 
  584    : d(new ImapParserPrivate)
 
  589ImapParser::~ImapParser() = 
default;
 
  591bool ImapParser::parseNextLine(
const QByteArray &readBuffer)
 
  593    d->continuation = 
false;
 
  596    if (d->tagBuffer.isEmpty()) {
 
  597        const int startOfData = ImapParser::parseString(readBuffer, d->tagBuffer);
 
  598        if (startOfData < readBuffer.
length() && startOfData >= 0) {
 
  599            d->dataBuffer = readBuffer.
mid(startOfData + 1);
 
  603        d->dataBuffer += readBuffer;
 
  607    if (d->literalSize > 0) {
 
  608        d->literalSize -= readBuffer.
size();
 
  611        if (d->literalSize > 0) {
 
  616        if (d->literalSize < 0) {
 
  618            d->parenthesesCount += ImapParser::parenthesesBalance(readBuffer, readBuffer.
length() + 
static_cast<int>(d->literalSize));
 
  621            if (d->checkLiteralStart(readBuffer, readBuffer.
length() + 
static_cast<int>(d->literalSize))) {
 
  627        if (d->parenthesesCount > 0) {
 
  633        d->parenthesesCount += ImapParser::parenthesesBalance(readBuffer);
 
  636        if (d->checkLiteralStart(readBuffer)) {
 
  641        if (d->parenthesesCount > 0) {
 
  651void ImapParser::parseBlock(
const QByteArray &data)
 
  653    Q_ASSERT(d->literalSize >= data.
size());
 
  654    d->literalSize -= data.
size();
 
  655    d->dataBuffer += data;
 
  665    return d->dataBuffer;
 
  668void ImapParser::reset()
 
  670    d->dataBuffer.
clear();
 
  671    d->tagBuffer.clear();
 
  672    d->parenthesesCount = 0;
 
  674    d->continuation = 
false;
 
  677bool ImapParser::continuationStarted()
 const 
  679    return d->continuation;
 
  682qint64 ImapParser::continuationSize()
 const 
  684    return d->literalSize;
 
Q_SCRIPTABLE QString start(QString train="")
 
Helper integration between Akonadi and Qt.
 
KDB_EXPORT KDbVersionInfo version()
 
KIOCORE_EXPORT QStringList list(const QString &fileClass)
 
const QList< QKeySequence > & begin()
 
const QList< QKeySequence > & end()
 
char at(qsizetype i) const const
 
bool contains(QByteArrayView bv) const const
 
bool endsWith(QByteArrayView bv) const const
 
qsizetype indexOf(QByteArrayView bv, qsizetype from) const const
 
bool isEmpty() const const
 
qsizetype lastIndexOf(QByteArrayView bv) const const
 
QByteArray left(qsizetype len) const const
 
qsizetype length() const const
 
QByteArray mid(qsizetype pos, qsizetype len) const const
 
QByteArray & replace(QByteArrayView before, QByteArrayView after)
 
void reserve(qsizetype size)
 
qsizetype size() const const
 
int toInt(bool *ok, int base) const const
 
qlonglong toLongLong(bool *ok, int base) const const
 
QByteArray toLower() const const
 
QByteArray trimmed() const const
 
QDateTime addSecs(qint64 s) const const
 
bool isValid() const const
 
const_iterator constBegin() const const
 
const_iterator constEnd() const const
 
bool isEmpty() const const
 
qsizetype size() const const
 
QString fromUtf8(QByteArrayView str)