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

A utility class to serialize an object in text form. More...

#include <ObjectPrinter.h>

Public Member Functions

 ObjectPrinter (ObjectPrinterRecursionPredicate recursionPredicate, const std::vector< cMatchExpression * > &objectMatchExpressions, const std::vector< std::vector< cMatchExpression * >> &fieldNameMatchExpressionsList, int indentSize=4)
 Accepts the parsed form of the pattern string. More...
 
 ObjectPrinter (ObjectPrinterRecursionPredicate recursionPredicate=nullptr, const char *pattern="*", int indentSize=4)
 Pattern syntax is that of the "eventlog-message-detail-pattern" configuration entry – see documentation there. More...
 
 ~ObjectPrinter ()
 Destructor. More...
 
void printObjectToStream (std::ostream &ostream, cObject *object)
 
std::string printObjectToString (cObject *object)
 

Protected Member Functions

void printIndent (std::ostream &ostream, int level)
 
void printObjectToStream (std::ostream &ostream, any_ptr object, cClassDescriptor *descriptor, any_ptr *objects, int level)
 
bool matchesObjectField (cObject *object, int fieldIndex)
 

Protected Attributes

int indentSize
 
char buffer [1024]
 
std::vector< cMatchExpression * > objectMatchExpressions
 
std::vector< std::vector< cMatchExpression * > > fieldNameMatchExpressionsList
 
ObjectPrinterRecursionPredicate recursionPredicate
 

Detailed Description

A utility class to serialize an object in text form.

Constructor & Destructor Documentation

◆ ObjectPrinter() [1/2]

inet::ObjectPrinter::ObjectPrinter ( ObjectPrinterRecursionPredicate  recursionPredicate,
const std::vector< cMatchExpression * > &  objectMatchExpressions,
const std::vector< std::vector< cMatchExpression * >> &  fieldNameMatchExpressionsList,
int  indentSize = 4 
)

Accepts the parsed form of the pattern string.

The two vectors must be of the same size. The contained MatchExpression objects will be deallocated by this ObjectPrinter.

◆ ObjectPrinter() [2/2]

inet::ObjectPrinter::ObjectPrinter ( ObjectPrinterRecursionPredicate  recursionPredicate = nullptr,
const char *  pattern = "*",
int  indentSize = 4 
)

Pattern syntax is that of the "eventlog-message-detail-pattern" configuration entry – see documentation there.

Recommended pattern for packet printing: "*: not className and not fullName and not fullPath and not info and not rawBin and not rawHex"

Just some examples here: "*": captures all fields of all messages "*Msg | *Packet": captures all fields of classes named AnythingMsg or AnythingPacket "*Frame:*Address,*Id": captures all fields named anythingAddress and anythingId from objects of any class named AnythingFrame "MyMessage:declaredOn(MyMessage)": captures instances of MyMessage recording the fields declared on the MyMessage class "*:(not declaredOn(cMessage) and not declaredOn(cNamedObject) and not declaredOn(cObject))": records user-defined fields from all objects

75 {
76  std::vector<cMatchExpression *> objectMatchExpressions;
77  std::vector<std::vector<cMatchExpression *>> fieldNameMatchExpressionsList;
78 
79  cStringTokenizer tokenizer(objectFieldMatcherPattern, "|;");
80  std::vector<std::string> patterns = tokenizer.asVector();
81 
82  for (auto& pattern : patterns) {
83  char *objectPattern = (char *)pattern.c_str();
84  char *fieldNamePattern = strchr(objectPattern, ':');
85 
86  if (fieldNamePattern) {
87  *fieldNamePattern = '\0';
88  cStringTokenizer fieldNameTokenizer(fieldNamePattern + 1, ",");
89  std::vector<std::string> fieldNamePatterns = fieldNameTokenizer.asVector();
90  std::vector<cMatchExpression *> fieldNameMatchExpressions;
91 
92  for (auto& fieldNamePattern : fieldNamePatterns)
93  fieldNameMatchExpressions.push_back(new cMatchExpression(fieldNamePattern.c_str(), false, true, true));
94 
95  fieldNameMatchExpressionsList.push_back(fieldNameMatchExpressions);
96  }
97  else {
98  std::vector<cMatchExpression *> fieldNameMatchExpressions;
99  fieldNameMatchExpressions.push_back(new cMatchExpression("*", false, true, true));
100  fieldNameMatchExpressionsList.push_back(fieldNameMatchExpressions);
101  }
102 
103  objectMatchExpressions.push_back(new cMatchExpression(objectPattern, false, true, true));
104  }
105 
106  ASSERT(objectMatchExpressions.size() == fieldNameMatchExpressionsList.size());
107  this->recursionPredicate = recursionPredicate ? recursionPredicate : defaultRecurseIntoMessageFields;
108  this->objectMatchExpressions = objectMatchExpressions;
109  this->fieldNameMatchExpressionsList = fieldNameMatchExpressionsList;
110  this->indentSize = indentSize;
111 }

◆ ~ObjectPrinter()

inet::ObjectPrinter::~ObjectPrinter ( )

Destructor.

114 {
115  for (int i = 0; i < (int)objectMatchExpressions.size(); i++) {
116  delete objectMatchExpressions[i];
117  std::vector<cMatchExpression *>& fieldNameMatchExpressions = fieldNameMatchExpressionsList[i];
118  for (auto& fieldNameMatchExpression : fieldNameMatchExpressions)
119  delete fieldNameMatchExpression;
120  }
121 }

Member Function Documentation

◆ matchesObjectField()

bool inet::ObjectPrinter::matchesObjectField ( cObject *  object,
int  fieldIndex 
)
protected
238 {
239  const MatchableObject matchableObject(MatchableObject::ATTRIBUTE_CLASSNAME, object);
240 
241  for (int i = 0; i < (int)objectMatchExpressions.size(); i++) {
242  cMatchExpression *objectMatchExpression = objectMatchExpressions[i];
243 
244  if (objectMatchExpression->matches(&matchableObject)) {
245  std::vector<cMatchExpression *>& fieldNameMatchExpressions = fieldNameMatchExpressionsList[i];
246 
247  for (auto fieldNameMatchExpression : fieldNameMatchExpressions) {
248  const MatchableField matchableField(object, fieldIndex);
249 
250  if (fieldNameMatchExpression->matches(&matchableField))
251  return true;
252  }
253  }
254  }
255 
256  return false;
257 }

Referenced by printObjectToStream().

◆ printIndent()

void inet::ObjectPrinter::printIndent ( std::ostream &  ostream,
int  level 
)
protected
231 {
232  int count = level * indentSize;
233  for (int i = 0; i < count; i++)
234  ostream << " ";
235 }

Referenced by printObjectToStream().

◆ printObjectToStream() [1/2]

void inet::ObjectPrinter::printObjectToStream ( std::ostream &  ostream,
any_ptr  object,
cClassDescriptor *  descriptor,
any_ptr *  objects,
int  level 
)
protected
140 {
141  if (level == MAXIMUM_OBJECT_PRINTER_LEVEL) {
142  printIndent(ostream, level);
143  ostream << "<pruned>\n";
144  return;
145  }
146  else {
147  for (int i = 0; i < level; i++) {
148  if (parents[i] == object) {
149  printIndent(ostream, level);
150  ostream << "<recursion>\n";
151  return;
152  }
153  }
154  }
155  if (!descriptor) {
156  printIndent(ostream, level);
157  if (level == 0)
158  ostream << "{...}\n";
159  else
160  ostream << "...\n";
161  }
162  else {
163  parents[level] = object;
164  for (int fieldIndex = 0; fieldIndex < descriptor->getFieldCount(); fieldIndex++) {
165  bool isArray = descriptor->getFieldIsArray(fieldIndex);
166  bool isPointer = descriptor->getFieldIsPointer(fieldIndex);
167  bool isCompound = descriptor->getFieldIsCompound(fieldIndex);
168  bool isCObject = descriptor->getFieldIsCObject(fieldIndex);
169  const char *fieldType = descriptor->getFieldTypeString(fieldIndex);
170  const char *fieldName = descriptor->getFieldName(fieldIndex);
171 
172  int size = isArray ? descriptor->getFieldArraySize(object, fieldIndex) : 1;
173  for (int elementIndex = 0; elementIndex < size; elementIndex++) {
174  any_ptr fieldValue = isCompound ? descriptor->getFieldStructValuePointer(object, fieldIndex, elementIndex) : any_ptr(nullptr);
175 
177  if (recursionPredicate)
178  result = recursionPredicate(object, descriptor, fieldIndex, fieldValue, parents, level);
179  if (result == SKIP || (descriptor->extendsCObject() && !matchesObjectField(fromAnyPtr<cObject>(object), fieldIndex)))
180  continue;
181 
182  printIndent(ostream, level + 1);
183  ostream << fieldType << " ";
184 
185  if (isPointer)
186  ostream << "*";
187  ostream << fieldName;
188 
189  if (isArray)
190  ostream << "[" << elementIndex << "]";
191  ostream << " = ";
192 
193  if (isCompound) {
194  if (fieldValue != nullptr) {
195  cClassDescriptor *fieldDescriptor = isCObject ? cClassDescriptor::getDescriptorFor(fromAnyPtr<cObject>(fieldValue)) :
196  cClassDescriptor::getDescriptorFor(descriptor->getFieldStructName(fieldIndex));
197 
198  if (isCObject && result == FULL_NAME)
199  ostream << fromAnyPtr<cObject>(fieldValue)->getFullName() << "\n";
200  else if (isCObject && result == FULL_PATH)
201  ostream << fromAnyPtr<cObject>(fieldValue)->getFullPath() << "\n";
202  else if (fieldDescriptor) {
203  if (isCObject)
204  ostream << "class " << fromAnyPtr<cObject>(fieldValue)->getClassName() << " ";
205  else
206  ostream << "struct " << descriptor->getFieldStructName(fieldIndex) << " ";
207 
208  ostream << "{\n";
209  printObjectToStream(ostream, fieldValue, fieldDescriptor, parents, level + 1);
210  printIndent(ostream, level + 1);
211  ostream << "}\n";
212  }
213  else {
214  std::string value = descriptor->getFieldValueAsString(object, fieldIndex, elementIndex);
215  ostream << QUOTE(value.c_str()) << "\n";
216  }
217  }
218  else
219  ostream << "nullptr\n";
220  }
221  else {
222  std::string value = descriptor->getFieldValueAsString(object, fieldIndex, elementIndex);
223  ostream << QUOTE(value.c_str()) << "\n";
224  }
225  }
226  }
227  }
228 }

◆ printObjectToStream() [2/2]

void inet::ObjectPrinter::printObjectToStream ( std::ostream &  ostream,
cObject *  object 
)
124 {
125  any_ptr parents[MAXIMUM_OBJECT_PRINTER_LEVEL];
126  cClassDescriptor *descriptor = cClassDescriptor::getDescriptorFor(object);
127  ostream << "class " << descriptor->getName() << " {\n";
128  printObjectToStream(ostream, toAnyPtr(object), descriptor, parents, 0);
129  ostream << "}\n";
130 }

Referenced by printObjectToStream(), and printObjectToString().

◆ printObjectToString()

std::string inet::ObjectPrinter::printObjectToString ( cObject *  object)
133 {
134  std::stringstream out;
135  printObjectToStream(out, object);
136  return out.str();
137 }

Member Data Documentation

◆ buffer

char inet::ObjectPrinter::buffer[1024]
protected

◆ fieldNameMatchExpressionsList

std::vector<std::vector<cMatchExpression *> > inet::ObjectPrinter::fieldNameMatchExpressionsList
protected

◆ indentSize

int inet::ObjectPrinter::indentSize
protected

Referenced by ObjectPrinter(), and printIndent().

◆ objectMatchExpressions

std::vector<cMatchExpression *> inet::ObjectPrinter::objectMatchExpressions
protected

◆ recursionPredicate

ObjectPrinterRecursionPredicate inet::ObjectPrinter::recursionPredicate
protected

The documentation for this class was generated from the following files:
inet::RECURSE
@ RECURSE
Definition: ObjectPrinter.h:23
inet::ObjectPrinter::objectMatchExpressions
std::vector< cMatchExpression * > objectMatchExpressions
Definition: ObjectPrinter.h:45
inet::FULL_NAME
@ FULL_NAME
Definition: ObjectPrinter.h:24
MAXIMUM_OBJECT_PRINTER_LEVEL
#define MAXIMUM_OBJECT_PRINTER_LEVEL
Definition: ObjectPrinter.cc:15
inet::count
int count(const std::vector< T > &v, const Tk &a)
Definition: stlutils.h:54
inet::ObjectPrinter::indentSize
int indentSize
Definition: ObjectPrinter.h:43
QUOTE
#define QUOTE(txt)
Definition: ObjectPrinter.cc:17
inet::MatchableObject::ATTRIBUTE_CLASSNAME
@ ATTRIBUTE_CLASSNAME
Definition: MatchableObject.h:24
inet::ObjectPrinter::printObjectToStream
void printObjectToStream(std::ostream &ostream, cObject *object)
Definition: ObjectPrinter.cc:123
inet::ObjectPrinter::printIndent
void printIndent(std::ostream &ostream, int level)
Definition: ObjectPrinter.cc:230
inet::ObjectPrinter::matchesObjectField
bool matchesObjectField(cObject *object, int fieldIndex)
Definition: ObjectPrinter.cc:237
inet::SKIP
@ SKIP
Definition: ClockEvent_m.h:61
inet::ObjectPrinter::recursionPredicate
ObjectPrinterRecursionPredicate recursionPredicate
Definition: ObjectPrinter.h:47
omnetpp::toAnyPtr
any_ptr toAnyPtr(const inet::ClockTime *p)
Definition: common/ClockTime.h:351
inet::ObjectPrinterRecursionControl
ObjectPrinterRecursionControl
Controls recursion depth in OpbjectPrinter.
Definition: ObjectPrinter.h:21
inet::ObjectPrinter::fieldNameMatchExpressionsList
std::vector< std::vector< cMatchExpression * > > fieldNameMatchExpressionsList
Definition: ObjectPrinter.h:46
inet::FULL_PATH
@ FULL_PATH
Definition: ObjectPrinter.h:25