optimized resource usage, avoid unnecessary casts, formatting

This commit is contained in:
john30
2017-02-05 12:33:16 +01:00
parent 1df7df14e3
commit 71fec2d427
2 changed files with 141 additions and 129 deletions
+132 -129
View File
@@ -164,7 +164,6 @@ void MainLoop::run() {
(*it)->start(); (*it)->start();
} }
while (true) { while (true) {
string result;
// pick the next message to handle // pick the next message to handle
NetMessage* netMessage = m_netQueue.pop(taskDelay); NetMessage* netMessage = m_netQueue.pop(taskDelay);
time(&now); time(&now);
@@ -263,39 +262,37 @@ void MainLoop::run() {
if (!listening) { if (!listening) {
since = now; since = now;
} }
ostringstream ostream;
bool connected = true; bool connected = true;
if (request.length() > 0) { if (request.length() > 0) {
logDebug(lf_main, ">>> %s", request.c_str()); logDebug(lf_main, ">>> %s", request.c_str());
result = decodeMessage(request, netMessage->isHttp(), connected, listening, reload); ostream << decodeMessage(request, netMessage->isHttp(), connected, listening, reload);
if (result.length() == 0 && !netMessage->isHttp()) { if (ostream.tellp() == 0 && !netMessage->isHttp()) {
result = getResultCode(RESULT_EMPTY); ostream << getResultCode(RESULT_EMPTY);
} }
if (result.length() > 100) { if (ostream.tellp() > 100) {
logDebug(lf_main, "<<< %s ...", result.substr(0, 100).c_str()); logDebug(lf_main, "<<< %s ...", ostream.str().substr(0, 100).c_str());
} else { } else {
logDebug(lf_main, "<<< %s", result.c_str()); logDebug(lf_main, "<<< %s", ostream.str().c_str());
} }
if (result.length() == 0) { if (ostream.tellp() == 0) {
result = "\n"; // only for HTTP ostream << "\n"; // only for HTTP
} else if (!netMessage->isHttp()) { } else if (!netMessage->isHttp()) {
result += "\n\n"; ostream << "\n\n";
} }
} }
if (listening) { if (listening) {
messages = m_messages->findAll("", "", false, true, true, true, false, true, since, now); messages = m_messages->findAll("", "", false, true, true, true, false, true, since, now);
updates.str("");
updates.clear();
for (deque<Message*>::iterator it = messages.begin(); it != messages.end(); it++) { for (deque<Message*>::iterator it = messages.begin(); it != messages.end(); it++) {
Message* message = *it; Message* message = *it;
updates << message->getCircuit() << " " << message->getName() << " = " << dec; ostream << message->getCircuit() << " " << message->getName() << " = " << dec;
message->decodeLastData(updates); message->decodeLastData(ostream);
updates << endl; ostream << endl;
} }
result += updates.str();
} }
// send result to client // send result to client
netMessage->setResult(result, listening, now, !connected); netMessage->setResult(ostream.str(), listening, now, !connected);
} }
} }
@@ -1130,9 +1127,9 @@ string MainLoop::executeState(vector<string> &args) {
if (m_busHandler->hasSignal()) { if (m_busHandler->hasSignal()) {
ostringstream result; ostringstream result;
result << "signal acquired, " result << "signal acquired, "
<< static_cast<unsigned>(m_busHandler->getSymbolRate()) << " symbols/sec (" << m_busHandler->getSymbolRate() << " symbols/sec ("
<< static_cast<unsigned>(m_busHandler->getMaxSymbolRate()) << " max), " << m_busHandler->getMaxSymbolRate() << " max), "
<< static_cast<unsigned>(m_busHandler->getMasterCount()) << " masters"; << m_busHandler->getMasterCount() << " masters";
return result.str(); return result.str();
} }
return "no signal"; return "no signal";
@@ -1290,16 +1287,16 @@ string MainLoop::executeInfo(vector<string> &args) {
result << "version: " << PACKAGE_STRING "." REVISION "\n"; result << "version: " << PACKAGE_STRING "." REVISION "\n";
if (m_busHandler->hasSignal()) { if (m_busHandler->hasSignal()) {
result << "signal: acquired\n"; result << "signal: acquired\n";
result << "symbol rate: " << static_cast<unsigned>(m_busHandler->getSymbolRate()) << "\n"; result << "symbol rate: " << m_busHandler->getSymbolRate() << "\n";
} else { } else {
result << "signal: no signal\n"; result << "signal: no signal\n";
} }
result << "reconnects: " << static_cast<unsigned>(m_reconnectCount) << "\n"; result << "reconnects: " << m_reconnectCount << "\n";
result << "masters: " << static_cast<unsigned>(m_busHandler->getMasterCount()) << "\n"; result << "masters: " << m_busHandler->getMasterCount() << "\n";
result << "messages: " << static_cast<unsigned>(m_messages->size()) << "\n"; result << "messages: " << m_messages->size() << "\n";
result << "conditional: " << static_cast<unsigned>(m_messages->sizeConditional()) << "\n"; result << "conditional: " << m_messages->sizeConditional() << "\n";
result << "poll: " << static_cast<unsigned>(m_messages->sizePoll()) << "\n"; result << "poll: " << m_messages->sizePoll() << "\n";
result << "update: " << static_cast<unsigned>(m_messages->sizePassive()); result << "update: " << m_messages->sizePassive();
m_busHandler->formatSeenInfo(result); m_busHandler->formatSeenInfo(result);
return result.str(); return result.str();
} }
@@ -1355,8 +1352,8 @@ string MainLoop::executeGet(vector<string> &args, bool& connected) {
if (pos == string::npos) { if (pos == string::npos) {
circuit = uri.substr(6); circuit = uri.substr(6);
} else { } else {
circuit = uri.substr(6, pos-6); circuit = uri.substr(6, pos - 6);
name = uri.substr(pos+1); name = uri.substr(pos + 1);
} }
time_t since = 0; time_t since = 0;
unsigned char pollPriority = 0; unsigned char pollPriority = 0;
@@ -1370,7 +1367,7 @@ string MainLoop::executeGet(vector<string> &args, bool& connected) {
string qname, value; string qname, value;
if (pos != string::npos) { if (pos != string::npos) {
qname = token.substr(0, pos); qname = token.substr(0, pos);
value = token.substr(pos+1); value = token.substr(pos + 1);
} else { } else {
qname = token; qname = token;
} }
@@ -1382,7 +1379,7 @@ string MainLoop::executeGet(vector<string> &args, bool& connected) {
exact = value.length() == 0 || strcmp(value.c_str(), "1") == 0; exact = value.length() == 0 || strcmp(value.c_str(), "1") == 0;
} else if (strcmp(qname.c_str(), "verbose") == 0) { } else if (strcmp(qname.c_str(), "verbose") == 0) {
if (value.length() == 0 || strcmp(value.c_str(), "1") == 0) { if (value.length() == 0 || strcmp(value.c_str(), "1") == 0) {
verbosity |= OF_UNITS|OF_COMMENTS; verbosity |= OF_UNITS | OF_COMMENTS;
} }
} else if (strcmp(qname.c_str(), "indexed") == 0) { } else if (strcmp(qname.c_str(), "indexed") == 0) {
if (value.length() == 0 || strcmp(value.c_str(), "1") == 0) { if (value.length() == 0 || strcmp(value.c_str(), "1") == 0) {
@@ -1398,74 +1395,75 @@ string MainLoop::executeGet(vector<string> &args, bool& connected) {
} }
} }
} }
deque<Message*> messages = m_messages->findAll(circuit, name, exact, true, false, true);
bool first = true;
result << "{"; result << "{";
string lastCircuit = ""; string lastCircuit = "";
time_t maxLastUp = 0; time_t maxLastUp = 0;
for (deque<Message*>::iterator it = messages.begin(); ret == RESULT_OK && it != messages.end();) {
Message* message = *it++;
unsigned char dstAddress = message->getDstAddress();
if (dstAddress == SYN) {
continue;
}
if (pollPriority > 0 && message->setPollPriority(pollPriority)) {
m_messages->addPollMessage(message);
}
time_t lastup = message->getLastUpdateTime();
if (lastup == 0 && required) {
// read directly from bus
if (message->isPassive()) {
continue; // not possible to actively read this message
}
if (m_busHandler->readFromBus(message, "") != RESULT_OK) {
continue;
}
lastup = message->getLastUpdateTime();
} else {
if (since > 0 && lastup <= since) {
continue;
}
if (lastup > maxLastUp) {
maxLastUp = lastup;
}
}
if (message->getCircuit() != lastCircuit) {
if (lastCircuit.length() > 0) {
result << "\n },";
}
lastCircuit = message->getCircuit();
result << "\n \"" << lastCircuit << "\": {";
first = true;
}
if (first) {
first = false;
} else {
result << ",";
}
result << "\n \"" << message->getName() << "\": {";
result << "\n \"lastup\": " << setw(0) << dec << static_cast<unsigned>(lastup);
if (lastup != 0) {
result << ",\n \"zz\": \"" << setfill('0') << setw(2) << hex << static_cast<unsigned>(dstAddress) << "\"";
size_t pos = (size_t)result.tellp();
result << ",\n \"fields\": {";
result_t dret = message->decodeLastData(result, verbosity|(numeric?OF_NUMERIC:0)|OF_JSON);
if (dret == RESULT_OK) {
result << "\n }";
} else {
string prefix = result.str().substr(0, pos);
result.str("");
result.clear(); // remove written fields
result << prefix << ",\n \"decodeerror\": \"" << getResultCode(dret) << "\"";
}
}
result << ",\n \"passive\": " << (message->isPassive() ? "true" : "false");
result << ",\n \"write\": " << (message->isWrite() ? "true" : "false");
result << "\n }";
}
if (ret == RESULT_OK) { if (ret == RESULT_OK) {
deque<Message *> messages = m_messages->findAll(circuit, name, exact, true, false, true);
bool first = true;
for (deque<Message*>::iterator it = messages.begin(); it != messages.end();) {
Message* message = *it++;
unsigned char dstAddress = message->getDstAddress();
if (dstAddress == SYN) {
continue;
}
if (pollPriority > 0 && message->setPollPriority(pollPriority)) {
m_messages->addPollMessage(message);
}
time_t lastup = message->getLastUpdateTime();
if (lastup == 0 && required) {
// read directly from bus
if (message->isPassive()) {
continue; // not possible to actively read this message
}
if (m_busHandler->readFromBus(message, "") != RESULT_OK) {
continue;
}
lastup = message->getLastUpdateTime();
} else {
if (since > 0 && lastup <= since) {
continue;
}
if (lastup > maxLastUp) {
maxLastUp = lastup;
}
}
if (message->getCircuit() != lastCircuit) {
if (lastCircuit.length() > 0) {
result << "\n },";
}
lastCircuit = message->getCircuit();
result << "\n \"" << lastCircuit << "\": {";
first = true;
}
if (first) {
first = false;
} else {
result << ",";
}
result << "\n \"" << message->getName() << "\": {";
result << "\n \"lastup\": " << setw(0) << dec << static_cast<unsigned>(lastup);
if (lastup != 0) {
result << ",\n \"zz\": \"" << setfill('0') << setw(2) << hex << static_cast<unsigned>(dstAddress) << "\"";
size_t pos = (size_t) result.tellp();
result << ",\n \"fields\": {";
result_t dret = message->decodeLastData(result, verbosity | (numeric ? OF_NUMERIC : 0) | OF_JSON);
if (dret == RESULT_OK) {
result << "\n }";
} else {
string prefix = result.str().substr(0, pos);
result.str("");
result.clear(); // remove written fields
result << prefix << ",\n \"decodeerror\": \"" << getResultCode(dret) << "\"";
}
}
result << ",\n \"passive\": " << (message->isPassive() ? "true" : "false");
result << ",\n \"write\": " << (message->isWrite() ? "true" : "false");
result << "\n }";
}
if (lastCircuit.length() > 0) { if (lastCircuit.length() > 0) {
result << "\n },"; result << "\n },";
} }
@@ -1476,48 +1474,54 @@ string MainLoop::executeGet(vector<string> &args, bool& connected) {
result << "\n}"; result << "\n}";
type = 6; type = 6;
} }
connected = false;
return formatHttpResult(ret, result, type);
} // request for "/data/..."
if (uri.length() < 1 || uri[0] != '/' || uri.find("//") != string::npos || uri.find("..") != string::npos) {
ret = RESULT_ERR_INVALID_ARG;
} else { } else {
if (uri.length() < 1 || uri[0] != '/' || uri.find("//") != string::npos || uri.find("..") != string::npos) { string filename = m_htmlPath + uri;
ret = RESULT_ERR_INVALID_ARG; if (uri[uri.length() - 1] == '/') {
filename += "index.html";
}
size_t pos = filename.find_last_of('.');
if (pos != string::npos && pos != filename.length() - 1 && pos >= filename.length() - 5) {
string ext = filename.substr(pos + 1);
if (ext == "html") {
type = 0;
} else if (ext == "css") {
type = 1;
} else if (ext == "js") {
type = 2;
} else if (ext == "png") {
type = 3;
} else if (ext == "jpg" || ext == "jpeg") {
type = 4;
} else if (ext == "svg") {
type = 5;
} else if (ext == "json") {
type = 6;
}
}
if (type < 0) {
ret = RESULT_ERR_NOTFOUND;
} else { } else {
string filename = m_htmlPath+uri; ifstream ifs;
if (uri[uri.length()-1] == '/') { ifs.open(filename.c_str(), ifstream::in | ifstream::binary);
filename += "index.html"; if (!ifs.is_open()) {
}
size_t pos = filename.find_last_of('.');
if (pos != string::npos && pos != filename.length() - 1 && pos >= filename.length() - 5) {
string ext = filename.substr(pos+1);
if (ext == "html") {
type = 0;
} else if (ext == "css") {
type = 1;
} else if (ext == "js") {
type = 2;
} else if (ext == "png") {
type = 3;
} else if (ext == "jpg" || ext == "jpeg") {
type = 4;
} else if (ext == "svg") {
type = 5;
} else if (ext == "json") {
type = 6;
}
}
if (type < 0) {
ret = RESULT_ERR_NOTFOUND; ret = RESULT_ERR_NOTFOUND;
} else { } else {
ifstream ifs; ifs >> result.rdbuf();
ifs.open(filename.c_str(), ifstream::in | ifstream::binary); ifs.close();
if (!ifs.is_open()) {
ret = RESULT_ERR_NOTFOUND;
} else {
ifs >> result.rdbuf();
ifs.close();
}
} }
} }
} }
connected = false;
return formatHttpResult(ret, result, type);
}
string MainLoop::formatHttpResult(result_t ret, ostringstream& result, int type) {
string data = ret == RESULT_OK ? result.str() : ""; string data = ret == RESULT_OK ? result.str() : "";
result.str(""); result.str("");
result.clear(); result.clear();
@@ -1564,7 +1568,6 @@ string MainLoop::executeGet(vector<string> &args, bool& connected) {
} }
result << "\r\nServer: " PACKAGE_NAME "/" PACKAGE_VERSION "\r\n\r\n"; result << "\r\nServer: " PACKAGE_NAME "/" PACKAGE_VERSION "\r\n\r\n";
result << data; result << data;
connected = false;
return result.str(); return result.str();
} }
+9
View File
@@ -208,6 +208,15 @@ class MainLoop : public Thread, DeviceListener {
*/ */
string executeGet(vector<string> &args, bool& connected); string executeGet(vector<string> &args, bool& connected);
/**
* Format the HTTP answer to the result string.
* @param ret the result code of handling the request.
* @param result the @a ostringstream containing the successful result.
* @param type the content type.
* @return the result string.
*/
string formatHttpResult(result_t ret, ostringstream& result, int type);
/** the @a Device instance. */ /** the @a Device instance. */
Device* m_device; Device* m_device;