optimized

This commit is contained in:
john30
2017-05-13 17:22:08 +02:00
parent 99340c8d4b
commit a4e1aa65b4
6 changed files with 433 additions and 383 deletions
+2 -1
View File
@@ -1164,7 +1164,8 @@ result_t BusHandler::prepareScan(symbol_t slave, bool full, const string& levels
if (m_device->isReadOnly()) { if (m_device->isReadOnly()) {
return RESULT_OK; return RESULT_OK;
} }
deque<Message*> messages = m_messages->findAll("scan", "", levels, true); deque<Message*> messages;
m_messages->findAll("scan", "", levels, true, true, false, false, true, true, 0, 0, &messages);
auto it = messages.begin(); auto it = messages.begin();
while (it != messages.end()) { while (it != messages.end()) {
Message* message = *it; Message* message = *it;
+272 -242
View File
File diff suppressed because it is too large Load Diff
+58 -40
View File
@@ -147,10 +147,11 @@ class MainLoop : public Thread, DeviceListener {
* @param listening set to true when the client is in listening mode. * @param listening set to true when the client is in listening mode.
* @param user set to the new user name when changed by authentication. * @param user set to the new user name when changed by authentication.
* @param reload set to true when the configuration files were reloaded. * @param reload set to true when the configuration files were reloaded.
* @return result string to send back to the client. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string decodeMessage(const string& data, bool isHttp, bool* connected, bool* listening, result_t decodeMessage(const string& data, bool isHttp, bool* connected, bool* listening,
string* user, bool* reload); string* user, bool* reload, ostringstream* ostream);
/** /**
* Parse the hex master message from the remaining arguments. * Parse the hex master message from the remaining arguments.
@@ -174,137 +175,154 @@ class MainLoop : public Thread, DeviceListener {
* Execute the auth command. * Execute the auth command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @param user the current user name to set to the new user name on success. * @param user the current user name to set to the new user name on success.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeAuth(const vector<string>& args, string* user); result_t executeAuth(const vector<string>& args, string* user, ostringstream* ostream);
/** /**
* Execute the read command. * Execute the read command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @param levels the current user's access levels. * @param levels the current user's access levels.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeRead(const vector<string>& args, const string& levels); result_t executeRead(const vector<string>& args, const string& levels, ostringstream* ostream);
/** /**
* Execute the write command. * Execute the write command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @param levels the current user's access levels. * @param levels the current user's access levels.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeWrite(const vector<string>& args, const string levels); result_t executeWrite(const vector<string>& args, const string levels, ostringstream* ostream);
/** /**
* Execute the hex command. * Execute the hex command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeHex(const vector<string>& args); result_t executeHex(const vector<string>& args, ostringstream* ostream);
/** /**
* Execute the find command. * Execute the find command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @param levels the current user's access levels. * @param levels the current user's access levels.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeFind(const vector<string>& args, const string& levels); result_t executeFind(const vector<string>& args, const string& levels, ostringstream* ostream);
/** /**
* Execute the listen command. * Execute the listen command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @param listening set to true when the client is in listening mode. * @param listening set to true when the client is in listening mode.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeListen(const vector<string>& args, bool* listening); result_t executeListen(const vector<string>& args, bool* listening, ostringstream* ostream);
/** /**
* Execute the state command. * Execute the state command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeState(const vector<string>& args); result_t executeState(const vector<string>& args, ostringstream* ostream);
/** /**
* Execute the grab command. * Execute the grab command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeGrab(const vector<string>& args); result_t executeGrab(const vector<string>& args, ostringstream* ostream);
/** /**
* Execute the scan command. * Execute the scan command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @param levels the current user's access levels. * @param levels the current user's access levels.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeScan(const vector<string>& args, const string levels); result_t executeScan(const vector<string>& args, const string& levels, ostringstream* ostream);
/** /**
* Execute the log command. * Execute the log command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeLog(const vector<string>& args); result_t executeLog(const vector<string>& args, ostringstream* ostream);
/** /**
* Execute the raw command. * Execute the raw command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeRaw(const vector<string>& args); result_t executeRaw(const vector<string>& args, ostringstream* ostream);
/** /**
* Execute the dump command. * Execute the dump command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeDump(const vector<string>& args); result_t executeDump(const vector<string>& args, ostringstream* ostream);
/** /**
* Execute the reload command. * Execute the reload command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeReload(const vector<string>& args); result_t executeReload(const vector<string>& args, ostringstream* ostream);
/** /**
* Execute the info command. * Execute the info command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @param user the current user name. * @param user the current user name.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeInfo(const vector<string>& args, const string& user); result_t executeInfo(const vector<string>& args, const string& user, ostringstream* ostream);
/** /**
* Execute the quit command. * Execute the quit command.
* @param args the arguments passed to the command (starting with the command itself), or empty for help. * @param args the arguments passed to the command (starting with the command itself), or empty for help.
* @param connected set to false when the client connection shall be closed. * @param connected set to false when the client connection shall be closed.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeQuit(const vector<string>& args, bool *connected); result_t executeQuit(const vector<string>& args, bool *connected, ostringstream* ostream);
/** /**
* Execute the help command. * Execute the help command.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeHelp(); result_t executeHelp(ostringstream* ostream);
/** /**
* Execute the HTTP GET command. * Execute the HTTP GET command.
* @param args the arguments passed to the command (starting with the command itself). * @param args the arguments passed to the command (starting with the command itself).
* @param connected set to false when the client connection shall be closed. * @param connected set to false when the client connection shall be closed.
* @return the result string. * @param ostream the @a ostringstream to format the result string to.
* @return the result code.
*/ */
string executeGet(const vector<string>& args, bool* connected); result_t executeGet(const vector<string>& args, bool* connected, ostringstream* ostream);
/** /**
* Format the HTTP answer to the result string. * Format the HTTP answer to the result string.
* @param ret the result code of handling the request. * @param ret the result code of handling the request.
* @param type the content type. * @param type the content type.
* @param result the @a ostringstream containing the successful result. * @param ostream the @a ostringstream to format the result string to.
* @return the result string. * @return the result code.
*/ */
string formatHttpResult(result_t ret, int type, ostringstream &result); result_t formatHttpResult(result_t ret, int type, ostringstream* ostream);
/** the @a Device instance. */ /** the @a Device instance. */
Device* m_device; Device* m_device;
+26 -25
View File
@@ -931,7 +931,7 @@ void Message::decode(bool leadingSeparator, OutputFormat outputFormat, ostringst
if (leadingSeparator) { if (leadingSeparator) {
*output << ","; *output << ",";
} }
*output << "\n \"" << getName() << "\": {" *output << "\n \"" << getName() << "\": {" // TODO include read/write/passive for overlapping names
<< "\n \"lastup\": " << setw(0) << dec << static_cast<unsigned>(getLastUpdateTime()); << "\n \"lastup\": " << setw(0) << dec << static_cast<unsigned>(getLastUpdateTime());
if (getLastUpdateTime() != 0) { if (getLastUpdateTime() != 0) {
*output << ",\n \"zz\": \"" << setfill('0') << setw(2) << hex << static_cast<unsigned>(getDstAddress()) << "\""; *output << ",\n \"zz\": \"" << setfill('0') << setw(2) << hex << static_cast<unsigned>(getDstAddress()) << "\"";
@@ -1626,31 +1626,31 @@ result_t Instruction::create(const string& contextPath, const string& type,
return RESULT_ERR_INVALID_ARG; return RESULT_ERR_INVALID_ARG;
} }
string Instruction::getDestination() const { void Instruction::getDestination(ostringstream* ostream) const {
// ZZ.circuit[.suffix] // ZZ.circuit[.suffix]
string ret; bool empty = true;
auto it = m_defaults.find("zz"); auto it = m_defaults.find("zz");
if (it != m_defaults.end() && !it->second.empty()) { if (it != m_defaults.end() && !it->second.empty()) {
ret = it->second; *ostream << it->second;
empty = false;
} }
it = m_defaults.find("circuit"); it = m_defaults.find("circuit");
string circuit = it == m_defaults.end() ? "" : it->second; string circuit = it == m_defaults.end() ? "" : it->second;
it = m_defaults.find("suffix"); it = m_defaults.find("suffix");
string suffix = it == m_defaults.end() ? "" : it->second; string suffix = it == m_defaults.end() ? "" : it->second;
if (!circuit.empty() || !suffix.empty()) { if (!circuit.empty() || !suffix.empty()) {
if (!ret.empty()) { if (!empty) {
ret += "."; *ostream << ".";
} }
if (circuit.empty()) { if (circuit.empty()) {
ret += "*"; *ostream << "*";
} else { } else {
ret += circuit; *ostream << circuit;
} }
if (!suffix.empty()) { if (!suffix.empty()) {
ret += suffix; *ostream << suffix;
} }
} }
return ret;
} }
@@ -1661,14 +1661,17 @@ result_t LoadInstruction::execute(MessageMap* messages, ostringstream* log) {
*log << ", "; *log << ", ";
} }
if (result != RESULT_OK) { if (result != RESULT_OK) {
*log << "error " << (isSingleton() ? "loading \"" : "including \"") << m_filename << "\" for \"" *log << "error " << (isSingleton() ? "loading \"" : "including \"") << m_filename << "\" for \"";
<< getDestination() << "\": " << getResultCode(result); getDestination(log);
*log << "\": " << getResultCode(result);
if (!errorDescription.empty()) { if (!errorDescription.empty()) {
*log << " " << errorDescription; *log << " " << errorDescription;
} }
return result; return result;
} }
*log << (isSingleton() ? "loaded \"" : "included \"") << m_filename << "\" for \"" << getDestination() << "\""; *log << (isSingleton() ? "loaded \"" : "included \"") << m_filename << "\" for \"";
getDestination(log);
*log << "\"";
if (isSingleton() && !m_defaults["zz"].empty()) { if (isSingleton() && !m_defaults["zz"].empty()) {
result_t temp; result_t temp;
symbol_t address = (symbol_t)parseInt(m_defaults["zz"].c_str(), 16, 0, 0xff, &temp); symbol_t address = (symbol_t)parseInt(m_defaults["zz"].c_str(), 16, 0, 0xff, &temp);
@@ -1678,7 +1681,7 @@ result_t LoadInstruction::execute(MessageMap* messages, ostringstream* log) {
ostringstream out; ostringstream out;
m_condition->dump(true, &out); m_condition->dump(true, &out);
comment = out.str(); comment = out.str();
*log << " ("+comment+")"; *log << " (" << comment << ")";
} }
messages->addLoadedFile(address, m_filename, comment); messages->addLoadedFile(address, m_filename, comment);
} }
@@ -2228,8 +2231,9 @@ result_t MessageMap::executeInstructions(void (*readMessageFunc)(Message* messag
&errorDescription); &errorDescription);
if (result != RESULT_OK) { if (result != RESULT_OK) {
overallResult = result; overallResult = result;
*log << "error resolving condition for \"" << instruction->getDestination() << "\": " *log << "error resolving condition for \"";
<< getResultCode(result); instruction->getDestination(log);
*log << "\": " << getResultCode(result);
if (!errorDescription.empty()) { if (!errorDescription.empty()) {
*log << " " << errorDescription; *log << " " << errorDescription;
} }
@@ -2364,11 +2368,9 @@ Message* MessageMap::find(const string& circuit, const string& name, const strin
return NULL; return NULL;
} }
deque<Message*> MessageMap::findAll(const string& circuit, const string& name, const string& levels, void MessageMap::findAll(const string& circuit, const string& name, const string& levels,
bool completeMatch, bool withRead, bool withWrite, bool withPassive, bool completeMatch, bool withRead, bool withWrite, bool withPassive, bool includeEmptyLevel, bool onlyAvailable,
bool includeEmptyLevel, bool onlyAvailable, time_t since, time_t until, deque<Message*>* messages) const {
time_t since, time_t until) const {
deque<Message*> ret;
string lcircuit = circuit; string lcircuit = circuit;
FileReader::tolower(&lcircuit); FileReader::tolower(&lcircuit);
string lname = name; string lname = name;
@@ -2422,12 +2424,10 @@ deque<Message*> MessageMap::findAll(const string& circuit, const string& name, c
} }
} }
if (!onlyAvailable || message->isAvailable()) { if (!onlyAvailable || message->isAvailable()) {
ret.push_back(message); messages->push_back(message);
} }
} }
} }
return ret;
} }
Message* MessageMap::find(const MasterSymbolString& master, bool anyDestination, Message* MessageMap::find(const MasterSymbolString& master, bool anyDestination,
@@ -2510,7 +2510,8 @@ void MessageMap::invalidateCache(Message* message) {
message->m_lastUpdateTime = 0; message->m_lastUpdateTime = 0;
string circuit = message->getCircuit(); string circuit = message->getCircuit();
string name = message->getName(); string name = message->getName();
deque<Message*> messages = findAll(circuit, name, "*", true, true, true, true); deque<Message*> messages;
findAll(circuit, name, "*", true, true, true, true, true, true, 0, 0, &messages);
for (auto checkMessage : messages) { for (auto checkMessage : messages) {
if (checkMessage != message) { if (checkMessage != message) {
checkMessage->m_lastUpdateTime = 0; checkMessage->m_lastUpdateTime = 0;
+8 -9
View File
@@ -1109,10 +1109,10 @@ class Instruction {
bool isSingleton() const { return m_singleton; } bool isSingleton() const { return m_singleton; }
/** /**
* Return a string describing the destination from the stored default values. * Format a string describing the destination from the stored default values.
* @return a string describing the destination. * @param ostream the @a ostringstream to format the string to.
*/ */
string getDestination() const; void getDestination(ostringstream* ostream) const;
/** /**
* Execute the instruction. * Execute the instruction.
@@ -1363,6 +1363,7 @@ class MessageMap : public MappedFileReader {
/** /**
* Find all active get @a Message instances for the specified circuit and name. * Find all active get @a Message instances for the specified circuit and name.
* Note: the caller may not free the returned instances.
* @param circuit the circuit name, or empty for any. * @param circuit the circuit name, or empty for any.
* @param name the message name, or empty for any. * @param name the message name, or empty for any.
* @param levels the access levels to match. * @param levels the access levels to match.
@@ -1371,7 +1372,6 @@ class MessageMap : public MappedFileReader {
* @param withRead true to include read messages (default true). * @param withRead true to include read messages (default true).
* @param withWrite true to include write messages (default false). * @param withWrite true to include write messages (default false).
* @param withPassive true to include passive messages (default false). * @param withPassive true to include passive messages (default false).
* @return the found @a Message instances.
* @param includeEmptyLevel true to also include messages with no access level, false to include only messages with * @param includeEmptyLevel true to also include messages with no access level, false to include only messages with
* the specified level. * the specified level.
* @param onlyAvailable true to include only available messages (default true), false to also include messages that * @param onlyAvailable true to include only available messages (default true), false to also include messages that
@@ -1380,12 +1380,11 @@ class MessageMap : public MappedFileReader {
* address), or 0 to ignore. * address), or 0 to ignore.
* @param until the end time to which to add updates (exclusive, also removes messages with unset destination * @param until the end time to which to add updates (exclusive, also removes messages with unset destination
* address), or 0 to ignore. * address), or 0 to ignore.
* Note: the caller may not free the returned instances. * @param messages the @a deque to which to add the found @a Message instances.
*/ */
deque<Message*> findAll(const string& circuit, const string& name, const string& levels, void findAll(const string& circuit, const string& name, const string& levels,
bool completeMatch = true, bool withRead = true, bool withWrite = false, bool completeMatch, bool withRead, bool withWrite, bool withPassive, bool includeEmptyLevel, bool onlyAvailable,
bool withPassive = false, bool includeEmptyLevel = true, bool onlyAvailable = true, time_t since, time_t until, deque<Message*>* messages) const;
time_t since = 0, time_t until = 0) const;
/** /**
* Find the @a Message instance for the specified master data. * Find the @a Message instance for the specified master data.
+2 -1
View File
@@ -317,7 +317,8 @@ int main() {
if (onlyMap) { if (onlyMap) {
continue; continue;
} }
deque<Message*> msgs = messages->findAll("", "", "*", false, true, true, true, true, false); deque<Message*> msgs;
messages->findAll("", "", "*", false, true, true, true, true, false, 0, 0, &msgs);
if (msgs.empty()) { if (msgs.empty()) {
message = NULL; message = NULL;
cout << "\"" << check[0] << "\": create error: message not found" << endl; cout << "\"" << check[0] << "\": create error: message not found" << endl;