void trimLWS(std::string& v) { std::string::iterator it; for (it = v.begin(); it != v.end(); ++it) { if (!isLWS(*it)) break; } it = v.erase(v.begin(), it); if (!v.empty()) { it = v.end(); for (;;) { --it; if (!isLWS(*it)) break; it = v.erase(it); } } }
void trimQuoted(std::string& v) { std::string::iterator it; for (it = v.begin(); it != v.end(); ++it) { if (!isLWS(*it)) break; } it = v.erase(v.begin(), it); if (*it == '\'' || *it == '"') { char quote = *it; it = v.erase(it); while (it != v.end()) { if (*it == quote) { it = v.erase(it); v.erase(it, v.end()); break; } else if (*it == '\\') { it = v.erase(it); if (it == v.end()) return; } ++it; } return; } if (!v.empty()) { it = v.end(); for (;;) { --it; if (!isLWS(*it)) break; it = v.erase(it); } } }
static int nextNonWhitespace(const QByteArray &text, int from) { // RFC 2616 defines linear whitespace as: // LWS = [CRLF] 1*( SP | HT ) // We ignore the fact that CRLF must come as a pair at this point // It's an invalid HTTP header if that happens. while (from < text.length()) { if (isLWS(text.at(from))) ++from; else return from; // non-whitespace } // reached the end return text.length(); }
// ### move this to qnetworkcookie_p.h and share with qnetworkaccesshttpbackend static QPair<QByteArray, QByteArray> nextField(const QByteArray &text, int &position, bool isNameValue) { // format is one of: // (1) token // (2) token = token // (3) token = quoted-string int i; const int length = text.length(); position = nextNonWhitespace(text, position); // parse the first part, before the equal sign for (i = position; i < length; ++i) { register char c = text.at(i); if (c == ';' || c == ',' || c == '=') break; } QByteArray first = text.mid(position, i - position).trimmed(); position = i; if (first.isEmpty()) return qMakePair(QByteArray(), QByteArray()); if (i == length || text.at(i) != '=') // no equal sign, we found format (1) return qMakePair(first, QByteArray()); QByteArray second; second.reserve(32); // arbitrary but works for most cases i = nextNonWhitespace(text, position + 1); if (i < length && text.at(i) == '"') { // a quote, we found format (3), where: // quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) // qdtext = <any TEXT except <">> // quoted-pair = "\" CHAR // If its NAME=VALUE, retain the value as is // refer to ttp://bugreports.qt.nokia.com/browse/QTBUG-17746 if (isNameValue) second += '"'; ++i; while (i < length) { register char c = text.at(i); if (c == '"') { // end of quoted text if (isNameValue) second += '"'; break; } else if (c == '\\') { if (isNameValue) second += '\\'; ++i; if (i >= length) // broken line return qMakePair(QByteArray(), QByteArray()); c = text.at(i); } second += c; ++i; } for ( ; i < length; ++i) { register char c = text.at(i); if (c == ',' || c == ';') break; } position = i; } else { // no quote, we found format (2) position = i; for ( ; i < length; ++i) { register char c = text.at(i); if (c == ',' || c == ';' || isLWS(c)) break; } second = text.mid(position, i - position).trimmed(); position = i; } if (second.isNull()) second.resize(0); // turns into empty-but-not-null return qMakePair(first, second); }
static inline bool isSeparator(register char c) { static const char separators[] = "()<>@,;:\\\"/[]?={}"; return isLWS(c) || strchr(separators, c) != 0; }