OnixS C++ FIX Engine  4.12.0
API Documentation
Manipulating FIX Message Fields

A FIX message represents a sequence of fields whose values are associated with unique numbers (tags). Such an interpretation treats a message as a collection of values associated with tag numbers. For this reason, the primary approach in handling message fields is similar to managing associative collections.

Adding Field into Message

To associate a field with a value, the OnixS::FIX::Message::set method must be used. If there is no field of a given tag number available in the message, this member creates an association. If the field already exists, this member updates its value with the new value. Also, there are Set methods for each standard type (Int32, Int64, Decimal, etc.). Such methods transform input value into text-presentation, so the actually stored value is a text-presentation of input. Therefore, when the message is sent there is no need to serialize such values. If you do not perform a large amount of typed set/get operations with the message object on the critical path, then these methods are the best choice from the performance point of view. In addition, there are similar OnixS::FIX::Message::setV methods. Such methods set values as it is without transforming it into text-presentation. Assigning field value via SetV methods saves not only value and its type as well, therefore no parsing is performed during subsequent access to the field via typed Get methods. In this case, when the message is sent there is a need to serialize such values, however, if you perform a large amount of typed set/get operations with the message object on the critical path, then these methods are the best choice from the performance point of view.

Short String Optimization

OnixS::FIX::Message class supports the Short String Optimization (SSO). If the size of the string presentation of a field value less than the size of the internal field value buffer (15 bytes for 32-bit and 23 bytes for 64-bit) then such a value is stored directly in this buffer without any new memory allocation. Therefore, setting short string values is faster because the dynamical memory allocation is not performed. Also, subsequent access to a field with the short string can work faster due to the better data locality, however, please note that SSO is not applied if a long string is set earlier to the field.

Accessing Field Value

To get a field value, the OnixS::FIX::Message::get method must be used.

Checking Field Presence

To check the field presence, the OnixS::FIX::Message::contain method must be used.

Removing Field from Message

To remove a field, the OnixS::FIX::Message::erase method must be used.

Iterating over Fields of Message

To iterate over all fields of a FIX message you can use the OnixS::FIX::FieldSet::ConstIterator class. This iterator does not iterate over fields from a repeating group. To iterate over fields of the repeating group you need to get the corresponding OnixS::FIX::GroupInstance object from the repeating group, please see the FIX Repeating Groups.

Example

The following example demonstrates the basic operations over message fields.

using namespace OnixS::FIX;
using namespace OnixS::FIX::FIX42;
class OutputFunctor
{
public:
void operator()(const Field& field)
{
std::clog << field.tag << "=" << field.value.toString() << std::endl;
}
};
void iterateMessageFields()
{
Message order(Values::MsgType::Order_Single, ProtocolVersion::FIX_42);
order.set(11, "Unique identifier of execution message");
std::string clientOrderId = order.get(11);
//Iterates over all fields of the FIX message without fields of repeating groups.
std::for_each(order.begin(), order.end(), OutputFunctor());
order.erase(11);
}

A message can also be traversed using range-based for loop:

void iterateMessageFieldsRangeBased()
{
Message order(Values::MsgType::Order_Single, ProtocolVersion::FIX_42);
// Traverse the group using range-based for loop.
for(auto & field : order)
{
std::clog << field.tag << "=" << field.value.toString() << std::endl;
}
}

Named Constants

In each sub-namespace, which corresponds to certain FIX version (like OnixS::FIX::FIX40), the OnixS::FIX::FIX40::Tags namespace is defined. This namespace contains the constants for all-known tag numbers. Additionally, there are the OnixS::FIX::FIX40::Values and OnixS::FIX::FIX40::TypedValues namespaces. These namespaces contain the constants for all-known tag values. The OnixS::FIX::FIX40::Values namespace contains only string constant values, the OnixS::FIX::FIX40::TypedValues namespace contains typed constant values (string, char, int) in accordance with FIX protocol types. Both namespaces contain the same values, however, typed values can be more convenient in some cases, for example, you can compare directly your internal char or int variables with corresponding typed constant without the conversion from string to char, int.

Also, there is the OnixS::FIX::FIX50_SP2_Latest namespace. It contains tag numbers and values for the latest extension pack (e.g., EP264).

The usage of all mentioned constants makes the source code more readable.

using namespace OnixS::FIX;
using namespace OnixS::FIX::FIX42;
Message order(Values::MsgType::Order_Single, ProtocolVersion::FIX_42);
order.set(Tags::ClOrdID, "90001008")
.set(Tags::Side, Values::Side::Buy)
.set(Tags::TimeInForce, Values::TimeInForce::Day);