/** Constructor. Parses <b>status</b> for router status information. The given * string should match the router status entry format from Tor's dir-spec.txt. * The currently recognized lines are: * * "r" SP nickname SP identity SP digest SP publication SP IP SP ORPort * SP DirPort NL * "s" SP Flags NL * * Unrecognized lines are currently ignored. * * */ RouterStatus::RouterStatus(const QStringList &status) { bool ok; _valid = false; _flags = 0; _bandwidth = 0; foreach (QString line, status) { if (line.startsWith("r ")) { QStringList parts = line.split(" ", QString::SkipEmptyParts); if (parts.size() < 9) return; /* Nickname */ _name = parts.at(1); /* Identity key digest */ _id = base16_encode(QByteArray::fromBase64(parts.at(2).toAscii())); if (_id.isEmpty()) return; /* Most recent descriptor digest */ _digest = base16_encode(QByteArray::fromBase64(parts.at(3).toAscii())); if (_digest.isEmpty()) return; /* Most recent publication date */ _published = QDateTime::fromString(parts.at(4) + " " + parts.at(5), TIME_FORMAT); if (!_published.isValid()) return; /* IP address */ _ipAddress = QHostAddress(parts.at(6)); if (_ipAddress.isNull()) return; /* ORPort */ _orPort = parts.at(7).toUInt(&ok); if (!ok) return; /* DirPort */ _dirPort = parts.at(8).toUInt(&ok); if (!ok) return; _valid = true; } else if (line.startsWith("s ")) { /* Status flags */ QStringList flags = line.split(" ", QString::SkipEmptyParts); flags.removeFirst(); /* Remove the "s" */ foreach (QString flag, flags) { _flags |= flagValue(flag); } } else if (line.startsWith("w ")) {
void GTTParser::parseHeaderLine(const std::string& line) { const char *l = line.c_str(); int i = 0, iValue = 0; BOOST_ASSERT(line.length() != 0); // Read flag name if (!isalpha(l[i])) throw ParserException("GTTParser", "flag_name should begin with [a-zA-Z] or we should add newline to end the header"); i++; while (l[i] != ':') { if (!(isalnum(l[i]) || (l[i] == '_') || (l[i] == '-'))) throw ParserException("GTTParser", "flag name should continue with [A-Za-z0-9-_]* or end with a space"); i++; } std::string flagName(l, i); i++; // Skip spaces while (l[i] == ' ') i++; if (l[i] == 0) throw ParserException("GTTParser", "flag without value"); // Read value iValue = i; while (l[i] != 0) { if (!(l[i] >= 32 && l[i] < 126)) throw ParserException("GTTParser", "flag_value should consist of printable characters or just end with CRLF"); i++; } std::string flagValue(l + iValue, i - iValue); // Content length if (!strcasecmp(flagName.c_str(), "content-length")) { if (currentPkt->size > 0) throw ParserException("GTTParser", "content-length flag has already appeared"); currentPkt->size = String::toInt(flagValue.c_str()); if (currentPkt->size <= 0) throw ParserException("GTTParser", "not valid body size, body size should be a positive integer"); } else { currentPkt->headers[flagName] = flagValue; } }