OnixS C++ ICE Binary Order Entry Handler 1.2.3
API Documentation
Loading...
Searching...
No Matches
SBE Message

Inner Contents

 Message Fields
 Repeating Groups
 Schema Versioning

Detailed Description

The OnixS::ICE::BOE::Messaging::SbeMessage represents a Simple Binary Encoding (SBE) message.

MessageHolder class

The Handler exposes the OnixS::ICE::BOE::Messaging::MessageHolder class to encapsulate services related to handling SBE messages. It is a template class, which creates an underlying buffer to store an SBE message.

The template parameter SbeMessageType serves to indicate how the underlying buffer will be interpreted and what type of SBE message it will store.

The OnixS::ICE::BOE::Messaging::MessageHolder class contains the OnixS::ICE::BOE::Messaging::SimpleOpenFramingHeader and a strongly typed SBE message over the underlying data buffer.

To access to the strongly typed SBE message, use the OnixS::ICE::BOE::Messaging::MessageHolder::message method or OnixS::ICE::BOE::Messaging::MessageHolder::operator->().

The following diagram shows the relationship between MessageHolder, the SBE message wrapper, and the underlying buffer:

Strongly Typed SBE Message Wrappers

The Handler exposes strongly typed SBE message wrappers (e.g.: OnixS::ICE::BOE::Messaging::ExecutionReport_New), which provide interfaces to manipulate SBE message fields. These wrappers are used in strongly typed inbound callbacks of the OnixS::ICE::BOE::SessionListener class (e.g.: OnixS::ICE::BOE::SessionListener::onExecutionReport_New).

Note
Strongly typed SBE message wrapper classes do not have an underlying buffer and work only over an external buffer. Therefore, one needs to make sure that the lifetime of a strongly typed SBE message class object is the same as the lifetime of the buffer. For example, one should not use the delivered strongly typed SBE message object outside the inbound callback, since it uses an internal receiving buffer.

Copying a Message from a SessionListener Callback

If one needs to keep a message received in a strongly typed callback of the OnixS::ICE::BOE::SessionListener class, the message bytes should be copied to user-owned storage inside the callback.

The strongly typed callback argument is only a view over the Handler's internal receive buffer, so it should not be stored and used after the callback returns.

For example:

class Listener : public OnixS::ICE::BOE::SessionListener
{
public:
void onExecutionReport_New(const OnixS::ICE::BOE::Messaging::ExecutionReport_New msg, Session*) override
{
const auto* first = static_cast<const unsigned char*>(msg.binary());
const auto* last = first + msg.bufferSize();
executionReportBytes_.assign(first, last);
}
OnixS::ICE::BOE::Messaging::ExecutionReport_New executionReport() noexcept
{
return OnixS::ICE::BOE::Messaging::ExecutionReport_New(
executionReportBytes_.data(),
static_cast<OnixS::ICE::BOE::Messaging::ExecutionReport_New::EncodedLength>(executionReportBytes_.size()),
OnixS::ICE::BOE::Messaging::SbeMessage::NoInit{});
}
private:
std::vector<unsigned char> executionReportBytes_;
};
Note
In this case, only the SBE-encoded message is copied, starting from the SBE Message Header. The OnixS::ICE::BOE::Messaging::SimpleOpenFramingHeader is not part of the strongly typed callback argument.

Constructing SBE Message

To create an SBE message object, use the OnixS::ICE::BOE::Messaging::MessageHolder constructor. It creates the underlying buffer and the strongly typed message wrapper around it.

For example:

using namespace OnixS::ICE::BOE;
// Constructs a "New Order" message,
// optional field values are set to their `null` values,
// required field values are undefined.
typedef MessageHolder<NewOrderRequest> NewOrderSingle;
NewOrderSingle order;
order.message().side(SideEnum::Buy)
.clOrdId(123)
.timeInForce(TimeInForceEnum::Day)
.orderQty(1000)
.price(10);
//or
order->side(SideEnum::Buy)
.clOrdId(123)
.timeInForce(TimeInForceEnum::Day)
.orderQty(1000)
.price(10);
std::cout << "Order " << *order << std::endl;
Note
By default, the OnixS::ICE::BOE::Messaging::MessageHolder constructor sets optional fields to their null values, required field values are undefined. This behavior could be changed using the OnixS::ICE::BOE::Messaging::FieldsNoInitPolicy template argument.

For example:

using namespace OnixS::ICE::BOE;
// Constructs a "New Order - Single" message, both required and optional field values are undefined.
FieldsNoInitPolicy> NewOrderSingle;
NewOrderSingle order;
std::cout << "Order " << *order << std::endl;