extended Message::create to allow specifying multiple destinations (class is then suffixed with .0, .1 etc.)
This commit is contained in:
+50
-22
@@ -36,12 +36,13 @@ using namespace std;
|
||||
Message::Message(const string clazz, const string name, const bool isWrite,
|
||||
const bool isPassive, const string comment,
|
||||
const unsigned char srcAddress, const unsigned char dstAddress,
|
||||
const vector<unsigned char> id, DataField* data,
|
||||
const vector<unsigned char> id, DataField* data, const bool deleteData,
|
||||
const unsigned char pollPriority)
|
||||
: m_class(clazz), m_name(name), m_isWrite(isWrite),
|
||||
m_isPassive(isPassive), m_comment(comment),
|
||||
m_srcAddress(srcAddress), m_dstAddress(dstAddress),
|
||||
m_id(id), m_data(data), m_pollPriority(pollPriority),
|
||||
m_id(id), m_data(data), m_deleteData(deleteData),
|
||||
m_pollPriority(pollPriority),
|
||||
m_lastUpdateTime(0), m_lastChangeTime(0), m_pollCount(0), m_lastPollTime(0)
|
||||
{
|
||||
int exp = 7;
|
||||
@@ -62,7 +63,7 @@ Message::Message(const bool isWrite, const bool isPassive,
|
||||
: m_class(), m_name(), m_isWrite(isWrite),
|
||||
m_isPassive(isPassive), m_comment(),
|
||||
m_srcAddress(SYN), m_dstAddress(SYN),
|
||||
m_data(data), m_pollPriority(0),
|
||||
m_data(data), m_deleteData(true), m_pollPriority(0),
|
||||
m_lastUpdateTime(0), m_lastChangeTime(0), m_pollCount(0), m_lastPollTime(0)
|
||||
{
|
||||
m_id.push_back(pb);
|
||||
@@ -88,7 +89,7 @@ string getDefault(const string value, vector<string>* defaults, size_t pos)
|
||||
|
||||
result_t Message::create(vector<string>::iterator& it, const vector<string>::iterator end,
|
||||
vector< vector<string> >* defaultsRows,
|
||||
DataFieldTemplates* templates, Message*& returnValue)
|
||||
DataFieldTemplates* templates, vector<Message*>& messages)
|
||||
{
|
||||
// [type],[class],name,[comment],[QQ],[ZZ],id,fields...
|
||||
result_t result;
|
||||
@@ -167,15 +168,28 @@ result_t Message::create(vector<string>::iterator& it, const vector<string>::ite
|
||||
str = getDefault(*it++, defaults, defaultPos++).c_str();
|
||||
if (it == end)
|
||||
return RESULT_ERR_EOF;
|
||||
unsigned char dstAddress;
|
||||
if (*str == 0)
|
||||
dstAddress = SYN; // no specific destination
|
||||
else {
|
||||
dstAddress = (unsigned char)parseInt(str, 16, 0, 0xff, result);
|
||||
if (result != RESULT_OK)
|
||||
return result;
|
||||
if (!isValidAddress(dstAddress))
|
||||
return RESULT_ERR_INVALID_ADDR;
|
||||
vector<unsigned char> dstAddresses;
|
||||
bool isBroadcastOrMasterDestination = false;
|
||||
if (*str == 0) {
|
||||
dstAddresses.push_back(SYN); // no specific destination
|
||||
} else {
|
||||
istringstream stream(str);
|
||||
string token;
|
||||
bool first = true;
|
||||
while (getline(stream, token, VALUE_SEPARATOR) != 0) {
|
||||
unsigned char dstAddress = (unsigned char)parseInt(token.c_str(), 16, 0, 0xff, result);
|
||||
if (result != RESULT_OK)
|
||||
return result;
|
||||
if (!isValidAddress(dstAddress))
|
||||
return RESULT_ERR_INVALID_ADDR;
|
||||
bool broadcastOrMaster = (dstAddress == BROADCAST) || isMaster(dstAddress);
|
||||
if (first) {
|
||||
isBroadcastOrMasterDestination = broadcastOrMaster;
|
||||
first = false;
|
||||
} else if (isBroadcastOrMasterDestination != broadcastOrMaster)
|
||||
return RESULT_ERR_INVALID_ADDR;
|
||||
dstAddresses.push_back(dstAddress);
|
||||
}
|
||||
}
|
||||
|
||||
vector<unsigned char> id;
|
||||
@@ -240,7 +254,7 @@ result_t Message::create(vector<string>::iterator& it, const vector<string>::ite
|
||||
}
|
||||
}
|
||||
DataField* data = NULL;
|
||||
result = DataField::create(it, realEnd, templates, data, isWrite, dstAddress==SYN ? ESC : dstAddress);
|
||||
result = DataField::create(it, realEnd, templates, data, isWrite, false, isBroadcastOrMasterDestination);
|
||||
if (result != RESULT_OK) {
|
||||
return result;
|
||||
}
|
||||
@@ -249,7 +263,18 @@ result_t Message::create(vector<string>::iterator& it, const vector<string>::ite
|
||||
delete data;
|
||||
return RESULT_ERR_INVALID_POS;
|
||||
}
|
||||
returnValue = new Message(clazz, name, isWrite, isPassive, comment, srcAddress, dstAddress, id, data, pollPriority);
|
||||
size_t index = 0;
|
||||
bool multiple = dstAddresses.size()>1;
|
||||
char num[10];
|
||||
for (vector<unsigned char>::iterator it = dstAddresses.begin(); it != dstAddresses.end(); it++, index++) {
|
||||
unsigned char dstAddress = *it;
|
||||
string useClass = clazz;
|
||||
if (multiple) {
|
||||
sprintf(num, ".%ld", index);
|
||||
useClass = useClass + num;
|
||||
}
|
||||
messages.push_back(new Message(useClass, name, isWrite, isPassive, comment, srcAddress, dstAddress, id, data, pollPriority, index==0));
|
||||
}
|
||||
return RESULT_OK;
|
||||
}
|
||||
|
||||
@@ -516,18 +541,21 @@ result_t MessageMap::addFromFile(vector<string>::iterator& begin, const vector<s
|
||||
|
||||
istringstream stream(types);
|
||||
string type;
|
||||
vector<Message*> messages;
|
||||
while (getline(stream, type, VALUE_SEPARATOR) != 0) {
|
||||
*restart = type;
|
||||
begin = restart;
|
||||
Message* message = NULL;
|
||||
result = Message::create(begin, end, defaults, arg, message);
|
||||
messages.clear();
|
||||
result = Message::create(begin, end, defaults, arg, messages);
|
||||
for (vector<Message*>::iterator it = messages.begin(); it != messages.end(); it++) {
|
||||
Message* message = *it;
|
||||
if (result == RESULT_OK)
|
||||
result = add(message);
|
||||
if (result != RESULT_OK)
|
||||
delete message; // delete all remaining messages on error
|
||||
}
|
||||
if (result != RESULT_OK)
|
||||
return result;
|
||||
result = add(message);
|
||||
if (result != RESULT_OK) {
|
||||
delete message;
|
||||
return result;
|
||||
}
|
||||
begin = restart;
|
||||
}
|
||||
return result;
|
||||
|
||||
+10
-6
@@ -54,12 +54,13 @@ public:
|
||||
* @param dstAddress the destination address, or @a SYN for any (set later).
|
||||
* @param id the primary, secondary, and optional further ID bytes.
|
||||
* @param data the @a DataField for encoding/decoding the message.
|
||||
* @param deleteData whether to delete the @a DataField during destruction.
|
||||
* @param pollPriority the priority for polling, or 0 for no polling at all.
|
||||
*/
|
||||
Message(const string clazz, const string name, const bool isWrite,
|
||||
const bool isPassive, const string comment,
|
||||
const unsigned char srcAddress, const unsigned char dstAddress,
|
||||
const vector<unsigned char> id, DataField* data,
|
||||
const vector<unsigned char> id, DataField* data, const bool deleteData,
|
||||
const unsigned char pollPriority);
|
||||
|
||||
/**
|
||||
@@ -78,21 +79,21 @@ public:
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~Message() { delete m_data; }
|
||||
virtual ~Message() { if (m_deleteData) delete m_data; }
|
||||
|
||||
/**
|
||||
* Factory method for creating a new instance.
|
||||
* Factory method for creating new instances.
|
||||
* @param it the iterator to traverse for the definition parts.
|
||||
* @param end the iterator pointing to the end of the definition parts.
|
||||
* @param defaultsRows a @a vector with rows containing defaults, or NULL.
|
||||
* @param templates the @a DataFieldTemplates to be referenced by name, or NULL.
|
||||
* @param returnValue the variable in which to store the created instance.
|
||||
* @param messages the @a vector to which to add created instances.
|
||||
* @return @a RESULT_OK on success, or an error code.
|
||||
* Note: the caller needs to free the created instance.
|
||||
* Note: the caller needs to free the created instances.
|
||||
*/
|
||||
static result_t create(vector<string>::iterator& it, const vector<string>::iterator end,
|
||||
vector< vector<string> >* defaultsRows,
|
||||
DataFieldTemplates* templates, Message*& returnValue);
|
||||
DataFieldTemplates* templates, vector<Message*>& messages);
|
||||
|
||||
/**
|
||||
* Get the optional device class.
|
||||
@@ -286,6 +287,9 @@ private:
|
||||
/** the @a DataField for encoding/decoding the message. */
|
||||
DataField* m_data;
|
||||
|
||||
/** whether to delete the @a DataField during destruction. */
|
||||
const bool m_deleteData;
|
||||
|
||||
/** the priority for polling, or 0 for no polling at all. */
|
||||
const unsigned char m_pollPriority;
|
||||
|
||||
|
||||
@@ -59,6 +59,8 @@ int main()
|
||||
{"u,broadcast,hwStatus,,,fe,b505,27,,,UCH,,,,,,UCH,,,,,,UCH,,,", "0;19;0", "10feb505042700130097", "00", ""},
|
||||
{"w,,first,,,15,b509,0400,date,,bda", "26.10.2014", "ff15b50906040026100614", "00", "m"},
|
||||
{"r,ehp,time,,,08,b509,0d2800,,,time", "15:00:17", "ff08b509030d2800", "0311000f", "md"},
|
||||
{"r,ehp,time,,,08;10,b509,0d2800,,,time", "15:00:17", "ff08b509030d2800", "0311000f", "c"},
|
||||
{"r,ehp,time,,,08;09,b509,0d2800,,,time", "15:00:17", "ff08b509030d2800", "0311000f", "md*"},
|
||||
{"r,ehp,date,,,08,b509,0d2900,,,date", "23.11.2014", "ff08b509030d2900", "03170b0e", "md"},
|
||||
{"u,ehp,ActualEnvironmentPower,Energiebezug,,08,B509,29BA00,,s,IGN:2,,,,,s,power", "8", "1008b5090329ba00", "03ba0008", "pm"},
|
||||
{"uw,ehp,test,Test,,08,B5de,ab,,,power,,,,,s,hex:1", "8;39", "1008b5de02ab08", "0139", "pm"},
|
||||
@@ -72,7 +74,7 @@ int main()
|
||||
MessageMap* messages = new MessageMap();
|
||||
|
||||
Message* message = NULL;
|
||||
Message* deleteMessage = NULL;
|
||||
vector<Message*> deleteMessages;
|
||||
for (size_t i = 0; i < sizeof(checks) / sizeof(checks[0]); i++) {
|
||||
string check[5] = checks[i];
|
||||
istringstream isstr(check[0]);
|
||||
@@ -97,15 +99,19 @@ int main()
|
||||
bool decode = flags.find('d') != string::npos;
|
||||
bool failedPrepare = flags.find('p') != string::npos;
|
||||
bool failedPrepareMatch = flags.find('P') != string::npos;
|
||||
bool multi = flags.find('*') != string::npos;
|
||||
string item;
|
||||
vector<string> entries;
|
||||
|
||||
while (getline(isstr, item, FIELD_SEPARATOR) != 0)
|
||||
entries.push_back(item);
|
||||
|
||||
if (deleteMessage != NULL) {
|
||||
delete deleteMessage;
|
||||
deleteMessage = NULL;
|
||||
if (deleteMessages.size()>0) {
|
||||
for (vector<Message*>::iterator it = deleteMessages.begin(); it!=deleteMessages.end(); it++) {
|
||||
Message* deleteMessage = *it;
|
||||
delete deleteMessage;
|
||||
}
|
||||
deleteMessages.clear();
|
||||
}
|
||||
if (isTemplate) {
|
||||
// store new template
|
||||
@@ -138,7 +144,8 @@ int main()
|
||||
}
|
||||
else {
|
||||
vector<string>::iterator it = entries.begin();
|
||||
result = Message::create(it, entries.end(), NULL, templates, deleteMessage);
|
||||
|
||||
result = Message::create(it, entries.end(), NULL, templates, deleteMessages);
|
||||
if (failedCreate) {
|
||||
if (result == RESULT_OK)
|
||||
cout << "\"" << check[0] << "\": failed create error: unexpectedly succeeded" << endl;
|
||||
@@ -152,7 +159,7 @@ int main()
|
||||
printErrorPos(entries.begin(), entries.end(), it, "", 0, result);
|
||||
continue;
|
||||
}
|
||||
if (deleteMessage == NULL) {
|
||||
if (deleteMessages.size()==0) {
|
||||
cout << "\"" << check[0] << "\": create error: NULL" << endl;
|
||||
continue;
|
||||
}
|
||||
@@ -160,17 +167,31 @@ int main()
|
||||
cout << "\"" << check[0] << "\": create error: trailing input" << endl;
|
||||
continue;
|
||||
}
|
||||
if (multi && deleteMessages.size()==1) {
|
||||
cout << "\"" << check[0] << "\": create error: single message instead of multiple" << endl;
|
||||
continue;
|
||||
}
|
||||
if (!multi && deleteMessages.size()>1) {
|
||||
cout << "\"" << check[0] << "\": create error: multiple messages instead of single" << endl;
|
||||
continue;
|
||||
}
|
||||
cout << "\"" << check[0] << "\": create OK" << endl;
|
||||
if (!dontMap) {
|
||||
result_t result = messages->add(deleteMessage);
|
||||
if (result != RESULT_OK) {
|
||||
cout << "\"" << check[0] << "\": add error: "
|
||||
<< getResultCode(result) << endl;
|
||||
continue;
|
||||
result_t result = RESULT_OK;
|
||||
for (vector<Message*>::iterator it = deleteMessages.begin(); it!=deleteMessages.end(); it++) {
|
||||
Message* deleteMessage = *it;
|
||||
result_t result = messages->add(deleteMessage);
|
||||
if (result != RESULT_OK) {
|
||||
cout << "\"" << check[0] << "\": add error: "
|
||||
<< getResultCode(result) << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result!=RESULT_OK)
|
||||
continue;
|
||||
cout << " map OK" << endl;
|
||||
message = deleteMessage;
|
||||
deleteMessage = NULL;
|
||||
message = deleteMessages.front();
|
||||
deleteMessages.clear();
|
||||
if (onlyMap)
|
||||
continue;
|
||||
Message* foundMessage = messages->find(mstr);
|
||||
@@ -182,7 +203,7 @@ int main()
|
||||
cout << " find error: different" << endl;
|
||||
}
|
||||
else
|
||||
message = deleteMessage;
|
||||
message = deleteMessages.front();
|
||||
}
|
||||
|
||||
if (message->isPassive() || decode) {
|
||||
@@ -222,9 +243,12 @@ int main()
|
||||
}
|
||||
}
|
||||
|
||||
if (deleteMessage != NULL) {
|
||||
delete deleteMessage;
|
||||
deleteMessage = NULL;
|
||||
if (deleteMessages.size()>0) {
|
||||
for (vector<Message*>::iterator it = deleteMessages.begin(); it!=deleteMessages.end(); it++) {
|
||||
Message* deleteMessage = *it;
|
||||
delete deleteMessage;
|
||||
}
|
||||
deleteMessages.clear();
|
||||
}
|
||||
|
||||
delete templates;
|
||||
|
||||
Reference in New Issue
Block a user