Composite data structures use a handler class called DataStructMember for member management.
With composite data structures you can use a reference to such a handler object or use methods directly on the composite object. The DataStructure class provides methods to set or read member values.
void setField (const String& name, int value);
void setField (const String& name, float value);
void setField (const String& name, const String& value);
void setField (const String& name, const Type& value);
You can set a value for a field using these methods, where name is the name of the member.
void setField (unsigned int index, int value);
void setField (unsigned int index, float value);
void setField (unsigned int index, const String& value);
void setField (unsigned int index, const Type& value);
If you know the index you can call these methods with index and value making the simulation much faster.
If the member with the given name or index is not found a DataTypeException is thrown.
// creates a new data structure TypeRef tData("Root.NetworkProtocol.TCPProtocol"); // sets the field "Name" to value XYZ tData.setField("Name","XYZ"); // set the "SourceID" field to index "1" // using the string representation tData.setField(1,"{192,168,2,0}"); // create a new IPAddress TypeRef tDestination("Root.Address.IPAddress"); // sets "Byte1" to 255 tDestination.setField("Byte1",255); tData.setField("DestIP",tDestination); // outputs the data structure to the "Output" port Output.put(arrivalTime) << tData;
Type& getField (const String& name);
Type& getField (unsigned int pIndex);
const Type& getField (const String& name) const;
const Type& getField (unsigned int pIndex) const;
When the method is non const it returns a copy of the data inside, otherwise it returns a reference to the data inside. When the field is not found, the methods throw a DataTypeException.
int getIndexForMember (const String& pName) const;
Returns the index for a specific member. Use this method in the setup method of a primitive to save the index (see example).
protected { // primitive member to save the index int mIndex; } setup { // assign the index value before the simulation starts const TypeClass& tTCP = DsHandler::findClass("Root.NetworkProtocol.TCPProtocol"); mIndex = tTCP.getIndexForMember("SourcePort"); } go { // get data structure from the input port TypeRef tTcp = Input.get(); // assign to the variable tPortValue the member value (calls the cast operator) int tPortValue = tTcp.getFieldRef(mIndex); }
In the new mechanism the field handler, DataStructMember, belongs only to the data structure descriptors, the class part of data structures. It does not hold any longer a data structure value therefore old methods like:
Type& data ();
Type* getData ();
const Type& data () const;
const Type* getData () const;
void writeData (const Type* data);
are no longer available. If you used them, you have to replace them with calls directly on the DataStructure object. Return methods like getData() and data() can be replaced with getField(...) methods from the DataStructure class, and writeData(...) with setField(...).
You can iterate over members of a data structure using the iterator class
DSMemberIter (DataStructureClass& ds)
and over the values inside a composite data structure with
DSFieldIter (DataStructure& ds)
operator++ returns the current member and moves the cursor to the next one. If you used the old iterator DSMemberIter(DataStructure&) you'll have to replace it with one of these two iterators.