new enum type for OutputFormat, add level/pollprio/condition to HTTP GET and extend message key by circuit/direction/condition for OF_ALL_ATTRS, start message dump in JSON format
This commit is contained in:
@@ -130,7 +130,7 @@ bool ScanRequest::notify(result_t result, const SlaveSymbolString& slave) {
|
||||
}
|
||||
if (result == RESULT_OK) {
|
||||
ostringstream output;
|
||||
result = m_message->decodeLastData(true, nullptr, -1, 0, &output); // decode data
|
||||
result = m_message->decodeLastData(true, nullptr, -1, OF_NONE, &output); // decode data
|
||||
string str = output.str();
|
||||
m_busHandler->setScanResult(dstAddress, m_notifyIndex+m_index, str);
|
||||
}
|
||||
@@ -216,7 +216,7 @@ bool decodeType(const DataType* type, const SymbolString& input, size_t length,
|
||||
string in = input.getStr(input.getDataOffset());
|
||||
for (size_t offset = 0; offset <= offsets; offset++) {
|
||||
ostringstream out;
|
||||
result_t result = type->readSymbols(offset, length, input, 0, &out);
|
||||
result_t result = type->readSymbols(offset, length, input, OF_NONE, &out);
|
||||
if (result != RESULT_OK) {
|
||||
continue;
|
||||
}
|
||||
@@ -231,7 +231,7 @@ bool decodeType(const DataType* type, const SymbolString& input, size_t length,
|
||||
first = false;
|
||||
*output << endl << " ";
|
||||
ostringstream::pos_type cnt = output->tellp();
|
||||
type->dump(false, length, false, output);
|
||||
type->dump(OF_NONE, length, false, output);
|
||||
cnt = output->tellp() - cnt;
|
||||
while (cnt < 5) {
|
||||
*output << " ";
|
||||
@@ -1156,7 +1156,7 @@ void BusHandler::messageCompleted() {
|
||||
result = message->storeLastData(0, idData);
|
||||
if (result == RESULT_OK) {
|
||||
ostringstream output;
|
||||
result = message->decodeLastData(true, nullptr, -1, 0, &output);
|
||||
result = message->decodeLastData(true, nullptr, -1, OF_NONE, &output);
|
||||
if (result == RESULT_OK) {
|
||||
string str = output.str();
|
||||
setScanResult(slaveAddress, 0, str);
|
||||
@@ -1176,7 +1176,7 @@ void BusHandler::messageCompleted() {
|
||||
result_t result = message->storeLastData(m_command, m_response);
|
||||
if (result == RESULT_OK) {
|
||||
ostringstream output;
|
||||
result = message->decodeLastData(true, nullptr, -1, 0, &output);
|
||||
result = message->decodeLastData(true, nullptr, -1, OF_NONE, &output);
|
||||
if (result == RESULT_OK) {
|
||||
string str = output.str();
|
||||
setScanResult(dstAddress, 0, str);
|
||||
@@ -1216,7 +1216,7 @@ void BusHandler::messageCompleted() {
|
||||
result_t result = message->storeLastData(m_command, m_response);
|
||||
ostringstream output;
|
||||
if (result == RESULT_OK) {
|
||||
result = message->decodeLastData(false, nullptr, -1, 0, &output);
|
||||
result = message->decodeLastData(false, nullptr, -1, OF_NONE, &output);
|
||||
}
|
||||
if (result < RESULT_OK) {
|
||||
logError(lf_update, "unable to parse %s %s %s from %s / %s: %s", mode, circuit.c_str(), name.c_str(),
|
||||
@@ -1380,7 +1380,7 @@ void BusHandler::formatScanResult(ostringstream* output) const {
|
||||
*output << endl;
|
||||
}
|
||||
*output << hex << setw(2) << setfill('0') << static_cast<unsigned>(slave);
|
||||
message->decodeLastData(true, nullptr, -1, 0, output);
|
||||
message->decodeLastData(true, nullptr, -1, OF_NONE, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1029,7 +1029,7 @@ result_t loadScanConfigFile(MessageMap* messages, symbol_t address, bool verbose
|
||||
size_t offset = 0;
|
||||
size_t field = 0;
|
||||
bool fromLocal = s_configUriPrefix.empty();
|
||||
result_t result = (*identFields)[field]->read(data, offset, false, nullptr, -1, 0, -1, &out); // manufacturer name
|
||||
result_t result = (*identFields)[field]->read(data, offset, false, nullptr, -1, OF_NONE, -1, &out); // manufacturer name
|
||||
if (result == RESULT_ERR_NOTFOUND && fromLocal) {
|
||||
result = (*identFields)[field]->read(data, offset, false, nullptr, -1, OF_NUMERIC, -1, &out); // manufacturer name
|
||||
}
|
||||
@@ -1042,7 +1042,7 @@ result_t loadScanConfigFile(MessageMap* messages, symbol_t address, bool verbose
|
||||
out.str("");
|
||||
out.clear();
|
||||
offset += (*identFields)[field++]->getLength(pt_slaveData, MAX_LEN);
|
||||
result = (*identFields)[field]->read(data, offset, false, nullptr, -1, 0, -1, &out); // identification string
|
||||
result = (*identFields)[field]->read(data, offset, false, nullptr, -1, OF_NONE, -1, &out); // identification string
|
||||
}
|
||||
if (result == RESULT_OK) {
|
||||
ident = out.str();
|
||||
@@ -1307,7 +1307,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
if (result == RESULT_OK && opt.dumpConfig) {
|
||||
logNotice(lf_main, "configuration dump:");
|
||||
s_messageMap->dump(true, &cout);
|
||||
s_messageMap->dump(true, OF_NONE, &cout);
|
||||
}
|
||||
|
||||
shutdown(overallResult != RESULT_OK);
|
||||
|
||||
+56
-63
@@ -98,6 +98,13 @@ result_t UserList::addFromFile(const string& filename, unsigned int lineNo, map<
|
||||
}
|
||||
|
||||
|
||||
#define VERBOSITY_0 OF_NONE
|
||||
#define VERBOSITY_1 OF_NAMES
|
||||
#define VERBOSITY_2 (VERBOSITY_1 | OF_UNITS)
|
||||
#define VERBOSITY_3 (VERBOSITY_2 | OF_COMMENTS)
|
||||
#define VERBOSITY_4 (VERBOSITY_3 | OF_ALL_ATTRS)
|
||||
|
||||
|
||||
MainLoop::MainLoop(const struct options& opt, Device *device, MessageMap* messages)
|
||||
: Thread(), m_device(device), m_reconnectCount(0), m_userList(opt.accessLevel), m_messages(messages),
|
||||
m_address(opt.address), m_scanConfig(opt.scanConfig), m_initialScan(opt.readOnly ? ESC : opt.initialScan),
|
||||
@@ -702,7 +709,7 @@ result_t MainLoop::executeAuth(const vector<string>& args, string* user, ostring
|
||||
result_t MainLoop::executeRead(const vector<string>& args, const string& levels, ostringstream* ostream) {
|
||||
size_t argPos = 1;
|
||||
bool hex = false, newDefinition = false;
|
||||
OutputFormat verbosity = 0;
|
||||
OutputFormat verbosity = OF_NONE;
|
||||
time_t maxAge = 5*60;
|
||||
string circuit, params;
|
||||
symbol_t srcAddress = SYN, dstAddress = SYN;
|
||||
@@ -732,21 +739,17 @@ result_t MainLoop::executeRead(const vector<string>& args, const string& levels,
|
||||
break;
|
||||
}
|
||||
} else if (args[argPos] == "-v") {
|
||||
switch (verbosity) {
|
||||
case 0:
|
||||
verbosity = OF_NAMES;
|
||||
break;
|
||||
case OF_NAMES:
|
||||
verbosity |= OF_UNITS;
|
||||
break;
|
||||
case OF_NAMES|OF_UNITS:
|
||||
verbosity |= OF_COMMENTS;
|
||||
break;
|
||||
if ((verbosity & VERBOSITY_3) == VERBOSITY_0) {
|
||||
verbosity |= VERBOSITY_1;
|
||||
} else if ((verbosity & VERBOSITY_3) == VERBOSITY_1) {
|
||||
verbosity |= VERBOSITY_2;
|
||||
} else {
|
||||
verbosity |= VERBOSITY_3;
|
||||
}
|
||||
} else if (args[argPos] == "-vv") {
|
||||
verbosity |= OF_NAMES|OF_UNITS;
|
||||
verbosity |= VERBOSITY_2;
|
||||
} else if (args[argPos] == "-vvv" || args[argPos] == "-V") {
|
||||
verbosity |= OF_NAMES|OF_UNITS|OF_COMMENTS;
|
||||
verbosity |= VERBOSITY_3;
|
||||
} else if (args[argPos] == "-n") {
|
||||
verbosity = (verbosity & ~OF_VALUENAME) | OF_NUMERIC;
|
||||
} else if (args[argPos] == "-N") {
|
||||
@@ -799,7 +802,7 @@ result_t MainLoop::executeRead(const vector<string>& args, const string& levels,
|
||||
}
|
||||
argPos++;
|
||||
}
|
||||
if ((hex && (newDefinition || verbosity != 0 || !circuit.empty() || !params.empty() || dstAddress != SYN
|
||||
if ((hex && (newDefinition || verbosity != OF_NONE || !circuit.empty() || !params.empty() || dstAddress != SYN
|
||||
|| pollPriority > 0 || args.size() < argPos + 1))
|
||||
|| (newDefinition && (hex || !circuit.empty() || pollPriority > 0 || args.size() != argPos + 1))) {
|
||||
argPos = 0; // print usage
|
||||
@@ -882,7 +885,7 @@ result_t MainLoop::executeRead(const vector<string>& args, const string& levels,
|
||||
ret = message->storeLastData(master, slave);
|
||||
ostringstream result;
|
||||
if (ret == RESULT_OK) {
|
||||
ret = message->decodeLastData(false, nullptr, -1, 0, &result);
|
||||
ret = message->decodeLastData(false, nullptr, -1, OF_NONE, &result);
|
||||
}
|
||||
if (ret >= RESULT_OK) {
|
||||
logInfo(lf_main, "read hex %s %s cache update: %s", message->getCircuit().c_str(), message->getName().c_str(),
|
||||
@@ -1107,7 +1110,7 @@ result_t MainLoop::executeWrite(const vector<string>& args, const string levels,
|
||||
ret = message->storeLastData(master, slave);
|
||||
ostringstream result;
|
||||
if (ret == RESULT_OK) {
|
||||
ret = message->decodeLastData(false, nullptr, -1, 0, &result);
|
||||
ret = message->decodeLastData(false, nullptr, -1, OF_NONE, &result);
|
||||
}
|
||||
if (ret >= RESULT_OK) {
|
||||
logInfo(lf_main, "write hex %s %s cache update: %s", message->getCircuit().c_str(),
|
||||
@@ -1178,7 +1181,7 @@ result_t MainLoop::executeWrite(const vector<string>& args, const string levels,
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
ret = message->decodeLastData(false, false, nullptr, -1, 0, ostream); // decode data
|
||||
ret = message->decodeLastData(false, false, nullptr, -1, OF_NONE, ostream); // decode data
|
||||
if (ret >= RESULT_OK && ostream->str().empty()) {
|
||||
logNotice(lf_main, "write %s %s: decode %s", message->getCircuit().c_str(), message->getName().c_str(),
|
||||
getResultCode(ret));
|
||||
@@ -1325,29 +1328,27 @@ result_t MainLoop::executeFind(const vector<string>& args, const string& levels,
|
||||
bool configFormat = false, exact = false, withRead = true, withWrite = false, withPassive = true, first = true,
|
||||
onlyWithData = false, hexFormat = false, userLevel = true, withConditions = false;
|
||||
string useLevels = levels;
|
||||
OutputFormat verbosity = 0;
|
||||
OutputFormat verbosity = OF_NONE;
|
||||
vector<string> fieldNames;
|
||||
string circuit;
|
||||
vector<symbol_t> id;
|
||||
while (args.size() > argPos && args[argPos][0] == '-') {
|
||||
if (args[argPos] == "-v") {
|
||||
switch (verbosity) {
|
||||
case 0:
|
||||
verbosity |= OF_NAMES;
|
||||
break;
|
||||
case OF_NAMES:
|
||||
verbosity |= OF_UNITS;
|
||||
break;
|
||||
case OF_NAMES|OF_UNITS:
|
||||
verbosity |= OF_COMMENTS;
|
||||
break;
|
||||
if ((verbosity & VERBOSITY_4) == VERBOSITY_0) {
|
||||
verbosity |= VERBOSITY_1;
|
||||
} else if ((verbosity & VERBOSITY_4) == VERBOSITY_1) {
|
||||
verbosity |= VERBOSITY_2;
|
||||
} else if ((verbosity & VERBOSITY_4) == VERBOSITY_2) {
|
||||
verbosity |= VERBOSITY_3;
|
||||
} else {
|
||||
verbosity |= VERBOSITY_4;
|
||||
}
|
||||
} else if (args[argPos] == "-vv") {
|
||||
verbosity |= OF_NAMES|OF_UNITS;
|
||||
verbosity |= VERBOSITY_2;
|
||||
} else if (args[argPos] == "-vvv") {
|
||||
verbosity |= OF_NAMES|OF_UNITS|OF_COMMENTS;
|
||||
} else if (args[argPos] == "-V") {
|
||||
verbosity |= OF_NAMES|OF_UNITS|OF_COMMENTS|OF_ALL_ATTRS;
|
||||
verbosity |= VERBOSITY_3;
|
||||
} else if (args[argPos] == "-vvvv" || args[argPos] == "-V") {
|
||||
verbosity |= VERBOSITY_4;
|
||||
} else if (args[argPos] == "-f") {
|
||||
configFormat = true;
|
||||
if (hexFormat) {
|
||||
@@ -1470,12 +1471,12 @@ result_t MainLoop::executeFind(const vector<string>& args, const string& levels,
|
||||
if (found) {
|
||||
*ostream << endl;
|
||||
}
|
||||
message->dump(nullptr, withConditions, ostream);
|
||||
message->dump(nullptr, withConditions, verbosity, ostream);
|
||||
} else if (!fieldNames.empty()) {
|
||||
if (found) {
|
||||
*ostream << endl;
|
||||
}
|
||||
message->dump(&fieldNames, withConditions, ostream);
|
||||
message->dump(&fieldNames, withConditions, verbosity, ostream);
|
||||
} else {
|
||||
if (found) {
|
||||
*ostream << endl;
|
||||
@@ -1496,7 +1497,7 @@ result_t MainLoop::executeFind(const vector<string>& args, const string& levels,
|
||||
<< " / " << message->getLastSlaveData().getStr() << ")";
|
||||
}
|
||||
}
|
||||
if ((verbosity & (OF_NAMES|OF_UNITS|OF_COMMENTS)) == (OF_NAMES|OF_UNITS|OF_COMMENTS)) {
|
||||
if ((verbosity & VERBOSITY_3) == VERBOSITY_3) {
|
||||
symbol_t dstAddress = message->getDstAddress();
|
||||
if (dstAddress != SYN) {
|
||||
snprintf(str, sizeof(str), "%02x", dstAddress);
|
||||
@@ -1536,26 +1537,22 @@ result_t MainLoop::executeFind(const vector<string>& args, const string& levels,
|
||||
|
||||
result_t MainLoop::executeListen(const vector<string>& args, ClientSettings* settings, ostringstream* ostream) {
|
||||
size_t argPos = 1;
|
||||
OutputFormat verbosity = 0;
|
||||
OutputFormat verbosity = OF_NONE;
|
||||
bool listenWithUnknown = false;
|
||||
bool listenOnlyUnknown = false;
|
||||
while (args.size() > argPos && args[argPos][0] == '-') {
|
||||
if (args[argPos] == "-v") {
|
||||
switch (verbosity) {
|
||||
case 0:
|
||||
verbosity = OF_NAMES;
|
||||
break;
|
||||
case OF_NAMES:
|
||||
verbosity |= OF_UNITS;
|
||||
break;
|
||||
case OF_NAMES|OF_UNITS:
|
||||
verbosity |= OF_COMMENTS;
|
||||
break;
|
||||
if ((verbosity & VERBOSITY_3) == VERBOSITY_0) {
|
||||
verbosity |= VERBOSITY_1;
|
||||
} else if ((verbosity & VERBOSITY_3) == VERBOSITY_1) {
|
||||
verbosity |= VERBOSITY_2;
|
||||
} else {
|
||||
verbosity |= VERBOSITY_3;
|
||||
}
|
||||
} else if (args[argPos] == "-vv") {
|
||||
verbosity |= OF_NAMES|OF_UNITS;
|
||||
verbosity |= VERBOSITY_2;
|
||||
} else if (args[argPos] == "-vvv" || args[argPos] == "-V") {
|
||||
verbosity |= OF_NAMES|OF_UNITS|OF_COMMENTS;
|
||||
verbosity |= VERBOSITY_3;
|
||||
} else if (args[argPos] == "-n") {
|
||||
verbosity = (verbosity & ~OF_VALUENAME) | OF_NUMERIC;
|
||||
} else if (args[argPos] == "-N") {
|
||||
@@ -1686,24 +1683,20 @@ result_t MainLoop::executeDefine(const vector<string>& args, ostringstream* ostr
|
||||
|
||||
result_t MainLoop::executeDecode(const vector<string>& args, ostringstream* ostream) {
|
||||
size_t argPos = 1;
|
||||
OutputFormat verbosity = 0;
|
||||
OutputFormat verbosity = OF_NONE;
|
||||
while (args.size() > argPos && args[argPos][0] == '-') {
|
||||
if (args[argPos] == "-v") {
|
||||
switch (verbosity) {
|
||||
case 0:
|
||||
verbosity = OF_NAMES;
|
||||
break;
|
||||
case OF_NAMES:
|
||||
verbosity |= OF_UNITS;
|
||||
break;
|
||||
case OF_NAMES|OF_UNITS:
|
||||
verbosity |= OF_COMMENTS;
|
||||
break;
|
||||
if ((verbosity & VERBOSITY_3) == VERBOSITY_0) {
|
||||
verbosity |= VERBOSITY_1;
|
||||
} else if ((verbosity & VERBOSITY_3) == VERBOSITY_1) {
|
||||
verbosity |= VERBOSITY_2;
|
||||
} else {
|
||||
verbosity |= VERBOSITY_3;
|
||||
}
|
||||
} else if (args[argPos] == "-vv") {
|
||||
verbosity |= OF_NAMES|OF_UNITS;
|
||||
verbosity |= VERBOSITY_2;
|
||||
} else if (args[argPos] == "-vvv" || args[argPos] == "-V") {
|
||||
verbosity |= OF_NAMES|OF_UNITS|OF_COMMENTS;
|
||||
verbosity |= VERBOSITY_3;
|
||||
} else if (args[argPos] == "-n") {
|
||||
verbosity = (verbosity & ~OF_VALUENAME) | OF_NUMERIC;
|
||||
} else if (args[argPos] == "-N") {
|
||||
@@ -2096,7 +2089,7 @@ result_t MainLoop::executeGet(const vector<string>& args, bool* connected, ostri
|
||||
time_t maxLastUp = 0;
|
||||
if (ret == RESULT_OK) {
|
||||
bool first = true;
|
||||
verbosity |= OF_JSON | (full ? OF_ALL_ATTRS : 0) | (withDefinition ? OF_DEFINTION : 0);
|
||||
verbosity |= OF_JSON | (full ? OF_ALL_ATTRS : OF_NONE) | (withDefinition ? OF_DEFINITION : OF_NONE);
|
||||
deque<Message*> messages;
|
||||
m_messages->findAll(circuit, name, getUserLevels(user), exact, true, withWrite, true, true, true, 0, 0, false,
|
||||
&messages);
|
||||
@@ -2147,7 +2140,7 @@ result_t MainLoop::executeGet(const vector<string>& args, bool* connected, ostri
|
||||
Message* next = *(it+1);
|
||||
same = next->getCircuit() == lastCircuit && next->getName() == name;
|
||||
}
|
||||
message->decodeJson(!first, same, raw, verbosity, ostream);
|
||||
message->decodeJson(!first, same, true, raw, verbosity, ostream);
|
||||
lastName = name;
|
||||
first = false;
|
||||
}
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ class NetMessage {
|
||||
explicit NetMessage(bool isHttp)
|
||||
: m_isHttp(isHttp), m_resultSet(false), m_disconnect(false), m_listenSince(0) {
|
||||
m_settings.mode = cm_normal;
|
||||
m_settings.format = 0;
|
||||
m_settings.format = OF_NONE;
|
||||
m_settings.listenWithUnknown = false;
|
||||
m_settings.listenOnlyUnknown = false;
|
||||
pthread_mutex_init(&m_mutex, nullptr);
|
||||
|
||||
@@ -178,7 +178,7 @@ int main() {
|
||||
continue;
|
||||
}
|
||||
cout << "\"" << check[0] << "\"=\"";
|
||||
fields->dump(false, false, &cout);
|
||||
fields->dump(false, OF_NONE, &cout);
|
||||
cout << "\": create OK" << endl;
|
||||
|
||||
ostringstream output;
|
||||
@@ -194,9 +194,9 @@ int main() {
|
||||
cout << " parse \"" << sstr.getStr().substr(0, 2) << "\" error: " << getResultCode(result) << endl;
|
||||
error = true;
|
||||
}
|
||||
result = fields->read(mstr, 0, false, nullptr, -1, 0, -1, &output);
|
||||
result = fields->read(mstr, 0, false, nullptr, -1, OF_NONE, -1, &output);
|
||||
if (result >= RESULT_OK) {
|
||||
result = fields->read(sstr, 0, !output.str().empty(), nullptr, -1, 0, -1, &output);
|
||||
result = fields->read(sstr, 0, !output.str().empty(), nullptr, -1, OF_NONE, -1, &output);
|
||||
}
|
||||
if (failedRead) {
|
||||
if (result >= RESULT_OK) {
|
||||
|
||||
+33
-33
@@ -67,6 +67,7 @@ string AttributedItem::pluck(const string& key, map<string, string>* row) {
|
||||
}
|
||||
|
||||
void AttributedItem::dumpString(bool prependFieldSeparator, const string& str, ostream* output) {
|
||||
// not to be used for JSON format
|
||||
if (prependFieldSeparator) {
|
||||
*output << FIELD_SEPARATOR;
|
||||
}
|
||||
@@ -102,7 +103,7 @@ void AttributedItem::appendJson(bool prependFieldSeparator, const string& name,
|
||||
}
|
||||
}
|
||||
if (prependFieldSeparator) {
|
||||
*output << FIELD_SEPARATOR;
|
||||
*output << ",";
|
||||
}
|
||||
*output << " \"" << name << "\": ";
|
||||
if (plain) {
|
||||
@@ -129,9 +130,9 @@ void AttributedItem::mergeAttributes(map<string, string>* attributes) const {
|
||||
}
|
||||
}
|
||||
|
||||
void AttributedItem::dumpAttribute(bool prependFieldSeparator, bool asJson, const string& name, ostream* output)
|
||||
void AttributedItem::dumpAttribute(bool prependFieldSeparator, OutputFormat outputFormat, const string& name, ostream* output)
|
||||
const {
|
||||
if (asJson) {
|
||||
if (outputFormat & OF_JSON) {
|
||||
appendJson(prependFieldSeparator, name, getAttribute(name), false, output);
|
||||
} else {
|
||||
dumpString(prependFieldSeparator, getAttribute(name), output);
|
||||
@@ -171,7 +172,7 @@ bool AttributedItem::appendAttributes(OutputFormat outputFormat, ostream* output
|
||||
result_t result = RESULT_EMPTY;
|
||||
size_t addr = parseInt(entry.second.c_str(), 16, 0, 255, &result);
|
||||
if (result == RESULT_OK) {
|
||||
*output << FIELD_SEPARATOR << " \"" << key << "\": " << addr;
|
||||
*output << ", \"" << key << "\": " << addr;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -469,44 +470,43 @@ result_t SingleDataField::create(const string& name, const map<string, string>&
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
void SingleDataField::dumpPrefix(bool prependFieldSeparator, bool asJson, ostream* output) const {
|
||||
void SingleDataField::dumpPrefix(bool prependFieldSeparator, OutputFormat outputFormat, ostream* output) const {
|
||||
*output << setw(0) << dec; // initialize formatting
|
||||
if (asJson) {
|
||||
if (outputFormat & OF_JSON) {
|
||||
if (prependFieldSeparator) {
|
||||
*output << FIELD_SEPARATOR;
|
||||
*output << ",";
|
||||
}
|
||||
*output << "\n {";
|
||||
appendJson(false, "name", m_name, true, output);
|
||||
} else {
|
||||
dumpString(prependFieldSeparator, m_name, output);
|
||||
}
|
||||
*output << FIELD_SEPARATOR;
|
||||
if (asJson) {
|
||||
*output << " \"slave\": " << (m_partType == pt_slaveData ? "true" : "false") << ", ";
|
||||
if (outputFormat & OF_JSON) {
|
||||
*output << ", \"slave\": " << (m_partType == pt_slaveData ? "true" : "false") << ", ";
|
||||
} else {
|
||||
*output << FIELD_SEPARATOR;
|
||||
if (m_partType == pt_masterData) {
|
||||
*output << "m";
|
||||
} else if (m_partType == pt_slaveData) {
|
||||
*output << "s";
|
||||
}
|
||||
}
|
||||
if (!asJson) {
|
||||
*output << FIELD_SEPARATOR;
|
||||
}
|
||||
m_dataType->dump(asJson, m_length, true, output);
|
||||
m_dataType->dump(outputFormat, m_length, true, output);
|
||||
}
|
||||
|
||||
void SingleDataField::dumpSuffix(bool asJson, ostream* output) const {
|
||||
dumpAttribute(true, asJson, "unit", output);
|
||||
dumpAttribute(true, asJson, "comment", output);
|
||||
if (asJson) {
|
||||
void SingleDataField::dumpSuffix(OutputFormat outputFormat, ostream* output) const {
|
||||
dumpAttribute(true, outputFormat, "unit", output);
|
||||
dumpAttribute(true, outputFormat, "comment", output);
|
||||
if (outputFormat & OF_JSON) {
|
||||
appendAttributes(outputFormat & ~(OF_UNITS|OF_COMMENTS), output);
|
||||
*output << "}";
|
||||
}
|
||||
}
|
||||
|
||||
void SingleDataField::dump(bool prependFieldSeparator, bool asJson, ostream* output) const {
|
||||
dumpPrefix(prependFieldSeparator, asJson, output);
|
||||
dumpSuffix(asJson, output);
|
||||
void SingleDataField::dump(bool prependFieldSeparator, OutputFormat outputFormat, ostream* output) const {
|
||||
dumpPrefix(prependFieldSeparator, outputFormat, output);
|
||||
dumpSuffix(outputFormat, output);
|
||||
}
|
||||
|
||||
result_t SingleDataField::read(const SymbolString& data, size_t offset,
|
||||
@@ -557,7 +557,7 @@ result_t SingleDataField::read(const SymbolString& data, size_t offset,
|
||||
*output << "\"" << static_cast<signed int>(outputIndex < 0 ? 0 : outputIndex) << "\":";
|
||||
}
|
||||
if (!shortFormat) {
|
||||
*output << " {\"name\": \"" << m_name << "\"" << ", \"value\": ";
|
||||
*output << " {\"name\": \"" << m_name << "\", \"value\": ";
|
||||
}
|
||||
} else {
|
||||
if (fieldIndex < 0) {
|
||||
@@ -722,11 +722,11 @@ result_t ValueListDataField::derive(const string& name, PartType partType, int d
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
void ValueListDataField::dump(bool prependFieldSeparator, bool asJson, ostream* output) const {
|
||||
dumpPrefix(prependFieldSeparator, asJson, output);
|
||||
void ValueListDataField::dump(bool prependFieldSeparator, OutputFormat outputFormat, ostream* output) const {
|
||||
dumpPrefix(prependFieldSeparator, outputFormat, output);
|
||||
// no divisor appended since it is not allowed for ValueListDataField
|
||||
bool first = true;
|
||||
if (asJson) {
|
||||
if (outputFormat & OF_JSON) {
|
||||
*output << ", \"values\": {";
|
||||
for (const auto it : m_values) {
|
||||
appendJson(!first, formatInt(it.first), it.second, true, output); // TODO optimize?
|
||||
@@ -743,7 +743,7 @@ void ValueListDataField::dump(bool prependFieldSeparator, bool asJson, ostream*
|
||||
*output << it.first << "=" << it.second;
|
||||
}
|
||||
}
|
||||
dumpSuffix(asJson, output);
|
||||
dumpSuffix(outputFormat, output);
|
||||
}
|
||||
|
||||
result_t ValueListDataField::readSymbols(const SymbolString& input, size_t offset,
|
||||
@@ -838,22 +838,22 @@ result_t ConstantDataField::derive(const string& name, PartType partType, int di
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
void ConstantDataField::dump(bool prependFieldSeparator, bool asJson, ostream* output) const {
|
||||
dumpPrefix(prependFieldSeparator, asJson, output);
|
||||
void ConstantDataField::dump(bool prependFieldSeparator, OutputFormat outputFormat, ostream* output) const {
|
||||
dumpPrefix(prependFieldSeparator, outputFormat, output);
|
||||
// no divisor appended since it is not allowed for ConstantDataField
|
||||
if (asJson) {
|
||||
if (outputFormat & OF_JSON) {
|
||||
appendJson(false, "value", m_value, true, output);
|
||||
*output << ", \"verify\":" << (m_verify ? "true" : "false");
|
||||
*output << ", \"verify\": " << (m_verify ? "true" : "false");
|
||||
} else {
|
||||
*output << (m_verify?"==":"=") << m_value;
|
||||
}
|
||||
dumpSuffix(asJson, output);
|
||||
dumpSuffix(outputFormat, output);
|
||||
}
|
||||
|
||||
result_t ConstantDataField::readSymbols(const SymbolString& input, size_t offset,
|
||||
OutputFormat outputFormat, ostream* output) const {
|
||||
ostringstream coutput;
|
||||
result_t result = SingleDataField::readSymbols(input, offset, 0, &coutput);
|
||||
result_t result = SingleDataField::readSymbols(input, offset, outputFormat, &coutput);
|
||||
if (result != RESULT_OK) {
|
||||
return result;
|
||||
}
|
||||
@@ -1024,9 +1024,9 @@ bool DataFieldSet::hasField(const char* fieldName, bool numeric) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void DataFieldSet::dump(bool prependFieldSeparator, bool asJson, ostream* output) const {
|
||||
void DataFieldSet::dump(bool prependFieldSeparator, OutputFormat outputFormat, ostream* output) const {
|
||||
for (const auto field : m_fields) {
|
||||
field->dump(prependFieldSeparator, asJson, output);
|
||||
field->dump(prependFieldSeparator, outputFormat, output);
|
||||
prependFieldSeparator = true;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-12
@@ -122,11 +122,11 @@ class AttributedItem {
|
||||
/**
|
||||
* Dump the attribute optionally embedded in @a TEXT_SEPARATOR to the output.
|
||||
* @param prependFieldSeparator whether to start with a @a FIELD_SEPARATOR.
|
||||
* @param asJson whether to output in JSON format.
|
||||
* @param outputFormat the @a OutputFormat options.
|
||||
* @param name the name of the attribute to dump.
|
||||
* @param output the @a ostream to dump to.
|
||||
*/
|
||||
void dumpAttribute(bool prependFieldSeparator, bool asJson, const string& name, ostream* output) const;
|
||||
void dumpAttribute(bool prependFieldSeparator, OutputFormat outputFormat, const string& name, ostream* output) const;
|
||||
|
||||
/**
|
||||
* Append the attribute value to the output.
|
||||
@@ -273,10 +273,10 @@ class DataField : public AttributedItem {
|
||||
/**
|
||||
* Dump the field settings to the output.
|
||||
* @param prependFieldSeparator whether to start with a @a FIELD_SEPARATOR.
|
||||
* @param asJson whether to output in JSON format.
|
||||
* @param outputFormat the @a OutputFormat options.
|
||||
* @param output the @a ostream to dump to.
|
||||
*/
|
||||
virtual void dump(bool prependFieldSeparator, bool asJson, ostream* output) const = 0;
|
||||
virtual void dump(bool prependFieldSeparator, OutputFormat outputFormat, ostream* output) const = 0;
|
||||
|
||||
/**
|
||||
* Return whether the field is available.
|
||||
@@ -420,20 +420,20 @@ class SingleDataField : public DataField {
|
||||
/**
|
||||
* Dump the common prefix field settings to the output (name and part type).
|
||||
* @param prependFieldSeparator whether to start with a @a FIELD_SEPARATOR.
|
||||
* @param asJson whether to output in JSON format.
|
||||
* @param outputFormat the @a OutputFormat options.
|
||||
* @param output the @a ostream to dump to.
|
||||
*/
|
||||
void dumpPrefix(bool prependFieldSeparator, bool asJson, ostream* output) const;
|
||||
void dumpPrefix(bool prependFieldSeparator, OutputFormat outputFormat, ostream* output) const;
|
||||
|
||||
/**
|
||||
* Dump the common suffix field settings to the output (optional unit and comment).
|
||||
* @param asJson whether to output in JSON format.
|
||||
* @param outputFormat the @a OutputFormat options.
|
||||
* @param output the @a ostream to dump to.
|
||||
*/
|
||||
void dumpSuffix(bool asJson, ostream* output) const;
|
||||
void dumpSuffix(OutputFormat outputFormat, ostream* output) const;
|
||||
|
||||
// @copydoc
|
||||
void dump(bool prependFieldSeparator, bool asJson, ostream* output) const override;
|
||||
void dump(bool prependFieldSeparator, OutputFormat outputFormat, ostream* output) const override;
|
||||
|
||||
// @copydoc
|
||||
bool hasField(const char* fieldName, bool numeric) const override;
|
||||
@@ -519,7 +519,7 @@ class ValueListDataField : public SingleDataField {
|
||||
vector<const SingleDataField*>* fields) const override;
|
||||
|
||||
// @copydoc
|
||||
void dump(bool prependFieldSeparator, bool asJson, ostream* output) const override;
|
||||
void dump(bool prependFieldSeparator, OutputFormat outputFormat, ostream* output) const override;
|
||||
|
||||
|
||||
protected:
|
||||
@@ -572,7 +572,7 @@ class ConstantDataField : public SingleDataField {
|
||||
vector<const SingleDataField*>* fields) const override;
|
||||
|
||||
// @copydoc
|
||||
void dump(bool prependFieldSeparator, bool asJson, ostream* output) const override;
|
||||
void dump(bool prependFieldSeparator, OutputFormat outputFormat, ostream* output) const override;
|
||||
|
||||
|
||||
protected:
|
||||
@@ -685,7 +685,7 @@ class DataFieldSet : public DataField {
|
||||
bool hasField(const char* fieldName, bool numeric) const override;
|
||||
|
||||
// @copydoc
|
||||
void dump(bool prependFieldSeparator, bool asJson, ostream* output) const override;
|
||||
void dump(bool prependFieldSeparator, OutputFormat outputFormat, ostream* output) const override;
|
||||
|
||||
// @copydoc
|
||||
result_t read(const SymbolString& data, size_t offset,
|
||||
|
||||
+12
-12
@@ -42,10 +42,10 @@ using std::setw;
|
||||
using std::endl;
|
||||
|
||||
|
||||
bool DataType::dump(bool asJson, size_t length, bool appendDivisor, ostream* output) const {
|
||||
if (asJson) {
|
||||
*output << "\"type\": \"" << m_id << "\"" << FIELD_SEPARATOR << " \"isbits\": "
|
||||
<< (getBitCount() < 8 ? "true" : "false") << FIELD_SEPARATOR << " \"length\": ";
|
||||
bool DataType::dump(OutputFormat outputFormat, size_t length, bool appendDivisor, ostream* output) const {
|
||||
if (outputFormat & OF_JSON) {
|
||||
*output << "\"type\": \"" << m_id << "\", \"isbits\": "
|
||||
<< (getBitCount() < 8 ? "true" : "false") << ", \"length\": ";
|
||||
if (isAdjustableLength() && length == REMAIN_LEN) {
|
||||
*output << "-1";
|
||||
} else {
|
||||
@@ -297,11 +297,11 @@ result_t DateTimeDataType::readSymbols(size_t offset, size_t length, const Symbo
|
||||
last = symbol;
|
||||
continue;
|
||||
}
|
||||
unsigned int minutes = symbol*256 + last;
|
||||
minutes = symbol*256 + last;
|
||||
if (minutes > 24*60) {
|
||||
return RESULT_ERR_OUT_OF_RANGE; // invalid value
|
||||
}
|
||||
unsigned int minutesHour = minutes / 60;
|
||||
unsigned int minutesHour = (unsigned int)(minutes / 60);
|
||||
if (minutesHour > 24) {
|
||||
return RESULT_ERR_OUT_OF_RANGE; // invalid hour
|
||||
}
|
||||
@@ -353,7 +353,7 @@ result_t DateTimeDataType::readSymbols(size_t offset, size_t length, const Symbo
|
||||
}
|
||||
*output << dec << setfill('0') << setw(2) << static_cast<unsigned>(d) << "."
|
||||
<< setw(2) << static_cast<unsigned>(m) << "." << static_cast<unsigned>(y + 1900);
|
||||
m = minutes%(24*60);
|
||||
m = (int)(minutes%(24*60));
|
||||
d = m/60;
|
||||
*output << " " << setw(2) << dec << setfill('0') << static_cast<unsigned>(d);
|
||||
m -= d*60;
|
||||
@@ -568,25 +568,25 @@ size_t NumberDataType::calcPrecision(int divisor) {
|
||||
return precision;
|
||||
}
|
||||
|
||||
bool NumberDataType::dump(bool asJson, size_t length, bool appendDivisor, ostream* output) const {
|
||||
bool NumberDataType::dump(OutputFormat outputFormat, size_t length, bool appendDivisor, ostream* output) const {
|
||||
if (m_bitCount < 8) {
|
||||
DataType::dump(asJson, m_bitCount, appendDivisor, output);
|
||||
DataType::dump(outputFormat, m_bitCount, appendDivisor, output);
|
||||
} else {
|
||||
DataType::dump(asJson, length, appendDivisor, output);
|
||||
DataType::dump(outputFormat, length, appendDivisor, output);
|
||||
}
|
||||
if (!appendDivisor) {
|
||||
return false;
|
||||
}
|
||||
if (m_baseType) {
|
||||
if (m_baseType->m_divisor != m_divisor) {
|
||||
if (asJson) {
|
||||
if (outputFormat & OF_JSON) {
|
||||
*output << ", \"divisor\": ";
|
||||
}
|
||||
*output << (m_divisor / m_baseType->m_divisor);
|
||||
return true;
|
||||
}
|
||||
} else if (m_divisor != 1) {
|
||||
if (asJson) {
|
||||
if (outputFormat & OF_JSON) {
|
||||
*output << ", \"divisor\": ";
|
||||
}
|
||||
*output << m_divisor;
|
||||
|
||||
+48
-23
@@ -78,36 +78,61 @@ using std::ostringstream;
|
||||
/** the maximum value for value lists. */
|
||||
#define MAX_VALUE (0xFFFFFFFFu)
|
||||
|
||||
typedef unsigned int OutputFormatBaseType;
|
||||
|
||||
/** the type for data output format options. */
|
||||
typedef int OutputFormat;
|
||||
enum OutputFormat : OutputFormatBaseType {
|
||||
/** no bit set at all. */
|
||||
OF_NONE = 0,
|
||||
|
||||
/** bit flag for @a OutputFormat: include names. */
|
||||
#define OF_NAMES 0x01
|
||||
/** bit flag for @a OutputFormat: include names. */
|
||||
OF_NAMES = 1 << 0,
|
||||
|
||||
/** bit flag for @a OutputFormat: include units. */
|
||||
#define OF_UNITS 0x02
|
||||
/** bit flag for @a OutputFormat: include units. */
|
||||
OF_UNITS = 1 << 1,
|
||||
|
||||
/** bit flag for @a OutputFormat: include comments. */
|
||||
#define OF_COMMENTS 0x04
|
||||
/** bit flag for @a OutputFormat: include comments. */
|
||||
OF_COMMENTS = 1 << 2,
|
||||
|
||||
/** bit flag for @a OutputFormat: numeric format (keep numeric value of value=name pairs). */
|
||||
#define OF_NUMERIC 0x08
|
||||
/** bit flag for @a OutputFormat: numeric format (keep numeric value of value=name pairs). */
|
||||
OF_NUMERIC = 1 << 3,
|
||||
|
||||
/** bit flag for @a OutputFormat: value=name format for such pairs. */
|
||||
#define OF_VALUENAME 0x10
|
||||
/** bit flag for @a OutputFormat: value=name format for such pairs. */
|
||||
OF_VALUENAME = 1 << 4,
|
||||
|
||||
/** bit flag for @a OutputFormat: JSON format. */
|
||||
#define OF_JSON 0x20
|
||||
/** bit flag for @a OutputFormat: JSON format. */
|
||||
OF_JSON = 1 << 5,
|
||||
|
||||
/** bit flag for @a OutputFormat: short format (only name and value, no indentation). */
|
||||
#define OF_SHORT 0x40
|
||||
/** bit flag for @a OutputFormat: short format (only name and value for fields). */
|
||||
OF_SHORT = 1 << 6,
|
||||
|
||||
/** bit flag for @a OutputFormat: include all attributes. */
|
||||
#define OF_ALL_ATTRS 0x80
|
||||
/** bit flag for @a OutputFormat: include all attributes. */
|
||||
OF_ALL_ATTRS = 1 << 7,
|
||||
|
||||
/** bit flag for @a OutputFormat: include message/field definition. */
|
||||
#define OF_DEFINTION 0x100
|
||||
/** bit flag for @a OutputFormat: include message/field definition. */
|
||||
OF_DEFINITION = 1 << 8,
|
||||
};
|
||||
|
||||
constexpr inline enum OutputFormat operator| (enum OutputFormat self, enum OutputFormat other) {
|
||||
return (enum OutputFormat)((OutputFormatBaseType)self | (OutputFormatBaseType)other);
|
||||
}
|
||||
|
||||
inline enum OutputFormat& operator|= (enum OutputFormat& self, enum OutputFormat other) {
|
||||
self = self | other;
|
||||
return self;
|
||||
}
|
||||
|
||||
constexpr inline enum OutputFormat operator& (enum OutputFormat self, enum OutputFormat other) {
|
||||
return (enum OutputFormat)((OutputFormatBaseType)self & (OutputFormatBaseType)other);
|
||||
}
|
||||
|
||||
inline enum OutputFormat& operator&= (enum OutputFormat& self, enum OutputFormat other) {
|
||||
self = self & other;
|
||||
return self;
|
||||
}
|
||||
|
||||
constexpr inline enum OutputFormat operator~ (enum OutputFormat self) {
|
||||
return (enum OutputFormat)(~(OutputFormatBaseType)self);
|
||||
}
|
||||
|
||||
/** the message part in which a data field is stored. */
|
||||
enum PartType {
|
||||
@@ -219,13 +244,13 @@ class DataType {
|
||||
/**
|
||||
* Dump the type identifier with the specified length and optionally the
|
||||
* divisor to the output.
|
||||
* @param asJson whether to output in JSON format.
|
||||
* @param outputFormat the @a OutputFormat options.
|
||||
* @param length the number of symbols to read/write.
|
||||
* @param appendDivisor whether to append the divisor (if available).
|
||||
* @param output the @a ostream to dump to.
|
||||
* @return true when a non-default divisor was written to the output.
|
||||
*/
|
||||
virtual bool dump(bool asJson, size_t length, bool appendDivisor, ostream* output) const;
|
||||
virtual bool dump(OutputFormat outputFormat, size_t length, bool appendDivisor, ostream* output) const;
|
||||
|
||||
/**
|
||||
* Internal method for reading the numeric raw value from a @a SymbolString.
|
||||
@@ -436,7 +461,7 @@ class NumberDataType : public DataType {
|
||||
static size_t calcPrecision(int divisor);
|
||||
|
||||
// @copydoc
|
||||
bool dump(bool asJson, size_t length, bool appendDivisor, ostream* output) const override;
|
||||
bool dump(OutputFormat outputFormat, size_t length, bool appendDivisor, ostream* output) const override;
|
||||
|
||||
/**
|
||||
* Derive a new @a NumberDataType from this.
|
||||
|
||||
+71
-27
@@ -845,7 +845,8 @@ void Message::dumpHeader(const vector<string>* fieldNames, ostream* output) {
|
||||
}
|
||||
}
|
||||
|
||||
void Message::dump(const vector<string>* fieldNames, bool withConditions, ostream* output) const {
|
||||
void Message::dump(const vector<string>* fieldNames, bool withConditions, OutputFormat outputFormat, ostream* output) const {
|
||||
// not to be used together with OF_JSON
|
||||
bool first = true;
|
||||
if (fieldNames == nullptr) {
|
||||
for (const auto& fieldName : knownFieldNamesFull) {
|
||||
@@ -857,7 +858,7 @@ void Message::dump(const vector<string>* fieldNames, bool withConditions, ostrea
|
||||
} else {
|
||||
*output << FIELD_SEPARATOR;
|
||||
}
|
||||
dumpField(fieldName, withConditions, output);
|
||||
dumpField(fieldName, withConditions, outputFormat, output);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -867,11 +868,11 @@ void Message::dump(const vector<string>* fieldNames, bool withConditions, ostrea
|
||||
} else {
|
||||
*output << FIELD_SEPARATOR;
|
||||
}
|
||||
dumpField(fieldName, withConditions, output);
|
||||
dumpField(fieldName, withConditions, outputFormat, output);
|
||||
}
|
||||
}
|
||||
|
||||
void Message::dumpField(const string& fieldName, bool withConditions, ostream* output) const {
|
||||
void Message::dumpField(const string& fieldName, bool withConditions, OutputFormat outputFormat, ostream* output) const {
|
||||
if (fieldName == "type") {
|
||||
if (withConditions && m_condition != nullptr) {
|
||||
m_condition->dump(false, output);
|
||||
@@ -928,10 +929,10 @@ void Message::dumpField(const string& fieldName, bool withConditions, ostream* o
|
||||
return;
|
||||
}
|
||||
if (fieldName == "fields") {
|
||||
m_data->dump(false, false, output);
|
||||
m_data->dump(false, outputFormat, output);
|
||||
return;
|
||||
}
|
||||
dumpAttribute(false, false, fieldName, output);
|
||||
dumpAttribute(false, outputFormat, fieldName, output);
|
||||
}
|
||||
|
||||
void addData(const SymbolString& data, ostringstream* output) {
|
||||
@@ -948,26 +949,44 @@ void addData(const SymbolString& data, ostringstream* output) {
|
||||
*output << "]";
|
||||
}
|
||||
|
||||
void Message::decodeJson(bool leadingSeparator, bool appendDirection, bool addRaw, OutputFormat outputFormat,
|
||||
ostringstream* output) const {
|
||||
void Message::decodeJson(bool leadingSeparator, bool appendDirectionCondition, bool withData, bool addRaw,
|
||||
OutputFormat outputFormat, ostringstream* output) const {
|
||||
outputFormat |= OF_JSON;
|
||||
if (leadingSeparator) {
|
||||
*output << ",";
|
||||
*output << ",\n";
|
||||
}
|
||||
*output << "\n \"" << getName();
|
||||
if (appendDirection) {
|
||||
*output << " \"";
|
||||
*output << getName();
|
||||
if (appendDirectionCondition) {
|
||||
if (isPassive()) {
|
||||
*output << "-u";
|
||||
} else if (isWrite()) {
|
||||
*output << "-w";
|
||||
}
|
||||
if (isConditional()) {
|
||||
m_condition->dump(false, output);
|
||||
}
|
||||
}
|
||||
bool withDefinition = (outputFormat & OF_DEFINTION) != 0;
|
||||
bool withDefinition = outputFormat & OF_DEFINITION;
|
||||
*output << "\": {"
|
||||
<< "\n \"name\": \"" << getName() << "\""
|
||||
<< ",\n \"passive\": " << (isPassive() ? "true" : "false")
|
||||
<< ",\n \"write\": " << (isWrite() ? "true" : "false")
|
||||
<< ",\n \"lastup\": " << setw(0) << dec << m_lastUpdateTime;
|
||||
bool hasData = getLastUpdateTime() != 0;
|
||||
<< ",\n \"write\": " << (isWrite() ? "true" : "false");
|
||||
if (outputFormat & OF_ALL_ATTRS) {
|
||||
*output << ",\n \"level\": \"" << getLevel() << "\"";
|
||||
if (getPollPriority()>0) {
|
||||
*output << ",\n \"pollprio\": " << setw(0) << dec << getPollPriority();
|
||||
}
|
||||
if (isConditional()) {
|
||||
*output << ",\n \"condition\": \"";
|
||||
m_condition->dump(false, output);
|
||||
*output << "\"";
|
||||
}
|
||||
}
|
||||
if (withData) {
|
||||
*output << ",\n \"lastup\": " << setw(0) << dec << getLastUpdateTime();
|
||||
}
|
||||
bool hasData = withData && (getLastUpdateTime() != 0);
|
||||
if (hasData || withDefinition) {
|
||||
if (withDefinition && m_srcAddress != SYN) {
|
||||
*output << ",\n \"qq\": " << dec << static_cast<unsigned>(m_srcAddress);
|
||||
@@ -983,7 +1002,7 @@ void Message::decodeJson(bool leadingSeparator, bool appendDirection, bool addRa
|
||||
}
|
||||
*output << "]";
|
||||
}
|
||||
appendAttributes(OF_JSON | outputFormat, output);
|
||||
appendAttributes(outputFormat, output);
|
||||
if (hasData) {
|
||||
if (addRaw) {
|
||||
addData(m_lastMasterData, output);
|
||||
@@ -1004,7 +1023,7 @@ void Message::decodeJson(bool leadingSeparator, bool appendDirection, bool addRa
|
||||
}
|
||||
if (withDefinition) {
|
||||
*output << ",\n \"fielddefs\": [";
|
||||
m_data->dump(false, true, output);
|
||||
m_data->dump(false, outputFormat, output);
|
||||
*output << "\n ]";
|
||||
}
|
||||
}
|
||||
@@ -1256,9 +1275,9 @@ result_t ChainedMessage::combineLastParts() {
|
||||
return result;
|
||||
}
|
||||
|
||||
void ChainedMessage::dumpField(const string& fieldName, bool withConditions, ostream* output) const {
|
||||
void ChainedMessage::dumpField(const string& fieldName, bool withConditions, OutputFormat outputFormat, ostream* output) const {
|
||||
if (fieldName != "id") {
|
||||
Message::dumpField(fieldName, withConditions, output);
|
||||
Message::dumpField(fieldName, withConditions, outputFormat, output);
|
||||
return;
|
||||
}
|
||||
bool first = true;
|
||||
@@ -1608,7 +1627,7 @@ bool SimpleNumericCondition::checkValue(const Message* message, const string& fi
|
||||
|
||||
bool SimpleStringCondition::checkValue(const Message* message, const string& field) {
|
||||
ostringstream output;
|
||||
result_t result = message->decodeLastData(false, field.length() == 0 ? nullptr : field.c_str(), -1, 0, &output);
|
||||
result_t result = message->decodeLastData(false, field.length() == 0 ? nullptr : field.c_str(), -1, OF_NONE, &output);
|
||||
if (result == RESULT_OK) {
|
||||
string value = output.str();
|
||||
for (size_t i = 0; i < m_values.size(); i++) {
|
||||
@@ -2786,10 +2805,17 @@ Message* MessageMap::getNextPoll() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MessageMap::dump(bool withConditions, ostream* output) const {
|
||||
void MessageMap::dump(bool withConditions, OutputFormat outputFormat, ostream* output) const {
|
||||
bool first = true;
|
||||
Message::dumpHeader(nullptr, output);
|
||||
*output << endl;
|
||||
bool isJson = (outputFormat & OF_JSON) != 0;
|
||||
if (isJson) {
|
||||
*output << "{";
|
||||
} else {
|
||||
Message::dumpHeader(nullptr, output);
|
||||
}
|
||||
if (!(outputFormat & OF_SHORT)) {
|
||||
*output << endl;
|
||||
}
|
||||
for (const auto it : m_messagesByName) {
|
||||
if (it.first[0] == FIELD_SEPARATOR) { // skip instances stored multiple times (key starting with "-")
|
||||
continue;
|
||||
@@ -2799,28 +2825,46 @@ void MessageMap::dump(bool withConditions, ostream* output) const {
|
||||
if (!message) {
|
||||
continue;
|
||||
}
|
||||
bool wasFirst = first;
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
*output << endl;
|
||||
}
|
||||
message->dump(nullptr, withConditions, output);
|
||||
if (isJson) {
|
||||
ostringstream str;
|
||||
message->decodeJson(!wasFirst, true, false, false, outputFormat, &str);
|
||||
*output << str.str();
|
||||
} else {
|
||||
message->dump(nullptr, withConditions, outputFormat, output);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Message* message = getFirstAvailable(it.second);
|
||||
if (!message) {
|
||||
continue;
|
||||
}
|
||||
bool wasFirst = first;
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
*output << endl;
|
||||
}
|
||||
message->dump(nullptr, withConditions, output);
|
||||
if (isJson) {
|
||||
ostringstream str;
|
||||
message->decodeJson(!wasFirst, true, false, false, outputFormat, &str);
|
||||
*output << str.str();
|
||||
} else {
|
||||
message->dump(nullptr, withConditions, outputFormat, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!first) {
|
||||
*output << endl;
|
||||
if (isJson) {
|
||||
*output << "}" << endl;
|
||||
} else {
|
||||
if (!first) {
|
||||
*output << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-7
@@ -543,28 +543,31 @@ class Message : public AttributedItem {
|
||||
* Write the message definition or parts of it to the @a ostream.
|
||||
* @param fieldNames the list of field names to write, or nullptr for all.
|
||||
* @param withConditions whether to include the optional conditions prefix.
|
||||
* @param outputFormat the @a OutputFormat options.
|
||||
* @param output the @a ostream to append the formatted value to.
|
||||
*/
|
||||
void dump(const vector<string>* fieldNames, bool withConditions, ostream* output) const;
|
||||
void dump(const vector<string>* fieldNames, bool withConditions, OutputFormat outputFormat, ostream* output) const;
|
||||
|
||||
/**
|
||||
* Write the specified field to the @a ostream.
|
||||
* @param fieldName the field name to write.
|
||||
* @param withConditions whether to include the optional conditions prefix.
|
||||
* @param outputFormat the @a OutputFormat options.
|
||||
* @param output the @a ostream to append the formatted value to.
|
||||
*/
|
||||
virtual void dumpField(const string& fieldName, bool withConditions, ostream* output) const;
|
||||
virtual void dumpField(const string& fieldName, bool withConditions, OutputFormat outputFormat, ostream* output) const;
|
||||
|
||||
/**
|
||||
* Decode the message from the last stored data in JSON format.
|
||||
* @param leadingSeparator whether to prepend a separator before the first value.
|
||||
* @param appendDirection whether to append the direction to the name key (for passive and write).
|
||||
* @param appendDirectionCondition whether to append the direction and condition to the name key.
|
||||
* @param withData whether to add the last data as well.
|
||||
* @param addRaw whether to add the raw symbols as well.
|
||||
* @param outputFormat the @a OutputFormat options to use.
|
||||
* @param output the @a ostringstream to append the decoded value(s) to.
|
||||
*/
|
||||
virtual void decodeJson(bool leadingSeparator, bool appendDirection, bool addRaw, OutputFormat outputFormat,
|
||||
ostringstream* output) const;
|
||||
virtual void decodeJson(bool leadingSeparator, bool appendDirectionCondition, bool withData, bool addRaw,
|
||||
OutputFormat outputFormat, ostringstream* output) const;
|
||||
|
||||
protected:
|
||||
/** the optional circuit name. */
|
||||
@@ -723,7 +726,7 @@ class ChainedMessage : public Message {
|
||||
|
||||
protected:
|
||||
// @copydoc
|
||||
void dumpField(const string& fieldName, bool withConditions, ostream* output) const override;
|
||||
void dumpField(const string& fieldName, bool withConditions, OutputFormat outputFormat, ostream* output) const override;
|
||||
|
||||
|
||||
private:
|
||||
@@ -1519,9 +1522,10 @@ class MessageMap : public MappedFileReader {
|
||||
/**
|
||||
* Write the message definitions to the @a ostream.
|
||||
* @param withConditions whether to include the optional conditions prefix.
|
||||
* @param outputFormat the @a OutputFormat options.
|
||||
* @param output the @a ostream to append the formatted messages to.
|
||||
*/
|
||||
void dump(bool withConditions, ostream* output) const;
|
||||
void dump(bool withConditions, OutputFormat outputFormat, ostream* output) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@@ -568,7 +568,7 @@ int main() {
|
||||
if (flags.find('i') != string::npos) {
|
||||
findIndex = parseSignedInt(flags.substr(flags.find('i')+1).c_str(), 10, 0, 9, &result);
|
||||
}
|
||||
OutputFormat verbosity = 0;
|
||||
OutputFormat verbosity = OF_NONE;
|
||||
if (flags.find("v") != string::npos) {
|
||||
verbosity |= OF_NAMES;
|
||||
}
|
||||
@@ -633,7 +633,7 @@ int main() {
|
||||
continue;
|
||||
}
|
||||
cout << "\"" << check[0] << "\"=\"";
|
||||
fields->dump(false, false, &cout);
|
||||
fields->dump(false, OF_NONE, &cout);
|
||||
cout << "\": create OK" << endl;
|
||||
|
||||
ostringstream output;
|
||||
@@ -650,9 +650,9 @@ int main() {
|
||||
cout << " parse \"" << sstr.getStr().substr(0, 2) << "\" error: " << getResultCode(result) << endl;
|
||||
error = true;
|
||||
}
|
||||
result = fields->read(mstr, 0, false, findName, findIndex, verbosity|(numeric?OF_NUMERIC:0), -1, &output);
|
||||
result = fields->read(mstr, 0, false, findName, findIndex, verbosity|(numeric?OF_NUMERIC:OF_NONE), -1, &output);
|
||||
if (result >= RESULT_OK) {
|
||||
result = fields->read(sstr, 0, !output.str().empty(), findName, findIndex, verbosity|(numeric?OF_NUMERIC:0), -1, &output);
|
||||
result = fields->read(sstr, 0, !output.str().empty(), findName, findIndex, verbosity|(numeric?OF_NUMERIC:OF_NONE), -1, &output);
|
||||
}
|
||||
if (failedRead) {
|
||||
if (result >= RESULT_OK) {
|
||||
|
||||
@@ -183,8 +183,6 @@ int main() {
|
||||
{"*r,cir*cuit#level,na*me,com*ment,ff,75,b509,0d", "", "", "", ""},
|
||||
{"r,CIRCUIT,NAME,COMMENT,,,,0100,field,,UCH", "r,cirCIRCUITcuit,naNAMEme,comCOMMENTment,ff,75,b509,0d0100,field,s,UCH,,,: field=42", "ff75b509030d0100", "012a", "DN"},
|
||||
{"r,CIRCUIT,NAME,COMMENT,,,,0100,field,,UCH",
|
||||
// "\"naNAMEme\": {r,cirCIRCUITcuit,naNAMEme,comCOMMENTment,ff,75,b509,0d0100,field,s,UCH,,,: field=42"
|
||||
"\n"
|
||||
" \"naNAMEme\": {\n"
|
||||
" \"name\": \"naNAMEme\",\n"
|
||||
" \"passive\": false,\n"
|
||||
@@ -407,7 +405,7 @@ int main() {
|
||||
ostringstream output;
|
||||
if (withMessageDump) {
|
||||
if (decodeJson) {
|
||||
message->decodeJson(false, false, false, OF_JSON|OF_DEFINTION, &output);
|
||||
message->decodeJson(false, false, true, false, OF_JSON|OF_DEFINITION, &output);
|
||||
string str = output.str();
|
||||
size_t start = str.find("\"lastup\": ");
|
||||
if (start != string::npos) {
|
||||
@@ -420,12 +418,12 @@ int main() {
|
||||
output.str("");
|
||||
output << str;
|
||||
} else {
|
||||
message->dump(nullptr, true, &output);
|
||||
message->dump(nullptr, true, OF_NONE, &output);
|
||||
}
|
||||
output << ": ";
|
||||
}
|
||||
result = message->decodeLastData(false, nullptr, -1,
|
||||
(decodeVerbose?OF_NAMES|OF_UNITS|OF_COMMENTS:0)|(decodeJson?OF_NAMES|OF_JSON:0), &output);
|
||||
(decodeVerbose?OF_NAMES|OF_UNITS|OF_COMMENTS:OF_NONE)|(decodeJson?OF_NAMES|OF_JSON:OF_NONE), &output);
|
||||
if (result != RESULT_OK) {
|
||||
cout << " \"" << check[2] << "\" / \"" << check[3] << "\": decode error " << (message->isWrite() ? "write: " : "read: ")
|
||||
<< getResultCode(result) << endl;
|
||||
|
||||
Reference in New Issue
Block a user