INET Framework for OMNeT++/OMNEST
inet::MessageChecker Class Reference

#include <MessageChecker.h>

Inheritance diagram for inet::MessageChecker:

Public Member Functions

 MessageChecker ()
 

Protected Member Functions

void initialize () override
 
void handleMessage (cMessage *msg) override
 
void checkMessage (cMessage *msg)
 
void forwardMessage (cMessage *msg)
 
void finish () override
 
void checkFields (any_ptr object, cClassDescriptor *descriptor, const cXMLElementList &msgPattern) const
 
void checkFieldValue (any_ptr object, cClassDescriptor *descriptor, int field, cXMLAttributeMap &attr, int i=0) const
 
void checkFieldObject (any_ptr object, cClassDescriptor *descriptor, int field, cXMLAttributeMap &attr, const cXMLElement &pattern, int i=0) const
 
int checkFieldArray (any_ptr object, cClassDescriptor *descriptor, int field, cXMLAttributeMap &attr) const
 
void checkFieldValueInArray (any_ptr object, cClassDescriptor *descriptor, int field, cXMLAttributeMap &attr) const
 
void checkFieldObjectInArray (any_ptr object, cClassDescriptor *descriptor, int field, cXMLAttributeMap &attr, const cXMLElement &pattern) const
 
void checkFieldType (any_ptr object, cClassDescriptor *descriptor, int field, cXMLAttributeMap &attrList, int i=0) const
 
int findFieldIndex (any_ptr object, cClassDescriptor *descriptor, const std::string &fieldName) const
 

Protected Attributes

cXMLElementList m_checkingInfo
 
cXMLElementList::iterator m_iterChk
 
unsigned forwardedMsg
 
unsigned checkedMsg
 

Constructor & Destructor Documentation

◆ MessageChecker()

inet::MessageChecker::MessageChecker ( )
16  : forwardedMsg(0)
17  , checkedMsg(0)
18 {
19 }

Member Function Documentation

◆ checkFieldArray()

int inet::MessageChecker::checkFieldArray ( any_ptr  object,
cClassDescriptor *  descriptor,
int  field,
cXMLAttributeMap &  attr 
) const
protected
131 {
132  if (!descriptor->getFieldIsArray(field))
133  throw cRuntimeError("The field \"%s\" in message %d isn't an array", attr["name"].data(), forwardedMsg);
134 
135  // check the size of the field array into the client object
136  int size = atol(attr["size"].data());
137  int fieldSize = descriptor->getFieldArraySize(object, field);
138  if (size != fieldSize)
139  throw cRuntimeError("Field array \"%s\" contains %d element(s) (and not %d) in message %d",
140  attr["name"].data(), fieldSize, size, forwardedMsg);
141 
142  return fieldSize;
143 }

Referenced by checkFieldObjectInArray(), checkFields(), and checkFieldValueInArray().

◆ checkFieldObject()

void inet::MessageChecker::checkFieldObject ( any_ptr  object,
cClassDescriptor *  descriptor,
int  field,
cXMLAttributeMap &  attr,
const cXMLElement &  pattern,
int  i = 0 
) const
protected
118 {
119  // get the client object associated to the field
120  any_ptr obj = descriptor->getFieldStructValuePointer(object, field, i);
121 
122  // get the client object associated to the field, and its descriptor class
123  cClassDescriptor *descr = descriptor->getFieldIsCObject(field) ?
124  cClassDescriptor::getDescriptorFor(fromAnyPtr<cObject>(obj)) :
125  cClassDescriptor::getDescriptorFor(descriptor->getFieldStructName(field));
126 
127  checkFields(obj, descr, pattern.getChildren());
128 }

Referenced by checkFieldObjectInArray(), and checkFields().

◆ checkFieldObjectInArray()

void inet::MessageChecker::checkFieldObjectInArray ( any_ptr  object,
cClassDescriptor *  descriptor,
int  field,
cXMLAttributeMap &  attr,
const cXMLElement &  pattern 
) const
protected
160 {
161  int fieldSize = checkFieldArray(object, descriptor, field, attr);
162 
163  // convert attribute "index" into integer
164  int i = atol(attr["index"].data());
165 
166  if (i >= fieldSize)
167  throw cRuntimeError("Field \"%s\" in message %d has no entry for index %d", attr["name"].data(), forwardedMsg, i);
168 
169  // check field object into the client object
170  checkFieldObject(object, descriptor, field, attr, pattern, i);
171 }

Referenced by checkFields().

◆ checkFields()

void inet::MessageChecker::checkFields ( any_ptr  object,
cClassDescriptor *  descriptor,
const cXMLElementList &  msgPattern 
) const
protected
68 {
69  // fldPatternList contains the list of fields to be inspected
70  cXMLElementList::const_iterator iter = msgPattern.begin();
71  while (iter != msgPattern.end()) {
72  const cXMLElement& pattern = **iter;
73  cXMLAttributeMap attr = pattern.getAttributes();
74  std::string patternType(pattern.getTagName());
75 
76  // find field position into the client object
77  int field = findFieldIndex(object, descriptor, attr["name"]);
78 
79  // check the field type into the client object (if requiered)
80  if (containsKey(attr, "type"))
81  checkFieldType(object, descriptor, field, attr);
82 
83  if (patternType == "fieldValue")
84  checkFieldValue(object, descriptor, field, attr);
85  else if (patternType == "fieldObject")
86  checkFieldObject(object, descriptor, field, attr, pattern);
87  else if (patternType == "fieldArray")
88  checkFieldArray(object, descriptor, field, attr);
89  else if (patternType == "fieldValueInArray")
90  checkFieldValueInArray(object, descriptor, field, attr);
91  else if (patternType == "fieldObjectInArray")
92  checkFieldObjectInArray(object, descriptor, field, attr, pattern);
93 
94  iter++;
95  }
96 }

Referenced by checkFieldObject(), and checkMessage().

◆ checkFieldType()

void inet::MessageChecker::checkFieldType ( any_ptr  object,
cClassDescriptor *  descriptor,
int  field,
cXMLAttributeMap &  attrList,
int  i = 0 
) const
protected
174 {
175  std::string type;
176 
177  if (descriptor->getFieldIsCObject(field))
178  type = fromAnyPtr<cObject>(descriptor->getFieldStructValuePointer(object, field, i))->getClassName();
179  else
180  type = descriptor->getFieldTypeString(field);
181 
182  if (type != attr["type"])
183  throw cRuntimeError("Type mismatch for field \"%s\" in message %d (\"%s\" != \"%s\")",
184  attr["name"].data(), forwardedMsg, type.data(), attr["type"].data());
185 }

Referenced by checkFields().

◆ checkFieldValue()

void inet::MessageChecker::checkFieldValue ( any_ptr  object,
cClassDescriptor *  descriptor,
int  field,
cXMLAttributeMap &  attr,
int  i = 0 
) const
protected
99 {
100  // get the field string value from the client object
101  std::string value = descriptor->getFieldValueAsString(object, field, i);
102 
103  // convert the field value into its name of enum value
104  if (descriptor->getFieldProperty(field, "enum")) {
105  cEnum *enm = cEnum::find(descriptor->getFieldProperty(field, "enum"));
106  if (enm)
107  value = enm->getStringFor(atol(value.c_str()));
108  }
109 
110  // check field value into the client object
111  if (value.find(attr["value"]) != 0) // allow to keep reference values even if
112  // simtime precision changed...
113  throw cRuntimeError("Mismatch: field \"%s\" in the message %d (\"%s\" != \"%s\")",
114  attr["name"].data(), forwardedMsg, value.data(), attr["value"].data());
115 }

Referenced by checkFields(), and checkFieldValueInArray().

◆ checkFieldValueInArray()

void inet::MessageChecker::checkFieldValueInArray ( any_ptr  object,
cClassDescriptor *  descriptor,
int  field,
cXMLAttributeMap &  attr 
) const
protected
146 {
147  int fieldSize = checkFieldArray(object, descriptor, field, attr);
148 
149  // convert attribute "index" into integer
150  int i = atol(attr["index"].data());
151 
152  if (i >= fieldSize)
153  throw cRuntimeError("Field \"%s\" in message %d has no entry for index %d", attr["name"].data(), forwardedMsg, i);
154 
155  // check field value into the client object
156  checkFieldValue(object, descriptor, field, attr, i);
157 }

Referenced by checkFields().

◆ checkMessage()

void inet::MessageChecker::checkMessage ( cMessage *  msg)
protected
42 {
43  while (m_iterChk != m_checkingInfo.end()) {
44  cXMLElement& messagePattern = **m_iterChk;
45 
46  if (std::string(messagePattern.getTagName()) == "message" && messagePattern.hasAttributes()) {
47  int occurence = atol(messagePattern.getAttribute("occurence"));
48  if (occurence > 0) {
49  if (messagePattern.hasChildren())
50  checkFields(toAnyPtr(msg), msg->getDescriptor(), messagePattern.getChildren());
51 
52  occurence--;
53  std::ostringstream occur_str;
54  occur_str << occurence;
55  messagePattern.setAttribute("occurence", occur_str.str().data());
56  checkedMsg++;
57  }
58  if (occurence == 0)
59  m_iterChk++;
60  break;
61  }
62  else
63  m_iterChk++;
64  }
65 }

Referenced by handleMessage().

◆ findFieldIndex()

int inet::MessageChecker::findFieldIndex ( any_ptr  object,
cClassDescriptor *  descriptor,
const std::string &  fieldName 
) const
protected
188 {
189  std::ostringstream availableFields;
190  for (int i = 0; i < descriptor->getFieldCount(); i++) {
191  availableFields << descriptor->getFieldName(i) << ", ";
192  if (std::string(descriptor->getFieldName(i)) == fieldName)
193  return i;
194  }
195 
196  throw cRuntimeError("Unknown field \"%s\" in message %d\nAvailable fields in \"%s\" are : %s"
197  , fieldName.data(), forwardedMsg, descriptor->getClassName(), availableFields.str().data());
198  return 0;
199 }

Referenced by checkFields().

◆ finish()

void inet::MessageChecker::finish ( )
overrideprotected
214 {
215  if (forwardedMsg > checkedMsg)
216  throw cRuntimeError("%d message(s) has not been checked", forwardedMsg - checkedMsg);
217 
218  if (m_iterChk != m_checkingInfo.end())
219  throw cRuntimeError("Several message(s) have to be checked");
220 }

◆ forwardMessage()

void inet::MessageChecker::forwardMessage ( cMessage *  msg)
protected
202 {
203  cGate *gateOut = gate("out");
204  cChannel *channel = gateOut->getChannel();
205  simtime_t now = simTime();
206  simtime_t endTransmissionTime = channel->getTransmissionFinishTime();
207  simtime_t delayToWait = 0;
208  if (endTransmissionTime > now)
209  delayToWait = endTransmissionTime - now;
210  sendDelayed(msg, delayToWait, "out");
211 }

Referenced by handleMessage().

◆ handleMessage()

void inet::MessageChecker::handleMessage ( cMessage *  msg)
overrideprotected
35 {
36  forwardedMsg++;
37  checkMessage(msg);
38  forwardMessage(msg);
39 }

◆ initialize()

void inet::MessageChecker::initialize ( )
overrideprotected
22 {
23  cXMLElement *root = par("config");
24  if (std::string(root->getTagName()) == "checker") {
25  m_checkingInfo = root->getChildren();
26  m_iterChk = m_checkingInfo.begin();
27  }
28  forwardedMsg = 0;
29  checkedMsg = 0;
30  WATCH(forwardedMsg);
31  WATCH(checkedMsg);
32 }

Member Data Documentation

◆ checkedMsg

unsigned inet::MessageChecker::checkedMsg
protected

Referenced by checkMessage(), finish(), and initialize().

◆ forwardedMsg

◆ m_checkingInfo

cXMLElementList inet::MessageChecker::m_checkingInfo
protected

Referenced by checkMessage(), finish(), and initialize().

◆ m_iterChk

cXMLElementList::iterator inet::MessageChecker::m_iterChk
protected

Referenced by checkMessage(), finish(), and initialize().


The documentation for this class was generated from the following files:
inet::MessageChecker::findFieldIndex
int findFieldIndex(any_ptr object, cClassDescriptor *descriptor, const std::string &fieldName) const
Definition: MessageChecker.cc:187
inet::MessageChecker::checkFieldValueInArray
void checkFieldValueInArray(any_ptr object, cClassDescriptor *descriptor, int field, cXMLAttributeMap &attr) const
Definition: MessageChecker.cc:145
inet::find
std::vector< T >::iterator find(std::vector< T > &v, const Tk &a)
Definition: stlutils.h:44
inet::MessageChecker::checkFieldObjectInArray
void checkFieldObjectInArray(any_ptr object, cClassDescriptor *descriptor, int field, cXMLAttributeMap &attr, const cXMLElement &pattern) const
Definition: MessageChecker.cc:159
inet::MessageChecker::checkFields
void checkFields(any_ptr object, cClassDescriptor *descriptor, const cXMLElementList &msgPattern) const
Definition: MessageChecker.cc:67
inet::MessageChecker::checkFieldValue
void checkFieldValue(any_ptr object, cClassDescriptor *descriptor, int field, cXMLAttributeMap &attr, int i=0) const
Definition: MessageChecker.cc:98
inet::MessageChecker::checkFieldType
void checkFieldType(any_ptr object, cClassDescriptor *descriptor, int field, cXMLAttributeMap &attrList, int i=0) const
Definition: MessageChecker.cc:173
type
removed type
Definition: IUdp-gates.txt:7
inet::MessageChecker::forwardMessage
void forwardMessage(cMessage *msg)
Definition: MessageChecker.cc:201
inet::MessageChecker::m_iterChk
cXMLElementList::iterator m_iterChk
Definition: MessageChecker.h:40
omnetpp::toAnyPtr
any_ptr toAnyPtr(const inet::ClockTime *p)
Definition: common/ClockTime.h:351
inet::MessageChecker::checkedMsg
unsigned checkedMsg
Definition: MessageChecker.h:42
inet::MessageChecker::forwardedMsg
unsigned forwardedMsg
Definition: MessageChecker.h:41
inet::MessageChecker::checkFieldArray
int checkFieldArray(any_ptr object, cClassDescriptor *descriptor, int field, cXMLAttributeMap &attr) const
Definition: MessageChecker.cc:130
inet::MessageChecker::checkFieldObject
void checkFieldObject(any_ptr object, cClassDescriptor *descriptor, int field, cXMLAttributeMap &attr, const cXMLElement &pattern, int i=0) const
Definition: MessageChecker.cc:117
inet::MessageChecker::checkMessage
void checkMessage(cMessage *msg)
Definition: MessageChecker.cc:41
inet::MessageChecker::m_checkingInfo
cXMLElementList m_checkingInfo
Definition: MessageChecker.h:39
inet::containsKey
bool containsKey(const std::map< K, V, _C > &m, const Tk &a)
Definition: stlutils.h:80