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