There are iterators in FieldMap
class which is a super class of Message
and Group
class.
I'm not sure what do you mean by parsing repeating groups.
Fix engine parses raw fix messages for you when they arrive and your callback gets parsed FIX message - which has internal maps of tags (key/value) for tags in message header, body and tail.
Looking at 1.13.2 version of code, when the engine gets new string message from network it will eventually create a Message
passing it the string. Message
constructor then calls setString()
on itself which effectively parses the received string and creates a map of tags.
If you look at Message::setString
you can see that first the new field is added and then in setGroup
it checks if the field is part of the group. If it is then this method, setGroup
, takes over parsing of the following tags while those tags are part of the group. Once it comes across of tag that is not part of the group it stops parsing the group, it returns and continues parsing fields from message.
Now this all happens internally before the callback to your app where you handle received message.
There is a way to iterate over fields in a message. You can iterate over fields of header, body or over groups (and over each group).
const FIX40::ExecutionReport& msg; // new incoming message
// iterate over header
FIX::FieldMap::iterator it;
FIX::FieldMap::iterator b = msg.getHeader().begin();
FIX::FieldMap::iterator e = msg.getHeader().end();
for(it = b; it != e; ++it)
{
switch(it->first)
{
case FIX::FIELD::MsgSeqnum:
/* it->second.getString() - do something with tag data*/ ;
break;
...
}
}
And similarly for body:
FIX::FieldMap::iterator it;
FIX::FieldMap::iterator b = msg.begin();
FIX::FieldMap::iterator e = msg.end();
And there is groups iterator (FieldMap::g_begin/g_end
) as well so you could iterate over groups in msg or header and you can similarly iterate, or search, tags within each group.
Group as well as Message extends FieldMap so all the getField/setField functionality is shared across.
Internals ... skip if too much detail.
In the above example this code:
message.getGroup(1, group);
group.get(MDEntryType);
Effectively passes the call from message.getGroup(1, group)
-> FieldMap::getGroup(1, group.field(), group)
-> getGroupRef(num,field)
-> m_groups.find(field)
which gives you a vector of groups (vector<FieldMap*>
) and returns the num
element, aka the num
group from the message (a FieldMap
).
group.get(field)
is created using macros for each tag which is effectively translated as (map).getField(field)
.
During initialization the (map) for group is a reference to the object of which the tag is member of so it returns the tag from the specific group (see example src/C++/fix44/NewOrderSingle.h
it has couple of internal classes which extend Group)
Hope that it makes some sense.