ITCHCPP 1.6.1
High-Performance NASDAQ TotalView-ITCH 5.0 Parser & Market-Data Platform
Loading...
Searching...
No Matches
moldudp64.cpp
Go to the documentation of this file.
2
3#include <cstring>
4#include <stdexcept>
5#include <utility>
6
7namespace itch::transport {
8
9namespace {
10
11// Reads a big-endian unsigned integer of the field's width out of a byte span.
12template <typename UintType>
13auto read_big_endian(std::span<const std::byte> data, std::size_t offset) -> UintType {
14 UintType value {};
15 std::memcpy(&value, data.data() + offset, sizeof(UintType));
16 return utils::from_big_endian(value);
17}
18
19} // namespace
20
21MoldUdp64Decoder::MoldUdp64Decoder(MessageCallback callback) : m_callback {std::move(callback)} {}
22
23auto MoldUdp64Decoder::decode_packet(std::span<const std::byte> packet
24) -> std::optional<MoldUdp64Header> {
25 if (packet.size() < HEADER_SIZE) {
26 return std::nullopt;
27 }
28
29 ++m_packets_decoded;
30
31 MoldUdp64Header header {};
32 std::memcpy(header.session.data(), packet.data(), header.session.size());
33 constexpr std::size_t SEQUENCE_OFFSET = 10;
34 constexpr std::size_t COUNT_OFFSET = 18;
35 header.sequence_number = read_big_endian<std::uint64_t>(packet, SEQUENCE_OFFSET);
36 header.message_count = read_big_endian<std::uint16_t>(packet, COUNT_OFFSET);
37
38 if (header.is_end_of_session()) {
39 return header; // Control packet: no message blocks, no sequence advance.
40 }
41
42 // The sequence number names the first message in the packet; feed the count
43 // to the tracker so gaps in the multicast stream are detected. A heartbeat
44 // (count 0) still anchors the next expected sequence.
45 m_tracker.observe(header.session_view(), header.sequence_number, header.message_count);
46
47 if (header.is_heartbeat()) {
48 return header;
49 }
50
51 // After the header the datagram is a sequence of length-prefixed message
52 // blocks, which is exactly the framing the ordinary parser consumes. A
53 // malformed or truncated datagram is tolerated: the parser stops at the end
54 // of the buffer and we report through the callback what was decoded.
55 const std::span<const std::byte> blocks = packet.subspan(HEADER_SIZE);
56 auto counting_callback = [this](const Message& message) {
57 ++m_messages_decoded;
58 if (m_callback) {
59 m_callback(message);
60 }
61 };
62 // A truncated trailing block in a single datagram is non-fatal here; the gap
63 // will already have been surfaced by the sequence tracker. try_parse would
64 // avoid the exception, but it needs C++23's std::expected and this decoder
65 // must also build under C++20.
66 try {
67 m_parser.parse(blocks, counting_callback);
68 // NOLINTNEXTLINE(bugprone-empty-catch)
69 } catch (const std::runtime_error&) {
70 }
71
72 return header;
73}
74
75} // namespace itch::transport
MoldUdp64Decoder(MessageCallback callback)
Constructs a decoder that calls callback for each ITCH message.
Definition moldudp64.cpp:21
auto decode_packet(std::span< const std::byte > packet) -> std::optional< MoldUdp64Header >
Decodes a single MoldUDP64 datagram.
Definition moldudp64.cpp:23
Decoder for NASDAQ's MoldUDP64 UDP multicast market-data framing.
std::variant< SystemEventMessage, StockDirectoryMessage, StockTradingActionMessage, RegSHOMessage, MarketParticipantPositionMessage, MWCBDeclineLevelMessage, MWCBStatusMessage, IPOQuotingPeriodUpdateMessage, LULDAuctionCollarMessage, OperationalHaltMessage, AddOrderMessage, AddOrderMPIDAttributionMessage, OrderExecutedMessage, OrderExecutedWithPriceMessage, OrderCancelMessage, OrderDeleteMessage, OrderReplaceMessage, NonCrossTradeMessage, CrossTradeMessage, BrokenTradeMessage, NOIIMessage, RetailPriceImprovementIndicatorMessage, DLCRMessage > Message
A variant able to hold any one of the ITCH 5.0 message structs.
Definition messages.hpp:483
std::function< void(const Message &)> MessageCallback
The signature for the callback function used in streaming parse methods.
Definition parser.hpp:40
The fixed 20-byte header that prefixes every MoldUDP64 downstream packet.
Definition moldudp64.hpp:34