Compare commits

...
Author SHA1 Message Date
Pedro Pinto c8fcd19034 Fixed Pedro build scripts 2020-03-25 14:46:08 -04:00
Pedro Pinto 993fe6697f Updated build script 2020-03-25 14:28:53 -04:00
Pedro Pinto fa18dcc6d4 Updated .gitignore 2020-03-25 14:10:45 -04:00
Eric Harding 5786f8eba1 Work in progress 2020-01-17 11:39:51 -05:00
Eric Harding f5ae6559ee Add default_venue_observer so I don't need a nullptr 2019-12-31 11:40:26 -05:00
Eric Harding 917c3ee909 Update SecureLogon for ilink3 2019-12-30 16:49:58 -05:00
Eric Harding 25866533ea Generated ilink message code 2019-12-24 13:09:43 -05:00
Eric Harding 4306ac0737 Fix build 2019-12-24 12:56:36 -05:00
Pedro Pinto 874f655b55 Revised IVenue, IConnectionController to handle failover and checkpoints 2019-12-20 17:32:20 -05:00
Pedro Pinto 17c7a631f9 FIX. 2019-12-20 14:00:16 -05:00
Pedro Pinto 0a98fd7fed FIX Venue. 2019-12-20 08:33:57 -05:00
Pedro Pinto d82855aec2 Gateway. 2019-12-18 17:33:20 -05:00
Pedro Pinto 516c9c0d84 Started working on networking. 2019-12-11 10:39:27 -05:00
Pedro Pinto 1bfdeeded4 Gateway refactor. 2019-12-09 14:18:42 -05:00
Pedro Pinto 929c19f4b2 Gateway work. 2019-12-05 09:57:42 -05:00
Pedro Pinto 70e58edacb More gateway work. 2019-12-04 18:11:25 -05:00
Pedro Pinto 26702a1a7e Changed compile time calculation of tag str/tag crc to use contexpr
This is much simpler than the template mess it replaces.
2019-11-24 21:39:17 -05:00
Pedro Pinto 71db591365 Working on gateway. 2019-11-23 14:07:30 -05:00
Pedro Pinto a8d013d054 Changed bts_assert to bts_assert_d in performance sensitive code. 2019-11-23 14:05:57 -05:00
Pedro Pinto 3179f2647f Changed OM<->GW protocol 2019-11-21 11:14:12 -05:00
Pedro Pinto 91020c2ccc Wiring complete 2019-11-15 09:03:51 -05:00
Pedro Pinto 404104e12b Cleaner syntax, more wiring complete. 2019-11-14 14:40:07 -05:00
Pedro Pinto a4145e6bd5 Interconnect done. 2019-11-13 14:47:38 -05:00
Pedro Pinto 425cd6e6a0 New approach to signals/slots 2019-11-13 08:40:21 -05:00
Pedro Pinto c21735ad92 Work on orchestration. 2019-11-08 12:48:17 -05:00
Pedro Pinto 2f4708eaf5 Added some benchmarks, fixed build. 2019-11-08 12:19:52 -05:00
Pedro Pinto 062e28bf5d Removed logging in hot path. 2019-10-11 11:26:38 -04:00
Pedro Pinto a2754bc2f5 Removed logging from polling loop. 2019-10-11 11:26:26 -04:00
Pedro Pinto 6638a89abe Dropped call to config from the hot path. 2019-10-11 11:21:06 -04:00
Pedro Pinto a11979f1a2 Cosmetic fix in jetfix.proto 2019-10-11 11:20:08 -04:00
Pedro Pinto 7a04547b8d Removed obsolete code. 2019-10-01 15:17:26 -04:00
Pedro Pinto d4ebfcb5a2 Clang format. 2019-10-01 14:47:00 -04:00
Pedro Pinto 4ac3b77030 Removed unused code. 2019-09-27 17:11:49 -04:00
Pedro Pinto 5e9bd1729b Ran clang format. 2019-09-27 15:25:21 -04:00
Pedro Pinto 14f6e7646a Ran clang format. 2019-09-27 14:46:19 -04:00
Pedro Pinto e8281dc5a0 Fixed perflog build reporting type (it was always reporting release) 2019-09-26 13:30:31 -04:00
Pedro Pinto d3efd1215f Merge branch 'ice_exec3' into SP-231-improve-order-manager-performance 2019-09-26 10:09:06 -04:00
Pedro Pinto a5ac746a9d Added another benchmark 2019-09-24 16:04:39 -04:00
Pedro Pinto 578d8678d0 Updated subrepo ptrs 2019-09-24 09:02:08 -04:00
Pedro Pinto 7e7b96be22 Merge branch 'master' into SP-231-improve-order-manager-performance 2019-09-24 09:01:37 -04:00
Pedro Pinto 26dd802e6a Merge branch 'ice_exec3' into SP-231-improve-order-manager-performance 2019-09-24 09:01:14 -04:00
Pedro Pinto 129a0fe3ca Merged faster_orderman 2019-09-24 09:01:05 -04:00
Pedro Pinto 2c95cb6905 Fixed doc typo 2019-09-24 08:43:32 -04:00
Pedro Pinto 61f0851c3f Merged ice_exec3 2019-09-23 08:40:55 -04:00
Pedro Pinto 5e6dea91f3 Tech doc 2019-09-23 08:39:24 -04:00
Pedro Pinto 0c91672317 Better docs for orderman 2019-09-19 14:54:29 -04:00
Pedro Pinto e62fe88f1a Deleted unused file. 2019-09-12 15:23:51 -04:00
Pedro Pinto 14993973ff Minor refactoring. 2019-09-12 15:17:21 -04:00
Pedro Pinto 7e84e688b7 Improved OrderManager documentation. 2019-09-12 14:26:53 -04:00
Eric Harding 98dd396687 SP-214 add doc comment for on_status 2019-09-12 14:26:32 -04:00
Eric Harding eea3bc1d8b SP-214 simplify trading status for synthetic logic 2019-09-12 14:26:32 -04:00
Eric Harding 9e2f72b26e SP-214 attempt to simplify calling securityTradingStatus 2019-09-12 14:26:32 -04:00
Eric Harding 1137b0daf8 SP-214 Missed initialization of EventStream 2019-09-12 14:26:32 -04:00
Eric Harding d60720208d SP-214 Wire StatusEvent to IAlgoOrder/IAlgoServices 2019-09-12 14:26:32 -04:00
Eric Harding 780633e639 SP-214 add status to MDSource.h 2019-09-12 14:26:32 -04:00
Eric Harding 7168a4b54c SP-214 Expose trading_status on MDConsumer. 2019-09-12 14:26:32 -04:00
Eric Harding b5e85ac873 SP-214 map cme status to co2 status 2019-09-12 14:26:32 -04:00
Eric Harding a5a5d56228 Write exchange_status MDP3 2019-09-12 14:26:32 -04:00
250 changed files with 139363 additions and 693 deletions

No files matched your search

+2
View File
@@ -34,3 +34,5 @@ trace_data/
/doc/user/public/*
.ionide/*
/.ignore
/build
/analysis_data
+1 -1
View File
@@ -40,7 +40,7 @@ else ()
-fPIC -Wall -pedantic -Wextra -Werror \
-Wno-missing-braces -Wno-ignored-qualifiers \
--std=c++17 -fdiagnostics-color")
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -DNDEBUG -O3")
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_DEBUG} -DNDEBUG -O3")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wno-undef")
add_subdirectory(src/server/sparkd)
add_subdirectory(src/lib)
+2
View File
@@ -36,6 +36,7 @@ namespace bts {
Plugin,
ClientSdk,
Http,
OrderMan2,
// Please keep this list in sync with logging.h/logging.cpp
}
@@ -105,6 +106,7 @@ namespace bts {
internal static Logger DataFlow => new Logger(Subsystem.DataFlow);
public static Logger ClientSdk => new Logger(Subsystem.ClientSdk);
public static Logger Http => new Logger(Subsystem.Http);
public static Logger OrderMan2 => new Logger(Subsystem.OrderMan2);
internal static void log_at(this Logger logger, Level level, string message) {
switch (level) {
+7 -6
View File
@@ -1,12 +1,13 @@
Session ID Access ID Secret Key Creation Date Expiration Date Environment
Session ID Access ID Secret Key Creation Date Expiration Date Environment
M4D lLtjH74y1Kh5XUJTLyH2 f1K_tROQp2lTIplVp34WxKa7xDUgfFnIteolfik061o 2019-09-03 2020-09-03 CERT
M4D lLtjH74y1Kh5XUJTLyH2 f1K_tROQp2lTIplVp34WxKa7xDUgfFnIteolfik061o 2019-09-03 2020-09-03 CERT
MC1 VEMlkDuLz74OVHSuacQB IuHyYT3b-9KUo3WsuXykt-fXsjzp7L-JOrdCSQZLNl0 2019-09-03 2020-09-03 CERT
MC1 VEMlkDuLz74OVHSuacQB IuHyYT3b-9KUo3WsuXykt-fXsjzp7L-JOrdCSQZLNl0 2019-09-03 2020-09-03 CERT
MC5 77lzSUwPLlM9obaXh2mK z6aA9qfASDKfZkYTVKFqJd-78i0HZ2Q9ec3CKCYIqHg 2019-09-03 2020-09-03 CERT
MC5 77lzSUwPLlM9obaXh2mK z6aA9qfASDKfZkYTVKFqJd-78i0HZ2Q9ec3CKCYIqHg 2019-09-03 2020-09-03 CERT
MC7 RphzI3rn71oGUEiYnX9e y6OvvPPyoyj2S8YAnE1gFduXT8v29HIMjO5EngYxSNg 2019-09-03 2020-09-03 CERT
MC7 RphzI3rn71oGUEiYnX9e y6OvvPPyoyj2S8YAnE1gFduXT8v29HIMjO5EngYxSNg 2019-09-03 2020-09-03 CERT
MC8 PYBIm2TI9gFPIxmHbuYl 6o-ZolGH2DdeQOlGtJ5Zqoh_kg7VdbxkmjeOHmigKwU 2019-09-03 2020-09-03 CERT
MC8 PYBIm2TI9gFPIxmHbuYl 6o-ZolGH2DdeQOlGtJ5Zqoh_kg7VdbxkmjeOHmigKwU 2019-09-03 2020-09-03 CERT
NGG 1OXPqNxPhbqbzm0kF92e qlUrwY1KG1Pyq-TcbJgMqYXmBTQoAi-wEEBERRDRZPE 2019-12-20 2020-12-20 NEWRELEASE
+1 -1
View File
@@ -1 +1 @@
set(sources api/apicore.proto;api/apigateway.proto;api/apioptions.proto;api/core/ApiClientInterop.cpp;api/core/ApiServerInterop.cpp;api/public/ApiServer.cpp;api/public/ClientChannel.cpp;api/public/QuickbusClientChannel.cpp;api/public/ServerChannel.cpp;api/public/ServiceContext.cpp;api/service_helpers/AdminServiceUtils.cpp;api/service_helpers/AlgoServiceUtils.cpp;api/service_helpers/PositionUtilities.cpp;api/services/AdminService.proto;api/services/AlgoDefinitionService.proto;api/services/AlgoService.proto;api/services/ApiUnitTestService.proto;api/services/AuthService.proto;api/services/BasePositionService.proto;api/services/ErrorReportService.proto;api/services/HelloService.proto;api/services/MBOService.proto;api/services/MarginService.proto;api/services/MarketDataAuxiliaryService.proto;api/services/MarketDataRelay.proto;api/services/MoneyFileService.proto;api/services/OrderService.proto;api/services/OutOfProcessURLListener.proto;api/services/PersistenceService.proto;api/services/PositionService.proto;api/services/ShellDiagnosticService.proto;api/services/ShellLatencyService.proto;api/services/SyntheticSecurityService.proto;api/test/ApiTests.cpp;api/test/HelloServiceServer.cpp;config/ConfigCheck.cpp;config/ConfigDownloader.cpp;config/ConfigErrorCollector.cpp;config/ConfigLog.cpp;config/ConfigPropertyEvaluator.cpp;config/ConfigValueQueue.cpp;config/ConfigurationException.cpp;config/ConfigurationState.cpp;config/PreprocessInputStream.cpp;config/config.cpp;config/defaults/MarketData.conf;config/defaults/Ports.conf;config/defaults/Symbols.conf;config/defaults/cme_reference_data.conf;config/defaults/edge.conf;config/defaults/jetfix.conf;config/defaults/keycode.conf;config/defaults/logging.conf;config/defaults/orderman_cfg.conf;config/defaults/orders_fills_cleanup.conf;config/defaults/position_cfg.conf;config/defaults/span.conf;config/defaults/spreader.conf;config/defaults/testkeys.conf;config/defaults/threads.conf;config/defaults/toggles.conf;config/extensions/extensions.proto;config/invalid/invalid.proto;config/protos/ExchangeSimCfg.proto;config/protos/MarketData.proto;config/protos/Ports.proto;config/protos/Symbols.proto;config/protos/UI.proto;config/protos/cme_reference_data.proto;config/protos/jetfix.proto;config/protos/keycode.proto;config/protos/logging.proto;config/protos/mercury_cfg.proto;config/protos/orderman_cfg.proto;config/protos/orders_fills_cleanup.proto;config/protos/perflog_cfg.proto;config/protos/position_cfg.proto;config/protos/quickbus_cfg.proto;config/protos/span.proto;config/protos/spreader.proto;config/protos/system.proto;config/protos/testkeys.proto;config/protos/threads.proto;config/protos/toggles.proto;config/tests/HTTPServer.cpp;config/tests/config_ref_tests.cpp;config/tests/config_tests.cpp;config/text_format/text_format.cpp;domain_model/Security.cpp;domain_model/Security.proto;domain_model/SecurityTests.cpp;domain_model/sod.cpp;domain_model/tests/domain_tests.cpp;expression/BooleanGrammar.cpp;expression/ExpressionEvaluator.cpp;expression/ParserExceptions.cpp;expression/Value.cpp;expression/tests/expression_parser_tests.cpp;jetfix/codec/FIXArray.cpp;jetfix/common/OutFIX.cpp;jetfix/connection/AsyncReader.cpp;jetfix/connection/IConnection.cpp;jetfix/connection/SocketConnection.cpp;jetfix/gateway/CoreGateway.cpp;jetfix/gateway/JetFIXGateway.cpp;jetfix/gateway/Session.cpp;jetfix/store/FIXFileStore.cpp;jetfix/store/session_name.cpp;jetfix/tests/async_reader_tests.cpp;jetfix/tests/decoding_tests.cpp;jetfix/tests/fix_encoding_stream_tests.cpp;jetfix/tests/fix_fragment_tests.cpp;jetfix/tests/jetfix_performance_tests.cpp;jetfix/tests/sample_fix.cpp;jetfix/tests/store_tests.cpp;logging/LoggerHub.cpp;logging/Sink.cpp;logging/logging.cpp;logging/tests/logging_tests.cpp;md/Diag/MDPeriodicDumper.cpp;md/Diag/ShmDumper.cpp;md/MBOProcessor.cpp;md/MBOServiceServer.cpp;md/MDClient.cpp;md/MDConsumer.cpp;md/MDConsumerHandle.cpp;md/MDConsumerInterop.cpp;md/MDProducer.cpp;md/MDProducerHandle.cpp;md/MemorySegmentUtils.cpp;md/PlatformLoader.cpp;md/PriceSize.cpp;md/SecurityCache.cpp;md/SecurityDB.cpp;md/SecurityIDRecorder.cpp;md/SecurityMapper.cpp;md/SecurityOracle.cpp;md/SettlementRecorder.cpp;md/Shm/FixedSecurity.cpp;md/SyntheticSecurityService.cpp;md/cme/MDP3Utils.cpp;md/common.cpp;md/ice/ICEUtils.cpp;md/protos/co2.proto;md/relay/QueryServer.cpp;md/relay/RelayClient.cpp;md/relay/RelayRecorder.cpp;md/test/Co2ManagedTestHelper.cpp;md/test/Co2TestInstrument.cpp;md/test/mbo_tests.cpp;md/test/md2_tests.cpp;md/test/md_test_utils.cpp;md/test/synthetic_book_merge_tests.cpp;md/vendor/OnixsUtils.cpp;mercury/actors/IPollableActor.cpp;mercury/broker/Broker.cpp;mercury/broker/BrokerProxy.cpp;mercury/broker/ILocalBroker.cpp;mercury/broker/IRemoteBroker.cpp;mercury/common/mercury_common.cpp;mercury/events/TimerEvent.cpp;mercury/executor/Executor.cpp;mercury/topics/Topic.cpp;metrics/metrics.cpp;metrics/system_metrics.cpp;orderman/actors/AsyncFactory.cpp;orderman/actors/ExecutionGateway.cpp;orderman/actors/FillStore.cpp;orLine truncated
set(sources api/apicore.proto;api/apigateway.proto;api/apioptions.proto;api/core/ApiClientInterop.cpp;api/core/ApiServerInterop.cpp;api/public/ApiServer.cpp;api/public/ClientChannel.cpp;api/public/QuickbusClientChannel.cpp;api/public/ServerChannel.cpp;api/public/ServiceContext.cpp;api/service_helpers/AdminServiceUtils.cpp;api/service_helpers/AlgoServiceUtils.cpp;api/service_helpers/PositionUtilities.cpp;api/services/AdminService.proto;api/services/AlgoDefinitionService.proto;api/services/AlgoService.proto;api/services/ApiUnitTestService.proto;api/services/AuthService.proto;api/services/BasePositionService.proto;api/services/ErrorReportService.proto;api/services/HelloService.proto;api/services/MBOService.proto;api/services/MarginService.proto;api/services/MarketDataAuxiliaryService.proto;api/services/MarketDataRelay.proto;api/services/MoneyFileService.proto;api/services/OrderService.proto;api/services/OutOfProcessURLListener.proto;api/services/PersistenceService.proto;api/services/PositionService.proto;api/services/ShellDiagnosticService.proto;api/services/ShellLatencyService.proto;api/services/SyntheticSecurityService.proto;api/test/ApiTests.cpp;api/test/HelloServiceServer.cpp;config/ConfigCheck.cpp;config/ConfigDownloader.cpp;config/ConfigErrorCollector.cpp;config/ConfigLog.cpp;config/ConfigPropertyEvaluator.cpp;config/ConfigValueQueue.cpp;config/ConfigurationException.cpp;config/ConfigurationState.cpp;config/PreprocessInputStream.cpp;config/config.cpp;config/defaults/MarketData.conf;config/defaults/Ports.conf;config/defaults/Symbols.conf;config/defaults/cme_reference_data.conf;config/defaults/edge.conf;config/defaults/jetfix.conf;config/defaults/keycode.conf;config/defaults/logging.conf;config/defaults/orderman_cfg.conf;config/defaults/orders_fills_cleanup.conf;config/defaults/position_cfg.conf;config/defaults/span.conf;config/defaults/spreader.conf;config/defaults/testkeys.conf;config/defaults/threads.conf;config/defaults/toggles.conf;config/extensions/extensions.proto;config/invalid/invalid.proto;config/protos/ExchangeSimCfg.proto;config/protos/MarketData.proto;config/protos/Ports.proto;config/protos/Symbols.proto;config/protos/UI.proto;config/protos/cme_reference_data.proto;config/protos/jetfix.proto;config/protos/keycode.proto;config/protos/logging.proto;config/protos/mercury_cfg.proto;config/protos/orderman_cfg.proto;config/protos/orders_fills_cleanup.proto;config/protos/perflog_cfg.proto;config/protos/position_cfg.proto;config/protos/quickbus_cfg.proto;config/protos/span.proto;config/protos/spreader.proto;config/protos/system.proto;config/protos/testkeys.proto;config/protos/threads.proto;config/protos/toggles.proto;config/tests/HTTPServer.cpp;config/tests/config_ref_tests.cpp;config/tests/config_tests.cpp;config/text_format/text_format.cpp;domain_model/Security.cpp;domain_model/Security.proto;domain_model/SecurityTests.cpp;domain_model/sod.cpp;domain_model/tests/domain_tests.cpp;expression/BooleanGrammar.cpp;expression/ExpressionEvaluator.cpp;expression/ParserExceptions.cpp;expression/Value.cpp;expression/tests/expression_parser_tests.cpp;jetfix/codec/FIXArray.cpp;jetfix/common/OutFIX.cpp;jetfix/connection/AsyncReader.cpp;jetfix/connection/IConnection.cpp;jetfix/connection/SocketConnection.cpp;jetfix/gateway/CoreGateway.cpp;jetfix/gateway/JetFIXGateway.cpp;jetfix/gateway/Session.cpp;jetfix/store/FIXFileStore.cpp;jetfix/store/session_name.cpp;jetfix/tests/async_reader_tests.cpp;jetfix/tests/decoding_tests.cpp;jetfix/tests/fix_encoding_stream_tests.cpp;jetfix/tests/fix_fragment_tests.cpp;jetfix/tests/jetfix_performance_tests.cpp;jetfix/tests/sample_fix.cpp;jetfix/tests/store_tests.cpp;logging/LoggerHub.cpp;logging/Sink.cpp;logging/logging.cpp;logging/tests/logging_tests.cpp;md/Diag/MDPeriodicDumper.cpp;md/Diag/ShmDumper.cpp;md/MBOProcessor.cpp;md/MBOServiceServer.cpp;md/MDClient.cpp;md/MDConsumer.cpp;md/MDConsumerHandle.cpp;md/MDConsumerInterop.cpp;md/MDProducer.cpp;md/MDProducerHandle.cpp;md/MemorySegmentUtils.cpp;md/PlatformLoader.cpp;md/PriceSize.cpp;md/SecurityCache.cpp;md/SecurityDB.cpp;md/SecurityIDRecorder.cpp;md/SecurityMapper.cpp;md/SecurityOracle.cpp;md/SettlementRecorder.cpp;md/Shm/FixedSecurity.cpp;md/SyntheticSecurityService.cpp;md/cme/MDP3Utils.cpp;md/common.cpp;md/ice/ICEUtils.cpp;md/protos/co2.proto;md/relay/QueryServer.cpp;md/relay/RelayClient.cpp;md/relay/RelayRecorder.cpp;md/test/Co2ManagedTestHelper.cpp;md/test/Co2TestInstrument.cpp;md/test/mbo_tests.cpp;md/test/md2_tests.cpp;md/test/md_test_utils.cpp;md/test/synthetic_book_merge_tests.cpp;md/vendor/OnixsUtils.cpp;mercury/actors/IPollableActor.cpp;mercury/broker/Broker.cpp;mercury/broker/BrokerProxy.cpp;mercury/broker/ILocalBroker.cpp;mercury/broker/IRemoteBroker.cpp;mercury/common/mercury_common.cpp;mercury/events/TimerEvent.cpp;mercury/executor/Executor.cpp;mercury/topics/Topic.cpp;metrics/metrics.cpp;metrics/system_metrics.cpp;orderman/actors/AsyncFactory.cpp;orderman/actors/FillStore.cpp;orderman/actors/GLBXExecutionGateway.cpLine truncated
+29
View File
@@ -31,4 +31,33 @@ OrdermanCfg {
hosted_actor: "*"
}
}
}
OrderManThreadingCfg {
value {
thread {
name: "om_1"
poll: true
actor: { name: "order_manager" }
}
thread {
name: "om_2"
poll: true
actor: { name: "order_manager" }
}
thread {
name: "gw_1"
poll: true
actor: { name: "gateway" arg: "sim" }
actor: { name: "gateway" arg: "cme_mc5_99" }
}
thread {
name: "om_slow"
actor: {name: "storage"}
actor: {name: "service_bridge"}
}
}
}
+2 -2
View File
@@ -7,11 +7,11 @@ message JetFIX {
required string name = 10;
enum JetFIXPlatform {
GLBX = 1;
CBOE = 6;
GLBX = 1;
SIM = 2;
ICE = 3;
SIMICE = 4;
CBOE = 6;
}
optional JetFIXPlatform platform = 15 [default = GLBX];
+16
View File
@@ -10,3 +10,19 @@ message OrdermanCfg {
repeated Executor executor = 1;
optional uint32 default_iceberg_pause_secs = 2 [default = 0];
}
message OrderManThreadingCfg {
message Actor {
required string name = 1;
repeated string arg = 2;
}
message Thread {
required string name = 1;
optional bool poll = 2 [default = false];
optional uint32 slow_worker_period = 3 [default = 100000];
repeated Actor actor = 4;
}
repeated Thread thread= 1;
}
+3 -3
View File
@@ -11,7 +11,7 @@ inline int d_toa(double n, char *buffer, size_t buffer_size, int decimal_digits=
static double_conversion::DoubleToStringConverter const &c =
double_conversion::DoubleToStringConverter::EcmaScriptConverter();
bts_assert(buffer_size);
bts_assert_d(buffer_size);
if (pad == -1) {
// no padding, return the smallest number that contains all the
@@ -34,8 +34,8 @@ inline int d_toa(double n, char *buffer, size_t buffer_size, int decimal_digits=
// padding, return something with a fixed size
std::array<char, 128> pre_buffer;
bts_assert((int)buffer_size > pad);
bts_assert((int)pre_buffer.size() >= pad);
bts_assert_d((int)buffer_size > pad);
bts_assert_d((int)pre_buffer.size() >= pad);
double_conversion::StringBuilder builder(&pre_buffer[0], pre_buffer.size());
+10 -10
View File
@@ -22,7 +22,7 @@ size_t extract(char *start, char *end,
std::vector<InMsgBuffer> *msgs) {
auto first_unprocessed_byte = 0;
auto current = start;
for (;;) {
// consume prefix
auto this_msg_begin = current;
@@ -143,20 +143,20 @@ void AsyncReader::dispatch() {
// see what we can parse with the just read bytes
framed_msgs.clear();
// extract as many messages as we can from the last unprocess
// byte to the current write cursor, return offset of first
// byte in the buffer that we could not process (possibly the
// first byte of an incomplete msg)
auto first_unprocessed_offset = extract(
&((*me->working_buffer)[me->first_pending_msg]),
&((*me->working_buffer)[me->write_cursor]), me->working_buffer,
&framed_msgs);
// extract as many messages as we can from the last
// unprocessed byte to the current write cursor, return
// offset of first byte in the buffer that we could not
// process (possibly the first byte of an incomplete msg)
auto first_unprocessed_offset =
extract(&((*me->working_buffer)[me->first_pending_msg]),
&((*me->working_buffer)[me->write_cursor]),
me->working_buffer, &framed_msgs);
me->first_pending_msg += first_unprocessed_offset;
for (auto &msg : framed_msgs) {
trace.sn = msg.get_seq_num();
socket_read_time.shift_ns(1);
me->perf_log.log(trace, socket_read_time,"fix_msg_r");
me->perf_log.log(trace, socket_read_time, "fix_msg_r");
msg.set_trace(trace);
me->sink.in_msg_raw(msg);
}
+28 -71
View File
@@ -27,12 +27,12 @@ namespace jetfix {
enum class CoreGateway::State {
OFF,
PAUSED,
CONNECTING,
READY,
WREADER_DISCONNECT,
WSESSION_TERMINATE
};
PAUSED,
CONNECTING,
READY,
WREADER_DISCONNECT,
WSESSION_TERMINATE
};
struct CoreGateway::SessionInfo {
SessionInfo() : connection(), store(), reader(), session() {}
@@ -47,21 +47,21 @@ struct CoreGateway::EventData {
typedef void (CoreGateway::*Handler)(EventData const &ev);
EventData(const EventData &src)
: handler(src.handler), out_msgs(src.out_msgs), in_msg(src.in_msg),
trace(src.trace), ts(src.ts) {}
: handler(src.handler), out_msgs(src.out_msgs), in_msg(src.in_msg),
trace(src.trace), ts(src.ts) {}
EventData() : handler(), out_msgs(), in_msg(), trace(), ts() {}
EventData(Handler handler)
: handler(handler), out_msgs(), in_msg(), trace(), ts() {}
: handler(handler), out_msgs(), in_msg(), trace(), ts() {}
EventData(Handler handler, trace::CorID const &trace,
OutFIXPtr const &out_msgs)
: handler(handler), out_msgs(out_msgs), in_msg(), trace(trace), ts() {}
: handler(handler), out_msgs(out_msgs), in_msg(), trace(trace), ts() {}
EventData(Handler handler, InMsgBuffer const &in_msg)
: handler(handler), out_msgs(), in_msg(in_msg), trace(), ts() {}
: handler(handler), out_msgs(), in_msg(in_msg), trace(), ts() {}
EventData(Handler handler, std::shared_ptr<std::string> const &ts)
: handler(handler), out_msgs(), in_msg(), trace(), ts(ts) {}
: handler(handler), out_msgs(), in_msg(), trace(), ts(ts) {}
EventData &operator=(EventData &src) {
handler = src.handler;
@@ -91,11 +91,11 @@ struct CoreGateway::PImpl {
PImpl(config::JetFIX::Connection const &cfg, ICoreGatewayObserver &observer,
ConnectionFactory const &conn_factory,
StoreFactory const &store_factory, trace::PerfLog &l)
: cfg(cfg), observer(observer), make_connection(conn_factory),
make_store(store_factory), state(State::OFF), start_of_pause(),
session_info(), event_queue(), timer_thread(), destroy(false),
is_on(false), has_replayed(false), send_batch(), recv_batch(),
connection_attempts(0), perf_log(l) {
: cfg(cfg), observer(observer), make_connection(conn_factory),
make_store(store_factory), state(State::OFF), start_of_pause(),
session_info(), event_queue(), timer_thread(), destroy(false),
is_on(false), has_replayed(false), send_batch(), recv_batch(),
connection_attempts(0), perf_log(l) {
send_batch.reserve(1024);
recv_batch.reserve(1024);
}
@@ -130,7 +130,7 @@ CoreGateway::CoreGateway(config::JetFIX::Connection const &cfg,
ConnectionFactory const &conn_factory,
StoreFactory const &store_factory,
trace::PerfLog &perf_trace)
: me(new PImpl(cfg, observer, conn_factory, store_factory, perf_trace)) {
: me(new PImpl(cfg, observer, conn_factory, store_factory, perf_trace)) {
me->timer_thread = make_timer_thread();
}
@@ -148,14 +148,6 @@ void CoreGateway::send(OutFIXPtr const &fix, trace::CorID trace) {
me->event_queue.push(EventData(&CoreGateway::sync_send, trace, fix));
}
void CoreGateway::send_hb() {
me->event_queue.push(EventData(&CoreGateway::sync_send_hb));
}
void CoreGateway::send_test_request() {
me->event_queue.push(EventData(&CoreGateway::sync_send_test_request));
}
void CoreGateway::start() {
me->event_queue.push(EventData(&CoreGateway::sync_start));
}
@@ -198,7 +190,7 @@ void CoreGateway::dispatch_events() {
if (me->send_batch.size() || me->recv_batch.size()) {
for (auto &ev : me->send_batch)
(this->*ev.handler)(ev);
for (auto &ev : me->recv_batch)
for (auto &ev : me->recv_batch)
(this->*ev.handler)(ev);
me->send_batch.clear();
me->recv_batch.clear();
@@ -209,7 +201,7 @@ void CoreGateway::call_time() {
while (!me->destroy) {
std::this_thread::sleep_for(10ms);
auto ts = std::make_shared<std::string>(
datetime::FIX_timestamp(datetime::now()));
datetime::FIX_timestamp(datetime::now()));
me->event_queue.push(EventData(&CoreGateway::sync_time, ts)); // NOLINT
}
}
@@ -276,42 +268,6 @@ void CoreGateway::sync_send(EventData const &ev) {
}
}
void CoreGateway::sync_send_hb(EventData const &) {
switch (me->state) {
case State::OFF:
bts_assert(false);
break;
case State::PAUSED:
case State::CONNECTING:
case State::WREADER_DISCONNECT:
case State::WSESSION_TERMINATE:
break;
case State::READY:
me->session_info->session->send_hb();
break;
default:
bts_assert(false);
}
}
void CoreGateway::sync_send_test_request(EventData const &) {
switch (me->state) {
case State::OFF:
bts_assert(false);
break;
case State::PAUSED:
case State::CONNECTING:
case State::WREADER_DISCONNECT:
case State::WSESSION_TERMINATE:
break;
case State::READY:
me->session_info->session->send_test_request();
break;
default:
bts_assert(false);
}
}
void CoreGateway::sync_session_ready(EventData const &) {
switch (me->state) {
case State::OFF:
@@ -443,7 +399,8 @@ void CoreGateway::sync_time(EventData const &ev) {
if (!me->has_replayed) {
auto msgs_to_replay = me->session_info->store->replay();
LOG(Jetfix, Warn, "Replaying {} FIX msgs", msgs_to_replay.size());
LOG(Jetfix, Warn, "Replaying {} FIX msgs",
msgs_to_replay.size());
me->observer.replay(msgs_to_replay);
me->has_replayed = true;
}
@@ -468,13 +425,13 @@ void CoreGateway::sync_time(EventData const &ev) {
me->cfg.name());
me->session_info->session.reset(new Session(
me->cfg, *me->session_info->connection,
*me->session_info->store, *this,
[]() { return utils::TimeStamp::now(); }, me->perf_log));
me->cfg, *me->session_info->connection,
*me->session_info->store, *this,
[]() { return utils::TimeStamp::now(); }, me->perf_log));
me->session_info->reader.reset(new AsyncReader(
*me->session_info->connection, me->cfg.name(), *this,
me->perf_log, me->cfg.msg_buffer_sz(),
me->cfg.msg_high_water_mark()));
*me->session_info->connection, me->cfg.name(), *this,
me->perf_log, me->cfg.msg_buffer_sz(),
me->cfg.msg_high_water_mark()));
me->session_info->reader->start();
me->session_info->session->start();
transition(State::CONNECTING);
-6
View File
@@ -35,10 +35,6 @@ public:
void send (OutFIXPtr const &msgs, trace::CorID trace);
void dispatch_events ();
// for certification use only
void send_hb ();
void send_test_request ();
private:
enum class State;
struct SessionInfo;
@@ -56,8 +52,6 @@ private:
void sync_start (EventData const &);
void sync_stop (EventData const &);
void sync_send (EventData const &);
void sync_send_hb (EventData const&);
void sync_send_test_request (EventData const&);
void sync_session_ready (EventData const&) ;
void sync_session_terminated (EventData const&);
void sync_reader_disconnected (EventData const&) ;
-4
View File
@@ -67,10 +67,6 @@ public:
DispatcherTuple>::value> (_dispatchers).handler;
}
// for CERT purposes
void send_hb () {_core.send_hb ();}
void send_test_request () {_core.send_test_request ();}
private:
struct IDispatcher
{
+2 -2
View File
@@ -830,8 +830,8 @@ OutFIXPtr make_logon(uint32_t seq_num, uint32_t last_seq_num_processed,
buffer.add<EncodedTextLen>(ld.access_key.size());
buffer.add<EncodedText>(ld.access_key);
buffer.add<EncryptedPasswordMethod>("CME-1-SHA-256");
buffer.add<EncryptedPasswordLen>(ld.signature.size());
buffer.add<EncryptedPassword>(ld.signature);
buffer.add<EncryptedPasswordLen>(ld.signature_base64.size());
buffer.add<EncryptedPassword>(ld.signature_base64);
}
else
{
+1
View File
@@ -7,6 +7,7 @@
namespace bts {
namespace jetfix {
class InMsgBuffer;
class IFIXStore
+161 -93
View File
@@ -5,136 +5,204 @@
namespace bts {
namespace jetfix {
boost::gregorian::greg_weekday parse_weekday (std::string weekday_str)
{
boost::to_lower (weekday_str);
boost::gregorian::greg_weekday parse_weekday(std::string weekday_str) {
boost::to_lower(weekday_str);
for (int i = 0; i < 7; i++) {
auto gw_day = boost::gregorian::greg_weekday (i);
auto prefix = std::string (gw_day.as_short_string ());
boost::to_lower (prefix);
if (weekday_str.find (prefix) == 0)
auto gw_day = boost::gregorian::greg_weekday(i);
auto prefix = std::string(gw_day.as_short_string());
boost::to_lower(prefix);
if (weekday_str.find(prefix) == 0)
return gw_day;
}
bts_assert (false);
return boost::gregorian::greg_weekday (0);
bts_assert(false);
return boost::gregorian::greg_weekday(0);
}
boost::posix_time::time_duration parse_time (std::string const &time_str)
{
boost::posix_time::time_duration parse_time(std::string const &time_str) {
try {
return boost::posix_time::duration_from_string (time_str);
}
catch (boost::bad_lexical_cast &)
{
bts_assert (false);
return boost::posix_time::time_duration ();
return boost::posix_time::duration_from_string(time_str);
} catch (boost::bad_lexical_cast &) {
bts_assert(false);
return boost::posix_time::time_duration();
}
}
datetime::PTime closest_before (datetime::PTime const &ref_date,
boost::gregorian::greg_weekday weekday,
boost::posix_time::time_duration time_of_day)
{
if (ref_date.date ().day_of_week () == weekday) {
if (time_of_day < ref_date.time_of_day ())
return datetime::PTime (ref_date.date (),time_of_day);
datetime::PTime closest_before(datetime::PTime const &ref_date,
boost::gregorian::greg_weekday weekday,
boost::posix_time::time_duration time_of_day) {
if (ref_date.date().day_of_week() == weekday) {
if (time_of_day < ref_date.time_of_day())
return datetime::PTime(ref_date.date(), time_of_day);
else {
return datetime::PTime (ref_date.date () - boost::gregorian::date_duration (7),
time_of_day);
return datetime::PTime(
ref_date.date() - boost::gregorian::date_duration(7), time_of_day);
}
} else {
auto distance =
ref_date.date ().day_of_week ().as_number () -
weekday.as_number ();
ref_date.date().day_of_week().as_number() - weekday.as_number();
if (distance < 0)
distance += 7;
return datetime::PTime (ref_date.date () - boost::gregorian::date_duration (distance),
time_of_day);
return datetime::PTime(ref_date.date() -
boost::gregorian::date_duration(distance),
time_of_day);
}
}
bool in_session (datetime::PTime const &ref_date,
boost::posix_time::time_duration time_of_day_start,
boost::posix_time::time_duration time_of_day_end)
{
auto t = ref_date.time_of_day ();
bool in_session(datetime::PTime const &ref_date,
boost::posix_time::time_duration time_of_day_start,
boost::posix_time::time_duration time_of_day_end) {
auto t = ref_date.time_of_day();
if (time_of_day_start < time_of_day_end)
return t >= time_of_day_start && t <= time_of_day_end;
else
return t >= time_of_day_start || t <= time_of_day_end;
}
bool in_session (datetime::PTime const &ref_date,
boost::gregorian::greg_weekday weekday_start,
boost::posix_time::time_duration time_of_day_start,
boost::gregorian::greg_weekday weekday_end,
boost::posix_time::time_duration time_of_day_end)
{
auto closest_earlier_start = closest_before (ref_date,weekday_start,time_of_day_start);
auto closest_earlier_end = closest_before (ref_date,weekday_end,time_of_day_end);
return closest_earlier_end<closest_earlier_start;
bool in_session(datetime::PTime const &ref_date,
boost::gregorian::greg_weekday weekday_start,
boost::posix_time::time_duration time_of_day_start,
boost::gregorian::greg_weekday weekday_end,
boost::posix_time::time_duration time_of_day_end) {
auto closest_earlier_start =
closest_before(ref_date, weekday_start, time_of_day_start);
auto closest_earlier_end =
closest_before(ref_date, weekday_end, time_of_day_end);
return closest_earlier_end < closest_earlier_start;
}
std::string session_name_from_ptime (datetime::PTime t,
boost::posix_time::time_duration time_of_day_start,
boost::posix_time::time_duration time_of_day_end)
{
std::string result (10,' ');
SessionName
session_name_from_ptime(datetime::PTime t,
boost::posix_time::time_duration time_of_day_start,
boost::posix_time::time_duration time_of_day_end) {
std::string result(10, ' ');
auto start_of_session = t;
if (time_of_day_start > time_of_day_end &&
start_of_session.time_of_day () <= time_of_day_end)
start_of_session -= boost::gregorian::date_duration (1);
sprintf (&result[0], "%04d-%02d-%02d",
(unsigned short) start_of_session.date ().year (),
start_of_session.date ().month ().as_number (),
start_of_session.date ().day ().as_number ());
return result;
if (time_of_day_start > time_of_day_end &&
start_of_session.time_of_day() <= time_of_day_end)
start_of_session -= boost::gregorian::date_duration(1);
sprintf(&result[0], "%04d-%02d-%02d",
(unsigned short)start_of_session.date().year(),
start_of_session.date().month().as_number(),
start_of_session.date().day().as_number());
return {result,t};
}
std::string session_name (datetime::PTime const &ref_date,
boost::gregorian::greg_weekday weekday_start,
boost::posix_time::time_duration time_of_day_start,
boost::gregorian::greg_weekday weekday_end,
boost::posix_time::time_duration time_of_day_end)
{
if (in_session (ref_date,weekday_start,time_of_day_start,weekday_end,time_of_day_end))
return session_name_from_ptime (closest_before (ref_date,weekday_start,time_of_day_start),
boost::posix_time::time_duration(0, 0, 0),
boost::posix_time::time_duration(0, 0, 1));
std::optional<SessionName> session_name(datetime::PTime const &ref_date,
boost::gregorian::greg_weekday weekday_start,
boost::posix_time::time_duration time_of_day_start,
boost::gregorian::greg_weekday weekday_end,
boost::posix_time::time_duration time_of_day_end) {
if (in_session(ref_date, weekday_start, time_of_day_start, weekday_end,
time_of_day_end))
return session_name_from_ptime(
closest_before(ref_date, weekday_start, time_of_day_start),
boost::posix_time::time_duration(0, 0, 0),
boost::posix_time::time_duration(0, 0, 1));
else
return std::string ();
return std::nullopt;
}
std::string session_name (datetime::PTime const &ref_date,
boost::posix_time::time_duration time_of_day_start,
boost::posix_time::time_duration time_of_day_end)
{
if (in_session (ref_date,time_of_day_start,time_of_day_end))
return session_name_from_ptime (ref_date, time_of_day_start, time_of_day_end);
std::optional<SessionName> session_name(datetime::PTime const &ref_date,
boost::posix_time::time_duration time_of_day_start,
boost::posix_time::time_duration time_of_day_end) {
if (in_session(ref_date, time_of_day_start, time_of_day_end))
return session_name_from_ptime(ref_date, time_of_day_start,
time_of_day_end);
else
return "";
return std::nullopt;
}
std::string session_name (config::JetFIX::Connection const &session_cfg)
{
auto now = datetime::local_now ();
std::optional<SessionName> session_name(config::JetFIX::Connection const &session_cfg) {
auto now = datetime::local_now();
if (session_cfg.has_start_day()) {
bts_assert(session_cfg.has_end_day());
return session_name(now, parse_weekday(session_cfg.start_day()),
parse_time(session_cfg.start_time()),
parse_weekday(session_cfg.end_day()),
parse_time(session_cfg.end_time()));
} else
return session_name(now, parse_time(session_cfg.start_time()),
parse_time(session_cfg.end_time()));
}
SessionSpan session_span(datetime::PTime const &ref_date,
boost::gregorian::greg_weekday weekday_start,
boost::posix_time::time_duration time_of_day_start,
boost::gregorian::greg_weekday weekday_end,
boost::posix_time::time_duration time_of_day_end) {
auto one_week = boost::gregorian::date_duration(7);
auto closest_earlier_start =
closest_before(ref_date, weekday_start, time_of_day_start);
auto closest_earlier_end =
closest_before(ref_date, weekday_end, time_of_day_end);
if (closest_earlier_end < closest_earlier_start)
// we are in the session
return {closest_earlier_start, closest_earlier_end + one_week };
else
// need to wait for the next session
return {closest_earlier_start+one_week, closest_earlier_end + one_week };
}
SessionSpan session_span(datetime::PTime const &ref_date,
boost::posix_time::time_duration time_of_day_start,
boost::posix_time::time_duration time_of_day_end) {
auto t = ref_date.time_of_day();
auto today = ref_date.date() ;
auto tomorrow = today + boost::gregorian::date_duration(1) ;
auto yesterday = today - boost::gregorian::date_duration(1) ;
if (session_cfg.has_start_day ()) {
bts_assert (session_cfg.has_end_day ());
return session_name (now,
parse_weekday (session_cfg.start_day ()),
parse_time (session_cfg.start_time ()),
parse_weekday (session_cfg.end_day ()),
parse_time (session_cfg.end_time ()));
} else
return session_name (now,
parse_time (session_cfg.start_time ()),
parse_time (session_cfg.end_time ()));
if (time_of_day_start < time_of_day_end) {
// scheduled start/scheduled end do not span midnight
if (t <= time_of_day_end) {
// we are inside the schedule
return {
datetime::PTime(today,time_of_day_start),
datetime::PTime(today,time_of_day_end)
};
}
else {
// too late for today, tomorrow is the time for the session
return {
datetime::PTime(tomorrow,time_of_day_start),
datetime::PTime(tomorrow,time_of_day_end)
};
}
} else {
// the start/stop span over midnight
if (t <= time_of_day_end) {
// we are inside the the schedule
return {
datetime::PTime(yesterday,time_of_day_start),
datetime::PTime(today,time_of_day_end)
};
}
else {
// too late, skip to next session
return {
datetime::PTime(today,time_of_day_start),
datetime::PTime(tomorrow,time_of_day_end)
};
}
}
}
SessionSpan session_span(config::JetFIX::Connection const &session_cfg) {
auto now = datetime::local_now();
}}
if (session_cfg.has_start_day()) {
bts_assert(session_cfg.has_end_day());
return session_span(now, parse_weekday(session_cfg.start_day()),
parse_time(session_cfg.start_time()),
parse_weekday(session_cfg.end_day()),
parse_time(session_cfg.end_time()));
} else
return session_span(now, parse_time(session_cfg.start_time()),
parse_time(session_cfg.end_time()));
}
} // namespace jetfix
} // namespace bts
+16 -3
View File
@@ -4,6 +4,8 @@
#include <string>
#include "lib/utils/datetime.h"
#include "lib/config/protos/jetfix.pb.h"
#include <boost/date_time/posix_time/posix_time.hpp>
#include <optional>
namespace boost {
namespace gregorian {
@@ -17,6 +19,11 @@ class time_duration;
namespace bts {
namespace jetfix {
struct SessionName {
std::string name;
datetime::PTime time;
};
boost::gregorian::greg_weekday parse_weekday (std::string weekday_str);
bool parse_time (std::string const &time_str,boost::posix_time::time_duration *out);
@@ -34,16 +41,22 @@ bool in_session (datetime::PTime const &ref_date,
boost::posix_time::time_duration time_of_day_start,
boost::posix_time::time_duration time_of_day_end);
std::string session_name (datetime::PTime const &ref_date,
std::optional<SessionName> session_name (datetime::PTime const &ref_date,
boost::gregorian::greg_weekday weekday_start,
boost::posix_time::time_duration time_of_day_start,
boost::gregorian::greg_weekday weekday_end,
boost::posix_time::time_duration time_of_day_end);
std::string session_name (datetime::PTime const &ref_date,
std::optional<SessionName> session_name (datetime::PTime const &ref_date,
boost::posix_time::time_duration time_of_day_start,
boost::posix_time::time_duration time_of_day_end);
std::string session_name (config::JetFIX::Connection const &session_cfg);
std::optional<SessionName> session_name (config::JetFIX::Connection const &session_cfg);
struct SessionSpan {
datetime::PTime start;
datetime::PTime stop;
};
SessionSpan session_span(config::JetFIX::Connection const&session_cfg);
}}
+1
View File
@@ -120,6 +120,7 @@ void configure_logging(bts::config::Logging const&cfg, bts::config::ThreadGroupC
{log::Plugin,"Plugin"},
{log::ClientSdk,"ClientSdk"},
{log::Http,"Http"},
{log::OrderMan2,"OrderMan2"},
};
real_cfg.sinks["console"] =
+3 -1
View File
@@ -24,7 +24,8 @@ constexpr log::Level Sys {log::Level::Max-1};
namespace log {
// Please keep this list in sync with Log.cs
// Please keep this list in sync with Log.cs and make sure
// to replicate the change in logging.cpp
constexpr log::Subsystem Gen {0 };
constexpr log::Subsystem Cfg {Gen.ordinal+1 };
constexpr log::Subsystem QBus {Cfg.ordinal+1 };
@@ -46,6 +47,7 @@ constexpr log::Subsystem DataFlow {Latency.ordinal+1 };
constexpr log::Subsystem Plugin {DataFlow.ordinal+1 };
constexpr log::Subsystem ClientSdk {Plugin.ordinal+1 };
constexpr log::Subsystem Http {ClientSdk.ordinal+1 };
constexpr log::Subsystem OrderMan2 {Http.ordinal+1 };
struct LoggerHandle {
LoggerHandle(LoggerHandle const&) = delete;
+3 -7
View File
@@ -80,9 +80,9 @@ class BrokerProxy : public ILocalBroker {
send(m);
}
void do_work(trace::PerfLog& log) {
void do_work(trace::PerfLog& ) {
_cycles++;
_outgoing.consume_all([this,&log](BrokerMsg *m) {
_outgoing.consume_all([this](BrokerMsg *m) {
switch (m->msg_type) {
case BrokerMsgType::ADD_NEIGHBOUR:
_real_broker.add_neighbour(*m->neighbour);
@@ -102,13 +102,9 @@ class BrokerProxy : public ILocalBroker {
case BrokerMsgType::UNSUBSCRIBE:
_real_broker.unsubscribe(m->broker_id, m->sub_id, m->stream_id);
break;
case BrokerMsgType::NOTIFY: {
LOG(Latency, Diag, "Notify broker {}. Cycles: {}", _id.value(),
_cycles);
auto scoped_do_work = trace::log_scope(log, {}, "BrokerProxy::notify");
case BrokerMsgType::NOTIFY:
_real_broker.notify(m->broker_id, m->stream_id, m->sub_id,
m->notification);
}
break;
case BrokerMsgType::LOCAL_SUBSCRIBE:
_real_broker.local_subscribe(m->local_sub_id, m->filter,
+14 -21
View File
@@ -1,45 +1,38 @@
#include "lib/mercury/executor/Executor.h"
#include "lib/mercury/broker/Broker.h"
#include "lib/mercury/broker/BrokerProxy.h"
#include "lib/mercury/actors/Actor.h"
#include "lib/mercury/actors/IPollableActor.h"
#include "lib/mercury/broker/Broker.h"
#include "lib/mercury/broker/BrokerProxy.h"
namespace bts {
namespace mercury {
Executor::Executor() :
_broker(),
_incoming_proxies(),
_my_proxy(make_proxy()),
_actor_broker(_my_proxy),
_actors() {}
Executor::Executor()
: _broker(), _incoming_proxies(), _my_proxy(make_proxy()),
_actor_broker(_my_proxy), _actors() {}
Executor::~Executor() {
for (auto &a : _actors)
a->deactivate();
}
void Executor::init_neighbours(std::vector<Executor*> const&neighbours)
{
void Executor::init_neighbours(std::vector<Executor *> const &neighbours) {
for (auto e : neighbours)
if (e != this)
if (e != this)
_outgoing_proxies.push_back(&e->make_proxy());
for (auto n : _outgoing_proxies)
_broker.add_neighbour(*n);
}
void Executor::activate(Actor *actor)
{
_actors.push_back(std::unique_ptr<Actor> (actor));
auto pollable = dynamic_cast<IPollableActor*> (actor);
void Executor::activate(Actor *actor) {
_actors.push_back(std::unique_ptr<Actor>(actor));
auto pollable = dynamic_cast<IPollableActor *>(actor);
if (pollable)
_pollable_actors.push_back(pollable);
actor->activate(_actor_broker);}
actor->activate(_actor_broker);
}
BrokerProxy& Executor::make_proxy()
{
BrokerProxy &Executor::make_proxy() {
_incoming_proxies.push_back(std::make_unique<BrokerProxy>(_broker));
return *_incoming_proxies.back();
}
+2 -2
View File
@@ -7,7 +7,6 @@
#include "lib/md/cme/MDP3Utils.h"
#include "lib/mercury/actors/Actor.h"
#include "lib/mercury/actors/IPollableActor.h"
#include "lib/mercury/events/TimerEvent.h"
#include "lib/orderman/events/BookUpdateEvent.h"
#include "lib/orderman/events/MDRequestEvent.h"
#include "lib/orderman/events/TickerUpdateEvent.h"
@@ -25,7 +24,8 @@ namespace orderman {
// polls a md consumer and publishes BookUpdate events when new MD is
// available. To avoid the overhead of maintaing synopsis as well as
// polling only relevant MD, observes a MDRequestEvent and limits
// updates to requested securities.
// updates to requested securities. Also provides trade and security
// status events in a similar on demand fashion.
class MDSource : public mercury::Actor, public mercury::IPollableActor {
public:
-1
View File
@@ -3,7 +3,6 @@
#include "lib/api/services/OrderService.pb.h"
#include "lib/mercury/actors/Actor.h"
#include "lib/orderman/events/StoredFillEvent.h"
#include "lib/md/SecurityOracle.h"
using namespace bts::api::orderman;
+1 -1
View File
@@ -42,7 +42,7 @@ class DynamicOrderRegistry;
} // namespace bts
// end fwds
// Provides a threading bridge between the quickbux/service world and
// Provides a threading bridge between the quickbus/service world and
// the mercury event broker.
namespace bts {
namespace orderman {
@@ -5,8 +5,8 @@
#include "lib/orderman/actors/order_manager/OrderServices.h"
#include "lib/orderman/actors/order_manager/OrderServicesData.h"
#include "lib/orderman/events/AccountPnLUpdateEvent.h"
#include "lib/orderman/events/FilledPositionEvent.h"
#include "lib/orderman/events/ExcessLiquidityUpdateEvent.h"
#include "lib/orderman/events/FilledPositionEvent.h"
#include "lib/orderman/events/NewAdminDataEvent.h"
#include "lib/orderman/events/NewSecuritiesEvent.h"
#include "lib/orderman/events/OrderManagerReadyEvent.h"
@@ -111,7 +111,8 @@ void OrderManager::on_excess_liquidity_update(
const mercury::Update<ExcessLiquidityUpdateEvent> &u) {
if (u.events)
for (auto ev : *u.events)
me->services_data.limiter.set_excess_liquidity(ev.account_id, ev.excess_liquidity);
me->services_data.limiter.set_excess_liquidity(ev.account_id,
ev.excess_liquidity);
}
void OrderManager::on_securities(
@@ -541,7 +542,7 @@ void OrderManager::init_order_services() {
std::make_unique<ContentSubscription<TickerUpdateEvent>>(
*this, on_ticker_sub, log);
me->services_data.status_subs =
std::make_unique<ContentSubscription<StatusUpdateEvent>>(
std::make_unique<ContentSubscription<StatusUpdateEvent>>(
*this, on_status_sub, log);
me->services_data.settlement_subs =
std::make_unique<ContentSubscription<SettlementUpdateEvent>>(
@@ -581,10 +582,7 @@ void OrderManager::reload_fix_buffer(SessionServicesData &osd) {
}
}
void OrderManager::on_poll(trace::PerfLog &log) {
auto scoped_do_work =
trace::log_scope(log, {}, "OrderManager::dispatch_incoming_fix_messages",
utils::TimeStamp::Interval::from_microseconds(2));
void OrderManager::on_poll(trace::PerfLog &) {
for (auto &osd : me->services_data.sessions)
osd->gw->dispatch_incoming_fix_messages();
}
@@ -2,9 +2,9 @@
#include "lib/config/protos/jetfix.pb.h"
#include "lib/jetfix/common/OutFIXPtr.h"
#include "lib/md/SecurityOracle.h"
#include "lib/mercury/actors/Actor.h"
#include "lib/mercury/actors/IPollableActor.h"
#include "lib/md/SecurityOracle.h"
#include "lib/orderman/events/ActivateOrderEvent.h"
#include "lib/orderman/events/CancelOrderEvent.h"
#include "lib/orderman/events/DetachOrderEvent.h"
@@ -64,8 +64,9 @@ namespace orderman {
class OrderManager : public mercury::Actor, public mercury::IPollableActor {
public:
OrderManager(DynamicOrderRegistry const &dyn_order_builder, trace::PerfLog &, md::SecurityOracle);
OrderManager(DynamicOrderRegistry const &, trace::PerfLog &,
md::SecurityOracle);
~OrderManager();
void init() override;
@@ -86,8 +87,9 @@ class OrderManager : public mercury::Actor, public mercury::IPollableActor {
void on_timer(const mercury::Update<mercury::TimerEvent> &);
void on_admin_data(const mercury::Update<NewAdminDataEvent> &);
void on_pnl_update(const mercury::Update<AccountPnLUpdateEvent> &);
void on_excess_liquidity_update(const mercury::Update<ExcessLiquidityUpdateEvent> &);
void on_poll(trace::PerfLog& log) override;
void on_excess_liquidity_update(
const mercury::Update<ExcessLiquidityUpdateEvent> &);
void on_poll(trace::PerfLog &log) override;
// end external events
void init_order_services();
@@ -97,8 +99,8 @@ class OrderManager : public mercury::Actor, public mercury::IPollableActor {
void after_event() override;
void add_child_order(OrderServices &parent, Order &child);
Order* lookup_order(OrderKey k);
Order *lookup_order(OrderKey k);
void publish_order_def_update(
OrderKey k,
std::shared_ptr<api::orderman::OrderDefinition const> const &def);
-65
View File
@@ -1,65 +0,0 @@
** Attach/Detach semantics
*** Semantics
- An order base definition can include a list of running orders to attach
to
- Each custom definition can have parameters that allow configuration
of the specific order type with respect to the attachment
list. Obvious configuration alternatives are:
- Attach to each of the listed orders directly or
- Forward attachment list to children
- Only orders with no parent or parents in a terminal state can be
attached to
- a detach(order_key) message can be sent to any order, even if that
order was not started through attachment to an existing order. the
expected semantics is for the order in question to stop managing the
child order and transition to completed.
*** API
- IOrderServices:
- attach_to_order(ok, std::function<void(Result,ChildOrder)>
on_attach_complete);
- detach(ChildOrder)
- Order
- on_detach(order_key)
- on_attached();
- on_detached();
message OrderDefinition {
CTICode cti_code = 9;
l CUSTOMERORFIRM customer_or_firm = 10;
OrderSubType sub_type = 12;
+ repeated uint32 attach_to_order = 13;
CustomOrderDefinition custom_def = 11;
}
* Order fields
| Field | Group | Muttable | on_attach |
|------------------------+--------------+----------+-------------|
| security_key | standard def | N | from child |
| side | | N | from child |
| user | | N | from parent |
| user_id | | Y | from parent |
| account | | Y | from parent |
| account_id | | Y | from parent |
| time_in_force | | N | from child |
| manual_order_indicator | | Y | from parent |
| cti_code | | N | from child |
| customer_or_firm | | N | from child |
| sub_type | | N | |
| attach_order | | N | |
|------------------------+--------------+----------+-------------|
| custom_def | custom_def | Y | from child |
| | | | |
|------------------------+--------------+----------+-------------|
| key | order_record | N | |
| parent_key | | Y | from parent |
|------------------------+--------------+----------+-------------|
| status | order_state | Y | |
| price | | Y | |
| quantity | | Y | |
| filled_quantity | | Y | |
| last_price | | Y | |
| avg_price | | Y | |
| last_msg | | Y | |
| created | | Y | |
| last_change | | Y | |
| custom_state | custom_state | Y | |
Binary file not shown.
@@ -5,9 +5,22 @@
| completed | O | | | |
| canceled | canceled | | | |
| error | X | | | |
| disconnected | | | | |
| disconnected | | | | |
| rejected by spark | X | | | |
* References
** Timmings
| thing | cost | note |
|-------------------------+------+----------------------|
| lock/unlock | 8 | test_and_set |
| shared_ptr cpy | 14 | |
| binary_search_int64/8 | 7 | |
| binary_search_int64/512 | 13 | |
| mem_copy/8 | 5 | |
| mem_copy/64 | 5 | |
| mem_copy/512 | 14 | |
| new/delete | 58 | |
| boost pool new/delete | 2 | no synchronizatio |
| boost pool new/delete | 19 | with synchronization |
** To Exchange
- [[https://www.cmegroup.com/confluence/display/EPICSANDBOX/New+Order][NewOrderSingle]]
- [[https://www.cmegroup.com/confluence/display/EPICSANDBOX/Order%2BCancel-Replace%2BRequest][CancelReplace]]
@@ -22,8 +35,8 @@
- Trade Correction
- [[https://www.cmegroup.com/confluence/display/EPICSANDBOX/Execution+Report+-+Trade+Correction][Msg]]
- [[https://www.cmegroup.com/confluence/display/EPICSANDBOX/Execution+Report+-+Trade+Correction][Discussion]]
* Order Chain trace
** NewOrder
** Order Chain trace
*** NewOrder
=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-=
BeginString = FIX.4.2 8=FIX.4.2
BodyLength = 271 9=271
@@ -95,7 +108,7 @@ ExpireDate = 20161102 432=20161102
5979 = 1478119007620967425 5979=1478119007620967425
7928 = 8056218 7928=8056218
CheckSum = 038 10=038
** Cancel
*** Cancel
=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-=
BeginString = FIX.4.2 8=FIX.4.2
BodyLength = 327 9=327
@@ -169,7 +182,7 @@ ExpireDate = 20161102 432=20161102
7928 = 8056218 7928=8056218
9717 = 2KjMkw-1C22h9-001v8Q 9717=2KjMkw-1C22h9-001v8Q
CheckSum = 033 10=033
** Cancel/Replace
*** Cancel/Replace
=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-=
BeginString = FIX.4.2 8=FIX.4.2
BodyLength = 344 9=344
@@ -247,7 +260,7 @@ ExpireDate = 20161102 432=20161102
9717 = 2KjMkw-1C22gp-001v8P 9717=2KjMkw-1C22gp-001v8P
CheckSum = 151 10=151
** Trade Correction
*** Trade Correction
=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-=
BeginString = FIX.4.2 8=FIX.4.2
BodyLength = 000234 9=000234
@@ -401,35 +414,7 @@ CheckSum = 207 10=207
37711 = MDTradeEntryID
ExecRefID
* Open Issues
- Re-Connection is done on the fast thread, slowing everything down
- Need to make sure there are no duplicate order state update events
- Once we have multiple OM's we will need to guarantee that they can
see each others order, which means we need to use some sort of
synopsis or other mechanism to ensure that they are synchronized
- fill mitigation
- should cancel on disconnect be on
- handling of reject
- garbage collection of orders
- garbage collection of fills
- consider including restatement reason
- see if handling of cancel rejects is any good
- impossible to shutdown orderservice at the moment
* Timmings
- 10.96.25.35
| thing | cost | note |
|-------------------------+------+----------------------|
| lock/unlock | 8 | test_and_set |
| shared_ptr cpy | 14 | |
| binary_search_int64/8 | 7 | |
| binary_search_int64/512 | 13 | |
| mem_copy/8 | 5 | |
| mem_copy/64 | 5 | |
| mem_copy/512 | 14 | |
| new/delete | 58 | |
| boost pool new/delete | 2 | no synchronizatio |
| boost pool new/delete | 19 | with synchronization |
* Notes on "A guide to spread trading futures"
** Notes on "A guide to spread trading futures"
- Correlations are discovered by traders
- Spread trading exploits correlations between securities and mean
reversion
@@ -471,47 +456,28 @@ ExecRefID
- Strategies
- Mean Reversion
* Open Issues
- Re-Connection is done on the fast thread, slowing everything down
- Need to make sure there are no duplicate order state update events
- Once we have multiple OM's we will need to guarantee that they can
see each others order, which means we need to use some sort of
synopsis or other mechanism to ensure that they are synchronized
- consider including restatement reason
- see if handling of cancel rejects is any good
- impossible to shutdown orderservice at the moment
* Event Flow
#+begin_src dot :file event_flow.pdf :cmdline -Kdot -Tpdf
digraph G {
bgcolor="transparent";
subgraph cluster_fast {
label="Fast Core";
GW
OMan
MDSrc
}
subgraph cluster_slow {
label="Slow Core";
FillStore
SecSrc
UI
OrderStore
Factory
}
OMan -> Factory [label=req]
Factory -> OMan [label=rep]
SecSrc -> GW [label=psec]
SecSrc -> OrderStore [label=psec]
SecSrc -> OMan [label=psec]
GW -> FillStore [label=xmsgs]
GW -> OMan [label=xmsgs]
OMan -> GW [label=fix]
OMan -> OrderStore [label=oupdate]
OrderStore -> OMan [label=rec_orders]
OrderStore -> UI [label=orecs]
FillStore-> UI [label=frecs]
UI -> OMan [label="crud"]
MDSrc -> OMan [label="md"]
}
#+END_SRC
#+RESULTS:
[[file:event_flow.pdf]]
| | MDSource | OManager | Timer | AsyncF | OrderStore | FillStore | SecSrc | MdSup | Bridge |
|------------+----------+----------+-------+--------+------------+-----------+--------+-------+--------|
| MSource | | | | | | | | | |
| OManager | | | | | | | | | |
| Timer | | | | | | | | | |
| AsyncF | | | | | | | | | |
| OrderStore | | | | | | | | | |
| FillStore | | | | | | | | | |
| SecSrc | | | | | | | | | |
| MdSup | | | | | | | | | |
| Bridge | | | | | | | | | |
|------------+----------+----------+-------+--------+------------+-----------+--------+-------+--------|
* Better event broker:
** unbundle events from topics and synopsis.
- develop Channels = Channel<Event,Tag,Synopsis>
@@ -560,3 +526,4 @@ digraph G {
- Recovery from disk
- Jetfix gateway threading model is wrong, cannot take one thread for
each session
* Rewrite <2019-09-23 Mon>
-25
View File
@@ -1,25 +0,0 @@
#pragma once
#include <memory>
#include "lib/mercury/events/Event.h"
#include "lib/orderman/orderman_utils/orderman_common.h"
#include "lib/tracing/PerfLog.h"
namespace bts {
namespace orderman {
class DetachOrderEvent : public mercury::Event<DetachOrderEvent> {
public:
using SynopsisPolicy = mercury::NoSynopsis;
DetachOrderEvent(uint32_t req_id, OrderKey k)
: req_id(req_id), k(k) {}
uint32_t req_id;
// used by ContentSubscription
OrderKey key() const { return k; }
OrderKey k;
};
} // namespace orderman
} // namespace bts
+27 -20
View File
@@ -1,31 +1,37 @@
#pragma once
#include <memory>
#include "lib/utils/bts_chrono.h"
#include <memory>
namespace bts {
namespace orderman {
class Governor
{
public:
Governor(uint32_t max_msgs_window,
uint32_t window_duration_msecs,
TimeStamp now = Timer::now()) :
_max_msgs_window(max_msgs_window),
_window_duration_msecs(window_duration_msecs),
_start_of_window(now),
_msgs_in_window(0)
{}
bool can_send(TimeStamp now = Timer::now()) const
{
class Governor {
public:
Governor() {
init(std::numeric_limits<uint32_t>::max(),
std::numeric_limits<uint32_t>::max(), Timer::now());
}
Governor(uint32_t max_msgs_window, uint32_t window_duration_msecs,
TimeStamp now = Timer::now()) {
init(max_msgs_window, window_duration_msecs, now);
}
void init(uint32_t max_msgs_window, uint32_t window_duration_msecs,
TimeStamp now) {
_max_msgs_window = max_msgs_window;
_window_duration_msecs = window_duration_msecs;
_start_of_window = now;
}
bool can_send(TimeStamp now = Timer::now()) const {
if (in_window(now))
return _msgs_in_window < _max_msgs_window;
else
return true;
}
void record_sent(TimeStamp now = Timer::now()) {
if (!in_window(now)) {
_start_of_window = now;
@@ -34,15 +40,16 @@ public:
_msgs_in_window++;
}
private:
private:
bool in_window(TimeStamp now) const {
return ms_diff (now, _start_of_window) <= _window_duration_msecs;
return ms_diff(now, _start_of_window) <= _window_duration_msecs;
}
uint32_t _max_msgs_window;
uint32_t _window_duration_msecs;
TimeStamp _start_of_window;
uint64_t _msgs_in_window;
};
}}
} // namespace orderman
} // namespace bts
+4 -2
View File
@@ -5,7 +5,9 @@ namespace orderman {
LimitStore::LimitStore(const bts::api::admin::AdminData &admin_data,
const std::map<uint32_t, api::Security const *> &sec_map)
: _admin_data(bts::admin::AdminServiceUtils::sort_limits(admin_data)) {
: _admin_data(bts::admin::AdminServiceUtils::sort_limits(admin_data)),
_margin_enabled(config::get<bts::config::SpanMargin>().enabled())
{
for (const auto& acct : _admin_data.accounts())
_account_data_map.insert(std::pair<uint32_t,AccountData>(
acct.id(),AccountData(acct)));
@@ -110,4 +112,4 @@ LimitStore::test_only_func_find_product_node(AccountID account_id,
return nullptr;
}
} // namespace orderman
} // namespace bts
} // namespace bts
+2 -1
View File
@@ -72,6 +72,7 @@ private:
// this is passed over to the SecurityLimitTree
// entried (above)
std::vector<ProductLimitTree> _prod_map;
bool _margin_enabled;
const bts::api::admin::AccountProductPositionLimitUnit _zero_product_limit;
public:
LimitStore(const bts::api::admin::AdminData& admin_data,
@@ -298,7 +299,7 @@ private:
if(account_ptr != nullptr){
const auto& account_data = *account_ptr;
const auto& account = account_data.account;
if(config::get<bts::config::SpanMargin>().enabled()) {
if(_margin_enabled) {
if (account.has_margin_limit() && account.margin_limit().enforce_margin()){
double ex_liq = account_data.excess_liquidity;
if(os::is_nan(ex_liq)){
@@ -18,12 +18,6 @@ struct DynamicOrderRegistry::PImpl {
DynamicOrderRegistry::DynamicOrderRegistry() : me(new PImpl()) {}
DynamicOrderRegistry::~DynamicOrderRegistry() {}
void DynamicOrderRegistry::register_dynamic_order(
api::orderman::DynamicOrderDescriptor const &desc,
DynamicOrderBuilder const &b) {
me->dyn_orders[desc.dynamic_order_type()] = std::make_pair(b, desc);
}
void DynamicOrderRegistry::register_dynamic_algo_order(
api::orderman::DynamicOrderDescriptor const &desc,
DynamicAlgoBuilder const &b) {
@@ -13,11 +13,6 @@ class DynamicOrderRegistry {
DynamicOrderRegistry();
~DynamicOrderRegistry();
// deprecated
void
register_dynamic_order(api::orderman::DynamicOrderDescriptor const &desc,
DynamicOrderBuilder const &builder);
void register_dynamic_algo_order(
api::orderman::DynamicOrderDescriptor const &desc,
DynamicAlgoBuilder const &builder);
@@ -72,6 +72,7 @@ OrderOpResult SplitterAlgo::do_before_launch(IBeforeLaunchAlgoServices& ibl) {
void SplitterAlgo::do_launch(IAlgoServices& ias) {
me->algo = &ias;
me->target_qty = ias.quantity().value();
ias.set_ladder_visibility(false);
// launches initial child orders
sync_orders();
}
@@ -15,6 +15,14 @@ namespace orderman {
class DynamicOrderRegistry;
class OrderOpResultEvent;
// Inputs:
// - order maintenance rpc calls from the shell
// - admin data from the admin service
// - position data from the position service
// - margin data from the margin service
// Outputs:
// - order state
// - fills
class OrderServiceServer : public api::orderman::OrderServiceBase {
public:
OrderServiceServer(bts::api::ServiceContext &context,
+122
View File
@@ -0,0 +1,122 @@
// #include "lib/orderman_v2/OrderManEngine.h"
// #include "lib/config/protos/orderman_cfg.pb.h"
// #include "lib/md/MDConsumer.h"
// #include "lib/orderman_v2/Thread.h"
// #include "lib/orderman_v2/components.h"
// #include <fmt/format.h>
// namespace bts {
// namespace orderman_v2 {
// struct ThreadRec {
// ThreadRec(config::OrderManThreadingCfg::Thread const &t_cfg)
// : thread(t_cfg.name(), t_cfg.poll()), cfg(t_cfg) {}
// Thread thread;
// config::OrderManThreadingCfg::Thread cfg;
// };
// struct MDSourceOM {
// MDSourceOM(md::MDConsumer &md) : md_source(md), manager() {}
// MDSource md_source;
// OrderManager manager;
// };
// struct OrderManEngine::PImpl {
// PImpl(md::MDConsumer &md) : md_consumer(md) {}
// std::map<std::string, std::unique_ptr<ThreadRec>> threads;
// Component<ServiceBridge> service_bridge;
// Component<Storage> storage;
// std::vector<Component<MDSourceOM>> order_managers;
// std::vector<Component<Gateway>> gateways;
// md::MDConsumer &md_consumer;
// };
// OrderManEngine::OrderManEngine(md::MDConsumer &md,
// config::OrderManThreadingCfg const &cfg)
// : me(new PImpl(md)) {
// init_threads(cfg);
// init_components();
// }
// void OrderManEngine::init_threads(config::OrderManThreadingCfg const &cfg) {
// for (auto const &t_cfg : cfg.thread()) {
// auto &thread_ptr = me->threads[t_cfg.name()];
// bts_assert_msg(
// !thread_ptr,
// fmt::format("Duplicate thread name {} in OrderManThreading "
// "configuration key",
// t_cfg.name()));
// thread_ptr = std::make_unique<ThreadRec>(t_cfg);
// }
// bts_assert("No threads in OrderManThreading configuration key");
// }
// void OrderManEngine::init_components() {
// for (auto const &p : me->threads) {
// auto const &tr = p.second;
// for (auto const &c : tr->cfg.component()) {
// if (c.name() == "service_bridge") {
// bts_assert_msg(!me->service_bridge.component,
// "Duplicate service_bridge component found in "
// "OrderManThreading configuration key");
// me->service_bridge.thread = &tr->thread;
// me->service_bridge.component = std::make_unique<ServiceBridge>();
// continue;
// }
// if (c.name() == "storage") {
// bts_assert_msg(!me->storage.component,
// "Duplicate storage component found in "
// "OrderManThreading configuration key");
// me->storage.thread = &tr->thread;
// me->storage.component = std::make_unique<Storage>();
// continue;
// }
// if (c.name() == "order_manager") {
// auto md_om = std::make_unique<MDSourceOM>(me->md_consumer);
// Component<MDSourceOM> c{std::move(md_om), &tr->thread};
// me->order_managers.emplace_back(std::move (c));
// continue;
// }
// if (c.name() == "gateway") {
// bts_assert_msg(
// c.arg_size() == 1,
// "Gateway component should have a single jetfix session "
// "name (arg: jf_session_name) in OrderManThreading"
// "configuration key");
// auto gw = std::make_unique<Gateway>(c.arg(0));
// Component<Gateway> c{std::move(gw), &tr->thread};
// me->gateways.emplace_back(std::move(c));
// continue;
// }
// }
// bts_assert_msg(me->service_bridge.component,
// "Missing service_bridge component in OrderManThreading "
// "configuration key");
// bts_assert_msg(
// me->storage.component,
// "Missing storage component in OrderManThreading configuration key");
// bts_assert_msg(
// me->order_managers.size(),
// "At least a order_manager component is required in OrderManThreading"
// "configuration key");
// bts_assert_msg(me->order_managers.size(),
// "At least a gateway component is required in "
// "OrderManThreading configuration key");
// }
// }
// } // namespace orderman_v2
// } // namespace bts
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include <memory>
#include <vector>
namespace bts {
namespace config {class OrderManThreadingCfg;}
namespace orderman_v2 {
class Thread;
class OrderManEngine {
public:
OrderManEngine(config::OrderManThreadingCfg const&);
~OrderManEngine();
void start();
void stop ();
private:
struct PImpl;
std::unique_ptr<PImpl> me;
void init_threads(config::OrderManThreadingCfg const&cfg);
void init_components();
void link_components();
};
}}
+126
View File
@@ -0,0 +1,126 @@
// #include "lib/orderman_v2/OrderManScheduler.h"
// #include "lib/config/protos/orderman_cfg.pb.h"
// #include "lib/md/MDConsumer.h"
// #include "lib/orderman_v2/Thread.h"
// #include "lib/orderman_v2/components.h"
// #include <fmt/format.h>
// namespace bts {
// namespace orderman_v2 {
// struct ThreadRec {
// ThreadRec(config::OrderManThreadingCfg::Thread const &t_cfg)
// : thread(t_cfg.name(), t_cfg.poll()), cfg(t_cfg) {}
// Thread thread;
// config::OrderManThreadingCfg::Thread cfg;
// };
// struct MDSourceOM {
// MDSourceOM(md::MDConsumer &md) : md_source(md), manager() {}
// MDSource md_source;
// OrderManager manager;
// };
// template <class C> struct Component {
// std::unique_ptr<C> component;
// Thread *thread;
// };
// struct OrderManScheduler::PImpl {
// PImpl(md::MDConsumer &md) : md_consumer(md) {}
// std::map<std::string, std::unique_ptr<ThreadRec>> threads;
// Component<ServiceBridge> service_bridge;
// Component<Storage> storage;
// std::vector<Component<MDSourceOM>> order_managers;
// std::vector<Component<Gateway>> gateways;
// md::MDConsumer &md_consumer;
// };
// OrderManScheduler::OrderManScheduler(md::MDConsumer &md,
// config::OrderManThreadingCfg const &cfg)
// : me(new PImpl(md)) {
// init_threads(cfg);
// init_components();
// }
// void OrderManScheduler::init_threads(config::OrderManThreadingCfg const &cfg) {
// for (auto const &t_cfg : cfg.thread()) {
// auto &thread_ptr = me->threads[t_cfg.name()];
// bts_assert_msg(
// !thread_ptr,
// fmt::format("Duplicate thread name {} in OrderManThreading "
// "configuration key",
// t_cfg.name()));
// thread_ptr = std::make_unique<ThreadRec>(t_cfg);
// }
// bts_assert("No threads in OrderManThreading configuration key");
// }
// void OrderManScheduler::init_components() {
// for (auto const &p : me->threads) {
// auto const &tr = p.second;
// for (auto const &c : tr->cfg.component()) {
// if (c.name() == "service_bridge") {
// bts_assert_msg(!me->service_bridge.component,
// "Duplicate service_bridge component found in "
// "OrderManThreading configuration key");
// me->service_bridge.thread = &tr->thread;
// me->service_bridge.component = std::make_unique<ServiceBridge>();
// continue;
// }
// if (c.name() == "storage") {
// bts_assert_msg(!me->storage.component,
// "Duplicate storage component found in "
// "OrderManThreading configuration key");
// me->storage.thread = &tr->thread;
// me->storage.component = std::make_unique<Storage>();
// continue;
// }
// if (c.name() == "order_manager") {
// auto md_om = std::make_unique<MDSourceOM>(me->md_consumer);
// Component<MDSourceOM> c{std::move(md_om), &tr->thread};
// me->order_managers.emplace_back(std::move (c));
// continue;
// }
// if (c.name() == "gateway") {
// bts_assert_msg(
// c.arg_size() == 1,
// "Gateway component should have a single jetfix session "
// "name (arg: jf_session_name) in OrderManThreading"
// "configuration key");
// auto gw = std::make_unique<Gateway>(c.arg(0));
// Component<Gateway> c{std::move(gw), &tr->thread};
// me->gateways.emplace_back(std::move(c));
// continue;
// }
// }
// bts_assert_msg(me->service_bridge.component,
// "Missing service_bridge component in OrderManThreading "
// "configuration key");
// bts_assert_msg(
// me->storage.component,
// "Missing storage component in OrderManThreading configuration key");
// bts_assert_msg(
// me->order_managers.size(),
// "At least a order_manager component is required in OrderManThreading"
// "configuration key");
// bts_assert_msg(me->order_managers.size(),
// "At least a gateway component is required in "
// "OrderManThreading configuration key");
// }
// }
// } // namespace orderman_v2
// } // namespace bts
+28
View File
@@ -0,0 +1,28 @@
#pragma once
#include <memory>
#include <vector>
namespace bts {
namespace md {class MDConsumer;}
namespace config {class OrderManThreadingCfg;}
namespace orderman_v2 {
class Thread;
class OrderManScheduler {
public:
OrderManScheduler(md::MDConsumer &,config::OrderManThreadingCfg const&);
~OrderManScheduler();
void start();
void stop ();
private:
struct PImpl;
std::unique_ptr<PImpl> me;
void init_threads(config::OrderManThreadingCfg const&cfg);
void init_components();
void link_components();
};
}}
+14
View File
@@ -0,0 +1,14 @@
#include "Actor.h"
#include "lib/orderman_v2/interconnect/Thread.h"
namespace bts {
namespace orderman_v2 {
Actor::~Actor() {}
Queue* Actor::get_target_queue(Actor &target_actor) {
return target_actor._owner_thread->get_queue(*_owner_thread);
}
}}
+25
View File
@@ -0,0 +1,25 @@
#pragma once
namespace bts {
namespace orderman_v2 {
class Queue;
class Thread;
class Actor {
public:
virtual ~Actor() ;
virtual void init() {}
virtual void finit() {}
private:
friend class Thread;
template <class A> friend class Signal;
// Returns nullptr is the this actor and the target are on the same thread
Queue* get_target_queue(Actor &target_actor);
void set_owner_thread(Thread &owner) { _owner_thread = &owner; }
Thread *_owner_thread = nullptr;
};
} // namespace orderman_v2
} // namespace bts
+10
View File
@@ -0,0 +1,10 @@
#include "MDSource.h"
namespace bts {
namespace orderman_v2 {
MDSource::MDSource(md::MDConsumer &)
: on_book(this), on_ticker(this), on_sec_status(this) {}
} // namespace orderman_v2
} // namespace bts
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include "Actor.h"
#include "lib/orderman_v2/events/events.h"
#include "lib/orderman_v2/common.h"
#include "lib/orderman_v2/interconnect/Signal.h"
namespace bts {
namespace md {class MDConsumer;}
namespace orderman_v2 {
class MDSource : public Actor {
public:
MDSource(md::MDConsumer &consumer) ;
// Inputs
void on_md_request(MDRequest const&) {};
// Signals
Signal<BookUpdate> on_book;
Signal<TickerUpdate> on_ticker;
Signal<SecurityStatusUpdate> on_sec_status;
};
}}
@@ -0,0 +1,11 @@
#include "OrderManager.h"
namespace bts {
namespace orderman_v2 {
OrderManager::OrderManager()
: on_gw_op(this), on_order_update(this), on_om_reply(this),
on_md_request(this), on_om_bootstrap_orders(this) {}
} // namespace orderman_v2
} // namespace bts
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include "Actor.h"
#include "lib/orderman_v2/events/events.h"
#include "lib/orderman_v2/common.h"
#include "lib/orderman_v2/interconnect/Signal.h"
namespace bts {
namespace orderman_v2 {
class OrderManager : public Actor {
public:
OrderManager();
// Inputs
void on_bootstrap_orders(BootstrapOrders) {}
void on_native_order_update (GW_OrderReport const&) {}
void on_unknown_native_order_update(GW_UnknownOrderExeReport const&) {}
void on_create_order (CreateOrderRequest const&) {}
void on_update_order (UpdateOrderRequest const&) {}
void on_cancel_order (CancelOrderRequest const&) {}
void on_detach_order (DetachOrderRequest const&) {}
void on_book(BookUpdate const&) {}
void on_ticker(TickerUpdate const&) {}
void on_sec_status(SecurityStatusUpdate const&) {}
void on_admin_data(const AdminDataUpdate &) {}
// Signals
Signal<GW_Op_Batch> on_gw_op;
Signal<OM_OrderUpdate> on_order_update;
Signal<OM_Reply> on_om_reply;
Signal<MDRequest> on_md_request;
Signal<OM_BootstrapOrders> on_om_bootstrap_orders;
};
}}
@@ -0,0 +1,18 @@
#include "ServiceBridge.h"
namespace bts {
namespace orderman_v2 {
ServiceBridge::ServiceBridge() :
on_create_order(this),
on_update_order(this),
on_cancel_order(this),
on_detach_order(this),
on_admin_data(this),
on_excess_liquidity(this),
on_account_pnl(this),
on_position(this)
{}
} // namespace orderman_v2
} // namespace bts
@@ -0,0 +1,37 @@
#pragma once
#include "Actor.h"
#include "lib/orderman_v2/events/events.h"
#include "lib/orderman_v2/common.h"
#include "lib/orderman_v2/interconnect/Signal.h"
namespace bts {
namespace orderman_v2 {
class ServiceBridge : public Actor {
public:
ServiceBridge();
// Inputs
void on_bootstrap_orders(BootstrapOrders) {}
void on_bootstrap_fills(BootstrapFills) {}
void on_new_stored_order(api::orderman::OrderRecord const*) {}
void on_new_stored_fill(api::orderman::Fill const*) {}
void on_gw_status(GW_Status const&) {}
void on_gw_error(GW_Error const&) {}
void on_om_reply(OM_Reply const&) {}
// Signals
Signal<CreateOrderRequest> on_create_order;
Signal<UpdateOrderRequest> on_update_order;
Signal<CancelOrderRequest> on_cancel_order;
Signal<DetachOrderRequest> on_detach_order;
Signal<AdminDataUpdate> on_admin_data;
Signal<ExcessLiquidityUpdate> on_excess_liquidity;
Signal<AccountPnLUpdate> on_account_pnl;
Signal<PositionUpdate> on_position;
};
}}
+12
View File
@@ -0,0 +1,12 @@
#include "Storage.h"
namespace bts {
namespace orderman_v2 {
Storage::Storage()
: on_bootstrap_orders(this), on_venue_checkpoint(this),
on_bootstrap_fills(this), on_new_stored_order(this),
on_new_stored_fill(this) {}
} // namespace orderman_v2
} // namespace bts
+28
View File
@@ -0,0 +1,28 @@
#pragma once
#include "Actor.h"
#include "lib/orderman_v2/events/events.h"
#include "lib/orderman_v2/common.h"
#include "lib/orderman_v2/interconnect/Signal.h"
namespace bts {
namespace orderman_v2 {
class Storage : public Actor {
public:
Storage();
// Inputs
void on_order_update (OM_OrderUpdate const&) {}
// Signals
Signal<BootstrapOrders> on_bootstrap_orders;
Signal<VenueCheckpointNotice> on_venue_checkpoint;
Signal<BootstrapFills> on_bootstrap_fills;
Signal<api::orderman::OrderRecord const*> on_new_stored_order;
Signal<api::orderman::Fill const*> on_new_stored_fill;
};
}}
@@ -0,0 +1,25 @@
#pragma once
#include "lib/orderman_v2/common.h"
#include "lib/orderman_v2/actors/gateway/fix/VenueCheckpoint.h"
namespace bts {
namespace orderman_v2 {
class IFullExeReportMsg;
class ExecReport {
public:
OrderKey order_key;
Quantity quantity;
Quantity total_fills;
Quantity last_fills;
Price price;
Price avg_price;
Price last_price;
OrderStatus status;
VenueCheckpoint checkpoint;
IFullExeReportMsg const *msg;
};
}}
@@ -0,0 +1,637 @@
#include "Gateway.h"
#include "lib/logging/logging.h"
#include "lib/orderman/limiter/Limiter.h"
#include "lib/orderman_v2/actors/gateway/ICancelMsg.h"
#include "lib/orderman_v2/actors/gateway/ICancelReplaceMsg.h"
#include "lib/orderman_v2/actors/gateway/ILimiter.h"
#include "lib/orderman_v2/actors/gateway/INewOrderSingleMsg.h"
#include "lib/orderman_v2/actors/gateway/IRouter.h"
#include "lib/orderman_v2/actors/gateway/IVenue.h"
#include "lib/orderman_v2/actors/gateway/UserAccountVenue.h"
#include "lib/orderman_v2/utils/FAFStore.h"
#include "lib/utils/bts_chrono.h"
#include <boost/pool/object_pool.hpp>
#include <unordered_map>
namespace bts {
namespace orderman_v2 {
// utilities
template <class Req> GW_Op_Ack make_ack(Req const &r) {
return GW_Op_Ack{GW_OP_Result::OK, r.req_id, nullptr};
}
struct Gateway::OrderRec {
OrderRec() = default;
OrderRec(OM_ID om_id, GW_BoundOrder const &order)
: order(order), cancel_replace(nullptr), cancel(nullptr),
originator(om_id) {}
GW_BoundOrder order;
ICancelReplaceMsg *cancel_replace;
ICancelMsg *cancel;
OM_ID originator;
GW_Op_Ack last_ack;
void clear_msgs() {
cancel_replace = nullptr;
cancel = nullptr;
}
bool is_routable() const { return cancel_replace != nullptr; }
void set_msgs(ICancelReplaceMsg const &cr, ICancelMsg &can) {
cancel_replace = &cr.clone();
cancel = &can.clone();
}
};
class Gateway::OrderMap {
public:
OrderRec *lookup(OrderKey k) { return _store.lookup(k.value); }
OrderRec *make_and_store(OM_ID om_id, GW_BoundOrder const &bo) {
return _store.make_and_index(bo.key.value, om_id, bo);
}
void remove(OrderKey k) { _store.remove(k.value); }
std::vector<OrderRec *> get_all() { return _store.get_all(); }
private:
FAFStore<OrderRec> _store;
};
enum class Gateway::State {
W_BOOTSTRAP,
W_SCHEDULE,
PAUSED,
W_LOGON,
READY,
};
struct Gateway::Hot {
using MsgTemplatesMap =
std::unordered_map<UserAccountVenue, MsgTemplates, UserAccountVenueHash>;
Hot(IVenue &v, ILimiter &l)
: state(State::W_BOOTSTRAP), venue(v), limiter(l), working_orders(),
pending_msgs(), msg_templates() {}
State state;
IVenue &venue;
ILimiter &limiter;
// TODO: Separate ourders that cannot be routed from working orders to avoid
// the if is_routable() on order events
OrderMap working_orders;
boost::container::small_vector<IVenueMsg *, 8> pending_msgs;
MsgTemplatesMap msg_templates;
};
struct Gateway::Cold {
Cold(IRouter &r, IClock &c, GatewayCfg const &cfg)
: router(r), clock(c), admin_data(), cfg(cfg), start_of_pause(),
current_exponential_backoff(0), bootstrap_orders(), interned_strings () {}
IRouter &router;
IClock &clock;
api::admin::AdminData const *admin_data;
GatewayCfg cfg;
TimeStamp start_of_pause;
size_t current_exponential_backoff;
SessionSpan session_span;
std::map<OM_ID, std::vector<GW_OrderBind> *> bootstrap_orders;
std::set<std::string> interned_strings;
};
struct Gateway::PImpl {
PImpl(IVenue &v, ILimiter &l, IRouter &r, IClock &c, GatewayCfg const &cfg)
: hot(v, l), cold(r, c, cfg) {}
Hot hot;
Cold cold;
};
Gateway::Gateway(IVenue &v, ILimiter &l, IRouter &r, IClock &c,
GatewayCfg const &cfg)
: on_order_report(this), on_unknown_native_order_update(this),
on_gw_error(this), me(new PImpl(v, l, r, c, cfg)) {
me->hot.venue.set_observer(*this);
}
Gateway::~Gateway() {}
void Gateway::do_slow_work() {
switch (me->hot.state) {
case State::W_BOOTSTRAP:
if (has_bootstrap_data()) {
setup_bootstrap_orders();
transition(State::W_SCHEDULE);
}
break;
case State::W_SCHEDULE:
me->cold.session_span = me->hot.venue.get_current_session_span();
if (in_active_schedule()) {
me->cold.start_of_pause = me->cold.clock.now();
transition(State::PAUSED);
}
break;
case State::PAUSED: {
auto now = me->cold.clock.now();
if (sec_diff(now, me->cold.start_of_pause) >
(me->cold.cfg.pause_seconds
<< me->cold.current_exponential_backoff)) {
transition(State::W_LOGON);
me->hot.venue.login();
}
break;
}
case State::READY: {
break;
}
case State::W_LOGON:
break;
}
}
void Gateway::on_om_bootstrap_orders(OM_BootstrapOrders const &orders) {
bts_assert(me->hot.state == State::W_BOOTSTRAP);
auto &bso_map = me->cold.bootstrap_orders;
bts_assert(bso_map.size() < me->cold.cfg.om_count);
bts_assert(bso_map.count(orders.originator) == 0);
bts_assert(orders.target == me->cold.cfg.my_id);
bts_assert(orders.originator.value < me->cold.cfg.om_count);
bso_map[orders.originator] = orders.orders;
}
void Gateway::on_gw_ops(const GW_Op_Batch &op_batch) {
op_batch.visit(*this);
send_pending_msgs();
}
void Gateway::on_account_pnl(const AccountPnLUpdate &pnl) {
me->hot.limiter.update(pnl);
}
void Gateway::on_position(const PositionUpdate &pos) {
me->hot.limiter.update(pos);
}
void Gateway::on_excess_liquidity(const ExcessLiquidityUpdate &l) {
me->hot.limiter.update(l);
}
void Gateway::on_admin_data(AdminDataUpdate const &admin) {
me->hot.limiter.update(*me->cold.admin_data);
me->cold.router.update(*me->cold.admin_data);
switch (me->hot.state) {
case State::W_BOOTSTRAP:
me->cold.admin_data = admin.admin_data;
break;
default:
rebuild_msg_templates();
}
}
void Gateway::on_venue_checkpoint(const VenueCheckpointNotice &notice) {
me->hot.venue.set_checkpoint(notice.checkpoint);
}
void Gateway::on_venue_login_success(std::vector<ExecReport> const &recovered) {
bts_assert(me->hot.state == State::W_LOGON);
me->cold.current_exponential_backoff = 0;
transition(State::READY);
for (auto const &er : recovered)
on_venue_exe_report(er);
}
void Gateway::on_venue_login_failure() {
bts_assert(me->hot.state == State::W_LOGON);
if (in_active_schedule()) {
me->cold.current_exponential_backoff ++;
transition(State::PAUSED);
}
else {
me->cold.current_exponential_backoff = 0;
transition(State::W_SCHEDULE);
}
}
void Gateway::on_venue_disconnect() {
bts_assert(me->hot.state == State::READY);
auto all_working = me->hot.working_orders.get_all();
for (auto orec : all_working) {
GW_Error error;
error.gw = me->cold.cfg.my_id;
error.error_code = GW_Error::DISCONNECT;
error.error_msg = "Venue disconnected";
error.order_key = orec->order.key;
on_gw_error(error);
}
}
void Gateway::on_venue_exe_report(const ExecReport &report) {
bts_assert(me->hot.state == State::READY);
auto r = me->hot.working_orders.lookup(report.order_key);
if (r) {
// This is an order we have seen before. This is the normal
// path.
r->order.last_exe_report = report;
// If the order is no longer working then we remove it from the
// working index.
if (report.status != OrderStatus::WORKING)
me->hot.working_orders.remove(report.order_key);
on_order_report(make_order_report(r));
} else if (report.status == OrderStatus::WORKING) {
auto sec = me->hot.venue.resolve_security(report);
if (sec)
on_unknown_native_order_update ( {sec,me->cold.cfg.my_id,report});
}
}
void Gateway::on_venue_error(VenueError const &v_error) {
GW_Error gw_error;
switch (v_error.error_code) {
case VenueError::CANCEL_REJECT:
gw_error.error_code = GW_Error::CANCEL_REJECT;
break;
case VenueError::BUSINESS_REJECT:
gw_error.error_code = GW_Error::BUSINESS_REJECT;
break;
case VenueError::SESSION_REJECT:
gw_error.error_code = GW_Error::SESSION_REJECT;
break;
default:
gw_error.error_code = GW_Error::OTHER;
break;
}
gw_error.error_msg = intern_string(v_error.error_msg);
gw_error.order_key = v_error.order_key;
on_gw_error(gw_error);
}
void Gateway::on_gw_op(OM_ID om_id, const GW_OrderCreate &create) {
bts_assert_d(me->hot.working_orders.lookup(create.bound_order.key) ==
nullptr);
// Construct new order record
auto gw_rec =
me->hot.working_orders.make_and_store(om_id, create.bound_order);
auto &order = gw_rec->order;
auto &ack = gw_rec->last_ack;
ack = make_ack(create);
switch (me->hot.state) {
case State::READY: {
// Validate route
auto &msg_templates = me->hot.msg_templates;
INewOrderSingleMsg *new_order_single;
auto it = msg_templates.find(order.uav);
if (it == msg_templates.end()) {
ack.result = GW_OP_Result::ERROR_NO_ROUTE;
break;
}
// TODO: Replace the chained ifs with the accumulate error flags
// and check them once.
// Set msgs in order record
new_order_single = &it->second.new_order->clone();
gw_rec->set_msgs(*it->second.cancel_replace, *it->second.cancel);
// Validate risk limit
auto lqt = me->hot.limiter.can_send_new_order(
order.uav.account, *order.security, order.side, order.quantity);
if (lqt.error()) {
ack.result = lqt.result;
ack.message = lqt.message;
break;
}
// Validate messaging limits
if (!me->hot.venue.under_messaging_limit()) {
ack.result = GW_OP_Result::ERROR_MESSAGING_BREACH;
break;
}
// All is good. Copy the order params to the order message and
// queue the message for sending.
new_order_single->set_order_params(order);
me->hot.pending_msgs.push_back(new_order_single);
// For speed we do not send acks for the operation until we hear
// from the exchange.
return;
}
default:
ack.result = GW_OP_Result::ERROR_GATEWAY_DISCONNECTED;
break;
}
// If we got to this point something went wrong and the creation of
// the order failed. Since the order is already indexed we need to
// remove it from the store. Additionally, because we will never
// hear from the exchange on this order we have to send our ack
// now. This is an exceptional path, it should almost never happen.
bts_assert_d(ack.result != GW_OP_Result::OK);
auto report = make_order_report(gw_rec);
me->hot.working_orders.remove(order.key);
on_order_report(report);
}
// When an order is recovered from disk or from the exchange (meaning
// the exchange sends a report for an order we do not have a record of
// creating) we are left in a situation where we have to create the
// order record that represents the order but we do not have to
// actually send the order to the exchange. This is what the bind
// order operation is for.
void Gateway::on_gw_op(OM_ID om_id, const GW_OrderBind &bind) {
bts_assert_d(me->hot.working_orders.lookup(bind.bound_order.key) == nullptr);
// Construct new order record
auto gw_rec = me->hot.working_orders.make_and_store(om_id, bind.bound_order);
auto &order = gw_rec->order;
auto &ack = gw_rec->last_ack;
ack = make_ack(bind);
// Find the message templates for this UAV and clone them for this
// order
auto &msg_templates = me->hot.msg_templates;
auto it = msg_templates.find(order.uav);
if (it == msg_templates.end())
ack.result = GW_OP_Result::ERROR_NO_ROUTE;
// In this case we have to send a reply to the bind operation
// because there is no guarantee that we will be able to piggy back
// the reply on the next exchange acknowledgement (which may never
// come).
on_order_report(make_order_report(gw_rec));
}
// A quick update is an update of just price and quantity. This is the
// most common type of order change so we special case it so that we
// can re-use the update message fields that will not change (which is
// everything but quantity and price)
void Gateway::on_gw_op(OM_ID, const GW_OrderQuickUpdate &quick_update) {
auto gw_rec = me->hot.working_orders.lookup(quick_update.order_key);
auto &ack = gw_rec->last_ack;
ack = make_ack(quick_update);
switch (me->hot.state) {
case State::READY: {
// Do we know about this order?
if (!gw_rec) {
ack.result = GW_OP_Result::ERROR_ORDER_IS_NOT_ACTIVE;
break;
}
// Can we route it?
if (!gw_rec->is_routable()) {
ack.result = GW_OP_Result::ERROR_NO_ROUTE;
break;
}
auto &order = gw_rec->order;
// Validate trading limits
auto delta_q = quick_update.quantity.value - order.quantity.value;
auto lqr = me->hot.limiter.can_update_order(
order.uav.account, *order.security, order.side, delta_q);
if (lqr.error()) {
ack.result = lqr.result;
ack.message = lqr.message;
break;
}
// Validate messaging limits
if (!me->hot.venue.under_messaging_limit()) {
ack.result = GW_OP_Result::ERROR_MESSAGING_BREACH;
break;
}
order.price = quick_update.price;
order.quantity = quick_update.quantity;
gw_rec->cancel_replace->update(order);
me->hot.pending_msgs.push_back(gw_rec->cancel_replace);
// We do not send out a order report for performance
// reasons. Instead we delay the report until the exchange
// reponds our order update.
return;
}
default:
ack.result = GW_OP_Result::ERROR_GATEWAY_DISCONNECTED;
break;
}
// If we got here something went wrong and the update failed. This
// is the exceptional path and it should almost never happen. In
// this case we send out a new order report detailing the reasons
// for the failure.
bts_assert(ack.result != GW_OP_Result::OK);
on_order_report(make_order_report(gw_rec));
}
// The difference between a full update and a quick update is that in
// a full update we allow for the account / user to change. In this
// case we have to re-create the messages for cancel and update since
// these messages embed in them account and user specific information.
void Gateway::on_gw_op(OM_ID om_id, const GW_OrderFullUpdate &full_update) {
auto gw_rec = me->hot.working_orders.lookup(full_update.order_key);
auto &ack = gw_rec->last_ack;
ack = make_ack(full_update);
switch (me->hot.state) {
case State::READY: {
// Do we know about this order?
if (!gw_rec) {
ack.result = GW_OP_Result::ERROR_ORDER_IS_NOT_ACTIVE;
break;
}
// Can we route it?
if (!gw_rec->is_routable()) {
ack.result = GW_OP_Result::ERROR_NO_ROUTE;
break;
}
auto &order = gw_rec->order;
auto &msg_templates = me->hot.msg_templates;
auto it = msg_templates.find(order.uav);
if (it == msg_templates.end()) {
ack.result = GW_OP_Result::ERROR_NO_ROUTE;
gw_rec->clear_msgs();
break;
}
// Update existing record with the non quick parts of the full
// order update. There is a bit of inconsistency here. We are
// already setting the message templates, uav, moi and tif
// fields below, even though the quick update might later fail
// to set the quantity and price. This could leave the order in
// a half-updated half not-updated state. This should be rare
// and benign enough so we live with it.
gw_rec->set_msgs(*it->second.cancel_replace, *it->second.cancel);
gw_rec->order.uav = full_update.uav;
gw_rec->order.moi = full_update.moi;
gw_rec->order.tif = full_update.tif;
// Fake a quick update, now that we already set the other fields
GW_OrderQuickUpdate quick_update;
quick_update.order_key = full_update.order_key;
quick_update.quantity = full_update.quantity;
quick_update.price = full_update.price;
quick_update.req_id = full_update.req_id;
on_gw_op(om_id, quick_update);
break;
}
default:
ack.result = GW_OP_Result::ERROR_GATEWAY_DISCONNECTED;
break;
}
// If we got to this point something went wrong and the update of
// the order failed. This should be very rare. In this case we send
// a reply right away.
bts_assert(ack.result != GW_OP_Result::OK);
on_order_report(make_order_report(gw_rec));
}
void Gateway::on_gw_op(OM_ID, const GW_OrderCancel &cancel) {
auto gw_rec = me->hot.working_orders.lookup(cancel.order_key);
auto &ack = gw_rec->last_ack;
ack = make_ack(cancel);
switch (me->hot.state) {
case State::READY: {
// Do we know about this order?
if (!gw_rec) {
ack.result = GW_OP_Result::ERROR_ORDER_IS_NOT_ACTIVE;
break;
}
// Can we route it?
if (!gw_rec->is_routable()) {
ack.result = GW_OP_Result::ERROR_NO_ROUTE;
break;
}
auto &order = gw_rec->order;
gw_rec->cancel->update(order);
me->hot.pending_msgs.push_back(gw_rec->cancel);
// We do not send out a order report yet for performance
// reasons. Instead we delay the report until the exchange
// reponds to our cancel
return;
}
default:
ack.result = GW_OP_Result::ERROR_GATEWAY_DISCONNECTED;
break;
}
// If we got here something went wrong and the cancel failed. This
// is the exceptional path and it should almost never happen. In
// this case we send out a new order report detailing the reasons
// for the failure.
bts_assert(ack.result != GW_OP_Result::OK);
on_order_report(make_order_report(gw_rec));
}
const char* Gateway::intern_string(std::string const&str) {
auto [it,_] = me->cold.interned_strings.insert(str);
(void)_;
return it->data();
}
void Gateway::send_pending_msgs() {
auto &pending = me->hot.pending_msgs;
// TODO: Need to make sure that there is no danger of reentrancy
// here, in the case that venue calls us back from the send call
me->hot.venue.send(pending.data(), (pending.data() + pending.size()));
pending.clear();
}
bool Gateway::has_bootstrap_data() const {
return me->cold.bootstrap_orders.size() == me->cold.cfg.om_count &&
me->cold.admin_data != nullptr;
}
bool Gateway::in_active_schedule() const {
auto now = me->cold.clock.ptime_now();
return now >= me->cold.session_span.start &&
now < me->cold.session_span.stop;
}
void Gateway::transition(State state) {
LOG(OrderMan, Info, "Transitioning gateway {} from {} to {}",
me->cold.cfg.my_id.value, state_name(me->hot.state), state_name(state));
me->hot.state = state;
}
void Gateway::rebuild_msg_templates() {
// First just rebuild our template cache
me->hot.msg_templates.clear();
auto all_uav = me->hot.limiter.get_all_user_account_venue();
for (auto const &uav : all_uav) {
auto rq = me->cold.router.get_route(uav);
if (rq.has_route) {
me->hot.msg_templates[uav] =
me->hot.venue.get_msg_templates(rq.routing_record);
}
}
// Now go through every order and update its messages
auto working = me->hot.working_orders.get_all();
for (auto &orec : working) {
orec->clear_msgs();
if (auto it = me->hot.msg_templates.find(orec->order.uav);
it != me->hot.msg_templates.end()) {
orec->set_msgs(*it->second.cancel_replace, *it->second.cancel);
} else {
LOG(OrderMan, Error, "Order {} can no longer be routed. {}",
orec->order.key, orec->order.uav.to_str());
orec->clear_msgs();
}
}
}
void Gateway::setup_bootstrap_orders() {
bts_assert(me->hot.state == State::W_BOOTSTRAP);
for (auto [om_id, order_vec] : me->cold.bootstrap_orders)
for (auto &bind_order : *order_vec)
on_gw_op(om_id, bind_order);
me->cold.bootstrap_orders.clear();
}
GW_OrderReport Gateway::make_order_report(OrderRec *gw_rec) {
GW_OrderReport report;
report.last_exe_report = gw_rec->order.last_exe_report;
report.last_ack = gw_rec->last_ack;
report.target = gw_rec->originator;
return report;
}
log::CharPtrWrapper Gateway::state_name(State state) {
switch (state) {
case State::W_BOOTSTRAP:
return {"W_BOOTSTRAP"};
case State::W_SCHEDULE:
return {"W_SCHEDULE"};
case State::PAUSED:
return {"PAUSED"};
case State::W_LOGON:
return {"W_LOGON"};
case State::READY:
return {"READY"};
}
return {""};
}
} // namespace orderman_v2
} // namespace bts
@@ -0,0 +1,78 @@
#pragma once
#include "lib/logging/logging.h"
#include "lib/orderman_v2/actors/Actor.h"
#include "lib/orderman_v2/common.h"
#include "lib/orderman_v2/events/events.h"
#include "lib/orderman_v2/interconnect/ISlowWorker.h"
#include "lib/orderman_v2/interconnect/Signal.h"
#include "lib/orderman_v2/actors/gateway/IVenueObserver.h"
namespace bts {
namespace orderman_v2 {
class IVenue;
class ILimiter;
class IRouter;
class IClock;
struct GatewayCfg;
class Gateway : public Actor, ISlowWorker, IGW_Op_Visitor, IVenueObserver {
public:
Gateway(IVenue &, ILimiter &, IRouter &, IClock &c, GatewayCfg const &);
~Gateway();
// Inputs
void on_om_bootstrap_orders(OM_BootstrapOrders const &);
void on_gw_ops(const GW_Op_Batch &);
void on_account_pnl(const AccountPnLUpdate &);
void on_position(const PositionUpdate &);
void on_excess_liquidity(const ExcessLiquidityUpdate &);
void on_admin_data(const AdminDataUpdate &);
void on_venue_checkpoint(const VenueCheckpointNotice &);
// Signals
Signal<GW_OrderReport> on_order_report;
Signal<GW_UnknownOrderExeReport> on_unknown_native_order_update;
Signal<GW_Error> on_gw_error;
// ISlowWorker
void do_slow_work() override;
private:
enum class State;
class OrderMap;
struct OrderRec;
struct PImpl;
struct Hot;
struct Cold;
std::unique_ptr<PImpl> me;
// IVenueObserver
void on_venue_login_success(std::vector<ExecReport> const&) override;
void on_venue_login_failure() override;
void on_venue_disconnect() override;
void on_venue_exe_report(const ExecReport &) override;
void on_venue_error(VenueError const&) override;
// IGW_Op_visitor
void on_gw_op(OM_ID, const GW_OrderCreate &) override;
void on_gw_op(OM_ID, const GW_OrderBind &) override;
void on_gw_op(OM_ID, const GW_OrderQuickUpdate &) override;
void on_gw_op(OM_ID, const GW_OrderCancel &) override;
void on_gw_op(OM_ID, const GW_OrderFullUpdate &) override;
const char* intern_string (std::string const&);
void send_pending_msgs();
bool has_bootstrap_data() const;
bool in_active_schedule() const;
void transition(State);
void rebuild_msg_templates();
void setup_bootstrap_orders();
GW_OrderReport make_order_report(OrderRec *);
static log::CharPtrWrapper state_name(State);
};
} // namespace orderman_v2
} // namespace bts
@@ -0,0 +1 @@
#include "ICancelMsg.h"
@@ -0,0 +1,19 @@
#pragma once
#include <memory>
#include "lib/orderman_v2/actors/gateway/IVenueMsg.h"
namespace bts {
namespace orderman_v2 {
struct GW_BoundOrder;
class ICancelMsg : public IVenueMsg {
public:
virtual ~ICancelMsg() {}
// These are very performance sensitive calls
virtual ICancelMsg& clone() const = 0;
virtual void update(GW_BoundOrder const&) const = 0;
};
}}
@@ -0,0 +1 @@
#include "ICancelReplaceMsg.h"
@@ -0,0 +1,19 @@
#pragma once
#include <memory>
#include "lib/orderman_v2/actors/gateway/IVenueMsg.h"
namespace bts {
namespace orderman_v2 {
struct GW_BoundOrder;
class ICancelReplaceMsg : public IVenueMsg {
public:
virtual ~ICancelReplaceMsg() {}
// These are very performance sensitive calls
virtual void update(GW_BoundOrder const&) = 0;
virtual ICancelReplaceMsg& clone() const = 0;
};
}}
@@ -0,0 +1 @@
#include "ILimiter.h"
@@ -0,0 +1,42 @@
#pragma once
#include <vector>
#include <string>
#include "lib/orderman_v2/common.h"
namespace bts {
namespace api {namespace admin { class AdminData; }}
namespace orderman_v2 {
struct AccountPnLUpdate;
struct PositionUpdate;
struct ExcessLiquidityUpdate;
struct UserAccountVenue;
class ILimiter {
public:
struct LimiterQueryResult {
GW_OP_Result result;
char const*message;
bool ok() const { return result == GW_OP_Result::OK; }
bool error() const { return !ok(); }
};
virtual LimiterQueryResult can_send_new_order(AccountID account,
api::Security const &sec,
Side side, Quantity quantity);
virtual LimiterQueryResult can_update_order(AccountID account,
api::Security const &sec,
Side side, double delta);
virtual void update(api::admin::AdminData const &admin);
virtual void update(AccountPnLUpdate const &) = 0;
virtual void update(PositionUpdate const &) = 0;
virtual void update(ExcessLiquidityUpdate const &) = 0;
virtual std::vector<UserAccountVenue> get_all_user_account_venue() const = 0;
};
}}
@@ -0,0 +1 @@
#include "INewOrderSingleMsg.h"
@@ -0,0 +1,19 @@
#pragma once
#include <memory>
#include "lib/orderman_v2/actors/gateway/IVenueMsg.h"
namespace bts {
namespace orderman_v2 {
struct GW_BoundOrder;
class INewOrderSingleMsg : public IVenueMsg {
public:
virtual ~INewOrderSingleMsg() {}
// These are very performance sensitive calls
virtual INewOrderSingleMsg & clone() const = 0;
virtual void set_order_params(GW_BoundOrder const&) =0;
};
}}
@@ -0,0 +1 @@
#include "IRouter.h"
@@ -0,0 +1,24 @@
#pragma once
#include <memory>
#include "lib/api/services/OrderService.pb.h"
namespace bts {
namespace api {namespace admin {class AdminData;}}
namespace orderman_v2 {
struct UserAccountVenue;
class IRouter {
public:
virtual void update(api::admin::AdminData const &admin);
struct RouteQueryResult {
bool has_route;
std::string error_msg;
api::orderman::RoutingRecord routing_record;
};
virtual RouteQueryResult get_route(UserAccountVenue const &) = 0;
};
}}
@@ -0,0 +1 @@
#include "IVenue.h"
@@ -0,0 +1,70 @@
#pragma once
#include "lib/utils/datetime.h"
#include <boost/date_time/posix_time/posix_time.hpp>
namespace bts {
namespace api {
class Security;
namespace orderman { class RoutingRecord;}
}
namespace orderman_v2 {
class INewOrderSingleMsg;
class ICancelReplaceMsg;
class ICancelMsg;
class IVenueMsg;
class IVenueObserver;
class ExecReport;
class VenueCheckpoint;
struct MsgTemplates {
INewOrderSingleMsg* new_order;
ICancelReplaceMsg* cancel_replace;
ICancelMsg* cancel;
};
struct SessionSpan {
datetime::PTime start;
datetime::PTime stop;
};
class IVenue {
public:
// call this before any of the below
virtual void set_observer(IVenueObserver &) = 0;
// Return the current (or next) time interval when this venue is
// active
virtual SessionSpan get_current_session_span() = 0;
// Logon to the venue. This can only be called if the caller knows that the
// venue is in the idle state.
virtual void login() = 0;
// Build new order, cancel replace and cancel messages appropriate
// for this venue and using the information in the passed routing
// record
virtual MsgTemplates
get_msg_templates(api::orderman::RoutingRecord const &) = 0;
// Check to to see if the venue is currently able to receive new
// messages without breaching messaging limits
virtual bool under_messaging_limit() = 0;
// Send the passed messages to the venue. It is only legal to call
// this if the venue is idle or ready.
virtual void send(IVenueMsg**begin, IVenueMsg**end) = 0;
// Resolved the security in the execution report. This is only
// needed for disaster recovery. Null should be returned in case of
// failure.
virtual api::Security const * resolve_security (ExecReport const&) = 0;
// Tell the venue what was the last message which had its effects
// commited to disk
virtual void set_checkpoint(VenueCheckpoint const&) = 0;
};
}}
@@ -0,0 +1,2 @@
#include "IVenueMsg.h"
@@ -0,0 +1,13 @@
#pragma once
namespace bts {
namespace orderman_v2 {
class IVenueMsg {
public:
virtual void dispatch() = 0;
virtual ~IVenueMsg() {}
};
}}
@@ -0,0 +1,15 @@
#include "IVenueObserver.h"
namespace bts {
namespace orderman_v2 {
struct SilentVenueObserver : public IVenueObserver {
void on_venue_login_success(std::vector<ExecReport> const &) override { }
void on_venue_login_failure() override { }
void on_venue_disconnect() override { }
void on_venue_exe_report(const ExecReport &) override { }
void on_venue_error(VenueError const &) override { }
};
IVenueObserver& default_venue_observer() {
static SilentVenueObserver svo;
return svo;
}
}}
@@ -0,0 +1,43 @@
#pragma once
#include "lib/orderman_v2/common.h" // OrderKey
namespace bts {
namespace orderman_v2 {
class ExecReport;
struct VenueError {
enum Code { CANCEL_REJECT, BUSINESS_REJECT, SESSION_REJECT, OTHER };
Code error_code;
std::string error_msg;
// null_order_key() if not applicable
OrderKey order_key;
};
class IVenueObserver {
public:
// We logged on successfully and recovered the execution reports
// passed (this should be empty unless fills occurred while we were
// logged out)
virtual void on_venue_login_success(std::vector<ExecReport> const &) = 0;
// We failed to login, either because we could not connect to the
// venue or because our credentials were invalid
virtual void on_venue_login_failure() = 0;
// We were disconnected from the venue
virtual void on_venue_disconnect() = 0;
// An execution report was received from the venue
virtual void on_venue_exe_report(const ExecReport &) = 0;
// A message indicating some sort of error was received from the
// exchange. If the error is order specific a order key will be
// included.
virtual void on_venue_error(VenueError const &) = 0;
};
IVenueObserver& default_venue_observer();
} // namespace orderman_v2
} // namespace bts
@@ -0,0 +1,34 @@
#pragma once
#include <boost/functional/hash.hpp>
#include <fmt/format.h>
#include <string>
namespace bts {
namespace orderman_v2 {
struct UserAccountVenue {
UserID user;
AccountID account;
api::Venue venue;
bool operator==(UserAccountVenue const &rhs) const {
return user == rhs.user && account == rhs.account && venue == rhs.venue;
}
std::string to_str() {
return fmt::format (" user_id: {} account_id: {} venue: {}",
user.value,
account.value,
api::Venue_Name(venue));
}
};
struct UserAccountVenueHash {
std::size_t operator()(UserAccountVenue const &k) const {
size_t result = k.user.value;
boost::hash_combine(result, k.account.value);
boost::hash_combine(result, k.venue);
return result;
}
};
}}
@@ -0,0 +1 @@
#include "lib/orderman_v2/actors/gateway/fix/FIXVenueCtx.h"
@@ -0,0 +1,36 @@
#pragma once
#include "lib/config/protos/jetfix.pb.h"
#include "lib/jetfix/codec/FIXEncodingStream.h"
#include "lib/orderman/governor/Governor.h"
#include "VenueCheckpoint.h"
namespace bts {
namespace orderman_v2 {
class IFIXStore {};
class IClock;
class IConnectionController;
class IVenueObserver;
class FIXVenueCtx {
public:
FIXVenueCtx(config::JetFIX::Connection const &cfg,
VenueCheckpoint const &last_processed_msg, IClock &clock,
IFIXStore &store)
: controller(), venue_observer(), store(store), clock(clock),
out_buffer(cfg, 1), cfg(cfg), last_processed_msg(last_processed_msg) {}
IConnectionController *controller;
IVenueObserver *venue_observer;
IFIXStore &store;
IClock &clock;
jetfix::FIXEncodingStream out_buffer;
orderman::Governor governor;
config::JetFIX::Connection cfg;
VenueCheckpoint last_processed_msg;
}; // namespace orderman_v2
} // namespace orderman_v2
} // namespace bts
@@ -0,0 +1,13 @@
#pragma once
namespace bts {
namespace orderman_v2 {
class VenueCheckpoint {
public:
const char*connection_name;
const char*session_uid;
uint32_t seq_number;
};
}}
@@ -0,0 +1,16 @@
#include "FIXVenueIdle.h"
#include "FIXVenueCtx.h"
namespace bts {
namespace orderman_v2 {
FIXVenueIdle::PImpl (FIXVenueCtx &,FIXVenueWConnect &) {
FIXVenueCtx &ctx;
FIX
};
FIXVenueIdle::FIXVenueIdle() : me (new PImpl()) {}
}}
@@ -0,0 +1,14 @@
// #include "FIXVenueIdle.h"
// #include "FIXVenueCtx.h"
// namespace bts {
// namespace orderman_v2 {
// FIXVenueIdle::PImpl (FIXVenueCtx &,FIXVenueWConnect &) {
// FIXVenueCtx &ctx;
// };
// FIXVenueIdle::FIXVenueIdle() : me (new PImpl()) {}
// }}
@@ -0,0 +1,24 @@
#pragma once
#include "IFIXVenueState.h"
namespace bts {
namespace orderman_v2 {
class WConnect;
class FIXVenueCtx;
class FIXVenueIdle : public IFIXVenueState {
public:
void init(FIXVenueCtx &,WConnect&);
void send(IVenueMsg **, IVenueMsg**) override {};
const char*name() override {return "FIXVenueIdle";}
void enter() override;
void login() override;
private:
struct PImpl;
std::unique_ptr<PImpl> me;
};
}}
@@ -0,0 +1,23 @@
#pragma once
#include <string_view>
#include "lib/utils/bts_assert.h"
namespace bts {
namespace jetfix {class InMsgBuffer;}
namespace orderman_v2 {
class IVenueMsg;
class IFIXVenueState {
public:
virtual void enter() = 0;
virtual void login() {bts_assert(false);}
virtual void send(IVenueMsg **, IVenueMsg**) {bts_assert(false);}
virtual void on_connect_success() {bts_assert(false);}
virtual void on_connect_fail() {bts_assert(false);}
virtual void on_disconnect() {bts_assert(false);}
virtual void on_msg(jetfix::InMsgBuffer const&) {bts_assert(false);}
virtual const char* name() = 0;
};
}}
@@ -0,0 +1,112 @@
#pragma once
namespace bts {
namespace orderman_v2 {
const char* translate_business_reject_reason(int reason) {
switch(reason) {
case 0: return "Other";
case 1: return "Unknown ID (unknown PartyDetailsListReqID being referenced in business message)";
case 2: return "Unknown Security";
case 3: return "Unsupported Message Type (for example using messages specific to cash markets for futures)";
case 5: return "Required Field Missing";
case 6: return "Not Authorized";
case 8: return "Throttle Limit Exceeded (volume controls)";
case 100: return "Value is incorrect (out of range) for this tag (for example using a value outside defined range of integer) ";
case 101: return "Incorrect data format for value (for example using ASCII character outside 32-126 in string field)";
case 102: return "Rejected due to Kill Switch";
case 103: return "Rejected due to Risk Management API";
case 104: return "Rejected due to Globex Credit Controls";
case 105: return "Not Authorized to trade Deliverable Swap Futures";
case 106: return "Not Authorized to trade Interest Rate Swap Futures";
case 107: return "Rejected due to Inline Credit Controls";
case 108: return "Invalid PartyDetailsListReqID (reusing already existing PartyDetailsListReqID while creating Party Details Definition Request)";
case 109: return "Incoming message could not be decoded";
case 110: return "Same repeating group entry appears more than once";
case 111: return "Exceeded maximum number of allowable Party Details Definition Requests";
case 112: return "Technical Error in Registering Party Details";
case 113: return "Rejected due to Cross Venue Risk";
case 114: return "Order Status Not Available";
case 115: return "Enum Not Supported";
case 116: return "Order Status Not Found";
case 117: return "Mass Order Status Cannot be Completed";
case 118: return "Exceeded Maximum Number of Allowable RequestingPartyID's in Party Details List Request";
case 119: return "Duplicate Order Threshold Exceeded";
case 120: return "On-Demand Message Rejected Due to Preceding Party Details Definition Request Being Rejected";
case 121: return "Message Rejected Since PartyDetailsListReqID Does Not Match with Immediately Preceding Party Details Definition Request sent to MSGW when using On-demand administrative information";
case 122: return "Party Details Definition Request sent to MSGW Being Rejected Due to Corresponding Business Message Being Rejected";
case 123: return "Another Message Sent in Between Party Details Definition Request and Business Message when using On-demand administrative information";
case 124: return "Cannot Have More Than One In-Flight Mass Order Status Request in Progress";
case 125: return "Exceeded Maximum Number of In-Flight Order Status Requests";
case 126: return "Cannot Have More Than One In-Flight Party Details List Request in Progress";
case 127: return "Party Details List Request is Missing Requesting Party ID and Party ID";
case 128: return "Party Details List Request cannot contain both RequestingPartyID and PartyID";
case 129: return "Party Details Definition Request Being Rejected Since Another Message was sent in Between On-Demand Message";
case 130: return "Buy Side Firm ID Does Not Match Sell Side Firm ID in New Order Cross";
case 131: return "Message Type Not Supported on Backup Instance";
case 132: return "New Order Cross Does Not Contain Buy Side Followed by Sell Side";
}
return "Unknown or invalid business reject reason.";
}
const char* translate_negotiation_reject(int reason) {
// https://www.cmegroup.com/confluence/display/EPICSANDBOX/Negotiation+Reject
// 01/13/2020
switch(reason) {
case 0: return "HMACNotAuthenticated: failed authentication because identity is not recognized";
case 1: return "HMACNotAvailable: HMAC component is not responding (5sec)";
case 2: return "InvalidUUID: UUID is not greater than the one last used or value sent by the client is out of acceptable range (MIN, MAX)";
case 3: return "InvalidTimestamp: Timestamp is not greater than the one last used or value sent by the client is out of acceptable range (MIN, MAX)";
case 4: return "RequiredHMACSignatureMissing: empty bytes in HMACSignature field";
case 5: return "RequiredAccessKeyIDMissing: empty bytes in AccessKeyID field";
case 6: return "RequiredSessionMissing: empty bytes in Session field";
case 7: return "RequiredFirmMissing: empty bytes in Firm field";
case 8: return "RequiredUUIDMisssing: null value in UUID field";
case 9: return "RequiredRequestTimestampMissing: null value in RequestTimestamp field";
case 10: return "SessionBlocked: session and firm are not authorized for this port";
case 12: return "InvalidAccessKeyID: contains non-printable ASCII character";
case 13: return "InvalidSession: contains non-printable ASCII character";
case 14: return "InvalidFirm: contains non-printable ASCII character";
case 15: return "Volume Controls - exceeding TPS limit as defined for volume controls (reject action)";
case 16: return "SplitMessageRejected - Messages queued due to split message penalty being rejected because of logout or disconnect";
case 17: return "SplitMessageQueue - Reached threshold of messages queued due to split message penalty";
case 27: return "DesignatedBackup - Using Designated backup before designated primary not allowed";
}
return "Unknown or invalid Negotiate reject reason.";
}
const char* translate_establish_reject(int reason) {
switch(reason) {
case 0: return "HMACNotAuthenticated: failed authentication because identity is not recognized";
case 1: return "HMACNotAvailable: HMAC component is not responding (5sec)";
case 2: return "InvalidUUID: UUID is not greater than the one last used or value sent by the client is out of acceptable range (MIN, MAX)";
case 3: return "InvalidTimestamp: Timestamp is not greater than the one last used or value sent by the client is out of acceptable range (MIN, MAX)";
case 4: return "RequiredHMACSignatureMissing: empty bytes in HMACSignature field";
case 5: return "RequiredAccessKeyIDMissing: empty bytes in AccessKeyID field";
case 6: return "RequiredSessionMissing: empty bytes in Session field";
case 7: return "RequiredFirmMissing: empty bytes in Firm field";
case 8: return "RequiredUUIDMisssing: null value in UUID field";
case 9: return "RequiredRequestTimestampMissing: null value in RequestTimestamp field";
case 10: return "SessionBlocked: session and firm are not authorized for this port";
case 11: return "InvalidKeepAliveInterval: value is out of acceptable range (MIN, MAX)";
case 12: return "InvalidAccessKeyID: contains non-printable ASCII character";
case 13: return "InvalidSession: contains non-printable ASCII character";
case 14: return "InvalidFirm: contains non-printable ASCII character";
case 15: return "Volume Controls - exceeding TPS limit as defined for volume controls (reject action)";
case 16: return "SplitMessageRejected - Messages queued due to split message penalty being rejected because of logout or disconnect";
case 17: return "SplitMessageQueue - Reached threshold of messages queued due to split message penalty";
case 18: return "RequiredTradingSystemNameMissing: empty bytes in TradingSystemName";
case 19: return "RequiredTradingSystemVersionMissing: empty bytes in TradingSystemVersion";
case 20: return "RequiredTradingSystemVendorMissing: empty bytes in TradingSystemVendor";
case 21: return "RequiredKeepAliveIntervalMissing: null value in KeepAliveInterval field";
case 22: return "RequiredNextSeqNoMissing: empty bytes in NextSeqNo field";
case 23: return "InvalidTradingSystemName: contains non-prinatable ASCII character";
case 24: return "InvalidTradingSystemVersion: contains non-prinatable ASCII character";
case 25: return "InvalidTradingSystemVendor: contains non-prinatable ASCII character";
case 26: return "DesignatedBackup - Using Designated backup before designated primary not allowed";
case 27: return "DesignatedBackup - Using Designated backup before designated primary not allowed";
}
return "Unknown or invalid Establish reject reason.";
}
}}//namespace
@@ -0,0 +1,294 @@
#include "ILink3Venue.h"
#include "ILink3Utils.h"
#include "lib/utils/bts_assert.h"
#include "lib/logging/logging.h"
#include "lib/utils/datetime.h"
#include "lib/orderman_v2/actors/gateway/IVenueObserver.h"
#include "lib/orderman_v2/actors/network/IConnectionController.h"
#include "lib/utils/SecureLogon.h"
#include "generated/MessageHeader.h"
#include "generated/Negotiate500.h"
#include "generated/NegotiationResponse501.h"
#include "generated/NegotiationReject502.h"
#include "generated/Establish503.h"
#include "generated/NewOrderSingle514.h"
#include "generated/BusinessReject521.h"
// high pri
#include "generated/ExecutionReportNew522.h"
#include "generated/ExecutionReportModify531.h"
#include <cstdint>
#include <variant>
#include <tuple>
#include <fstream>
namespace bts {
namespace orderman_v2 {
typedef unsigned char byte;
struct FramingHeader {
uint16_t message_size;
// always 0xCAFE
uint16_t encoding_type;
};
template <class Msg, size_t Data=0, size_t Sz=4+iLinkBinary::MessageHeader::encodedLength()+Msg::sbeBlockLength()>
std::array<char,Sz+Data> mkbuffer() {
static_assert(sizeof(FramingHeader) == 4);
return std::array<char,Sz+Data> {};
}
template <class Msg, size_t Sz>
Msg frame_message(std::array<char,Sz>& buffer) {
static_assert(Sz >= 4+iLinkBinary::MessageHeader::encodedLength()+Msg::sbeBlockLength());
static_assert(sizeof(FramingHeader) == 4);
FramingHeader* fhead = reinterpret_cast<FramingHeader*>(&buffer[0]);
fhead->message_size = buffer.size();
fhead->encoding_type = 0xCAFE;
Msg msg;
msg.wrapAndApplyHeader((char*)&buffer, sizeof(FramingHeader), buffer.size());
return msg;
}
//------------------------------------------------
//
// States
//
struct Idle {};
struct Connecting {
enum class Step {
EstablishSocket,
Negotiate, // initiates a new session
Establish, // binds to an existing session
Transfer, // negotate sequence number?
};
Step step;
int failover_count;
};
struct Connected {};
struct Disconnected {};
using State = std::variant<Idle,Connecting,Connected,Disconnected>;
//------------------------------------------------
struct ILink3Venue::PImpl {
PImpl():
session(determine_session()),
sequence(0),
sequence_cme(0),
state(Idle{}),
observer(default_venue_observer()),
connection(nullptr)
{ }
uint64_t session;
uint64_t sequence;
uint64_t sequence_cme;
State state;
IVenueObserver& observer;
IConnectionController* connection;
template<class T>
void assert_state() {
bts_assert(std::holds_alternative<T>(state));
}
uint64_t determine_session() {
// this is fairly complex
// see session_name.h
return utils::TimeStamp::now().to_uint64();
}
// CME messages
void do_negotiate() {
// add 2 bytes for empty 'credentials' (39008) length
auto buffer = mkbuffer<iLinkBinary::Negotiate500,2>();
auto msg = frame_message<iLinkBinary::Negotiate500>(buffer);
// msg.customerFlow(); // constant
// msg.hMACVersion(); // constant
msg.uUID(this->session);
msg.requestTimestamp(datetime::unix_nano_now());
msg.putSession("NGG");
// sets the length of the credential block to ushort 00
msg.putCredentials("");
// pad with 0 at the front *and* null at the back
const std::string_view firm = "004";
// this must use the std::string_view overload
// the char* overload does not pad correctly
msg.putFirm(firm);
const auto ld = glbx::calculate_hmac(
msg.getSessionAsString(),
std::to_string(msg.requestTimestamp()),
std::to_string(msg.uUID()),
msg.getSessionAsString(),
firm.data()
);
msg.putAccessKeyID(ld.access_key);
msg.putHMACSignature(ld.signature);
connection->send({ buffer.data(), buffer.size() });
}
void do_establish() {
// add 2 bytes for empty 'credentials' (39008) length
// auto buffer = mkbuffer<iLinkBinary::Establish503,2>();
// auto msg = frame_message<iLinkBinary::Establish503>(buffer);
}
template <class T>
void log(const T& t) {
std::stringstream buf;
buf << t;
LOG(OrderMan, Warn, "{}", buf.str());
}
template <class T, class D> void log(const T& t, int errcode, D decode) {
std::stringstream buf;
buf << t;
LOG(OrderMan, Warn, "Error: {}\n{}", std::string(decode(errcode)), buf.str());
}
void handle_negotiate_response(const iLinkBinary::NegotiationResponse501& msg) {
log(msg);
}
void handle_negotiate_reject(const iLinkBinary::NegotiationReject502& msg) {
log(msg, msg.errorCodes(), translate_negotiation_reject);
}
void handle_business_reject(const iLinkBinary::BusinessReject521& msg) {
log(msg, msg.businessRejectReason(), translate_business_reject_reason);
}
};
//////////////////////////////////////////////////////
// Interface methods
//////////////////////////////////////////////////////
ILink3Venue::ILink3Venue() : me(std::make_unique<PImpl>())
{
}
ILink3Venue::~ILink3Venue() {}
//
// IConnectionHandler
//
void ILink3Venue::init_handler(IConnectionController& c) {
me->connection = &c;
}
void ILink3Venue::on_connect_success() {
auto& state = std::get<Connecting>(me->state);
bts_assert(state.step == Connecting::Step::EstablishSocket);
state.step = Connecting::Step::Negotiate;
me->do_negotiate();
}
void ILink3Venue::on_connect_fail() {
me->assert_state<Connecting>();
me->connection->failover();
auto& state = std::get<Connecting>(me->state);
//todo: config this
if (state.failover_count < 16) {
state.failover_count += 1;
me->connection->connect();
}
else {
LOG(OrderMan,Error, "ilink3 connection exceeded failover count");
me->observer.on_venue_login_failure();
}
}
void ILink3Venue::on_disconnect() {
LOG(OrderMan, Warn, "Disconnected");
me->state = Disconnected {};
}
void ILink3Venue::on_data(const std::string_view& message) {
// decode message and dispatch to handler function
auto fh = reinterpret_cast<const FramingHeader*>(message.data());
bts_assert_d(fh->encoding_type == 0xCAFE);
iLinkBinary::MessageHeader header((char*)message.data()+4, message.size());
constexpr size_t offset = sizeof(FramingHeader) + iLinkBinary::MessageHeader::encodedLength();
char* buffer = (char*)message.data() + offset;
size_t size = message.size() - offset;
// TODO: Docs seem to say there will only be one SBE message per packet so we're
// going with that for now. If we miss a message it should shake out in certification
// TODO: For the sake of performance we should split the switch in 2 high priority messages are served first
switch(header.templateId()) {
case iLinkBinary::NegotiationResponse501::sbeTemplateId():
me->handle_negotiate_response({ buffer, size });
break;
case iLinkBinary::NegotiationReject502::sbeTemplateId():
me->handle_negotiate_reject({ buffer, size });
break;
case iLinkBinary::BusinessReject521::sbeTemplateId():
me->handle_business_reject({buffer,size});
break;
default:
LOG(OrderMan, Warn,
"Unrecognized iLink3 template templateId={} schemaId={} version={}",
header.templateId(),
header.schemaId(),
header.version()
);
}
}
//
// IVenue
//
void ILink3Venue::set_observer(IVenueObserver& o) {
me->observer = o;
}
SessionSpan ILink3Venue::get_current_session_span() {
bts_assert(false);
return SessionSpan{};
}
void ILink3Venue::login() {
if (me->connection == nullptr) {
LOG(OrderMan, Error, "Cannot log in ILink3 session without connection");
me->observer.on_venue_login_failure();
}
me->state = Connecting { Connecting::Step::EstablishSocket, 0 };
me->connection->connect();
}
MsgTemplates ILink3Venue::get_msg_templates(const api::orderman::RoutingRecord&) {
return {};
}
bool ILink3Venue::under_messaging_limit() {
return true;
}
void ILink3Venue::send(IVenueMsg**begin, IVenueMsg**end) {
(void)begin;
(void)end;
}
const api::Security* ILink3Venue::resolve_security (const ExecReport&) {
return nullptr;
}
void ILink3Venue::set_checkpoint(const VenueCheckpoint&) {
}
}} //namespace
@@ -0,0 +1,41 @@
#pragma once
#include "lib/orderman_v2/actors/gateway/IVenue.h"
#include "lib/orderman_v2/actors/network/IConnectionHandler.h"
namespace bts {
namespace orderman_v2 {
class ILink3Venue :
public IVenue,
public IConnectionHandler
{
struct PImpl;
std::unique_ptr<PImpl> me;
public:
ILink3Venue();
~ILink3Venue();
// IConnectionHandler
void init_handler(IConnectionController &) override;
void on_connect_success() override;
void on_connect_fail() override;
void on_disconnect() override;
void on_data(const std::string_view& data) override;
// IVenue
void set_observer(IVenueObserver &) override;
SessionSpan get_current_session_span() override;
void login() override;
MsgTemplates get_msg_templates(const api::orderman::RoutingRecord &) override;
bool under_messaging_limit() override;
void send(IVenueMsg**begin, IVenueMsg**end) override;
const api::Security* resolve_security (const ExecReport&) override;
void set_checkpoint(const VenueCheckpoint&) override;
};
}} //namespace
@@ -0,0 +1,141 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_AVGPXIND_H_
#define _ILINKBINARY_AVGPXIND_H_
#if defined(SBE_HAVE_CMATH)
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
# include <cmath>
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
#else
/* math.h needed for NAN */
# include <math.h>
# define SBE_FLOAT_NAN NAN
# define SBE_DOUBLE_NAN NAN
#endif
#if __cplusplus >= 201103L
# include <cstdint>
# include <string>
# include <cstring>
#endif
#if __cplusplus >= 201103L
# define SBE_CONSTEXPR constexpr
# define SBE_NOEXCEPT noexcept
#else
# define SBE_CONSTEXPR
# define SBE_NOEXCEPT
#endif
#if __cplusplus >= 201703L
# define SBE_NODISCARD [[nodiscard]]
#else
# define SBE_NODISCARD
#endif
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <ostream>
#include <sstream>
#include <iomanip>
#if defined(WIN32) || defined(_WIN32)
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif
#if defined(SBE_NO_BOUNDS_CHECK)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
namespace iLinkBinary {
class AvgPxInd
{
public:
enum Value
{
NoAveragePricing = (std::uint8_t)0,
TradeispartofanAveragePriceGroupIdentifiedbytheAvgPxGrpID = (std::uint8_t)1,
TradeispartofaNotionalValueAveragePriceGroup = (std::uint8_t)3,
NULL_VALUE = (std::uint8_t)255
};
static AvgPxInd::Value get(const std::uint8_t value)
{
switch (value)
{
case 0: return NoAveragePricing;
case 1: return TradeispartofanAveragePriceGroupIdentifiedbytheAvgPxGrpID;
case 3: return TradeispartofaNotionalValueAveragePriceGroup;
case 255: return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum AvgPxInd [E103]");
}
static const char* c_str(const AvgPxInd::Value value)
{
switch (value)
{
case NoAveragePricing: return "NoAveragePricing";
case TradeispartofanAveragePriceGroupIdentifiedbytheAvgPxGrpID: return "TradeispartofanAveragePriceGroupIdentifiedbytheAvgPxGrpID";
case TradeispartofaNotionalValueAveragePriceGroup: return "TradeispartofaNotionalValueAveragePriceGroup";
case NULL_VALUE: return "NULL_VALUE";
}
throw std::runtime_error("unknown value for enum AvgPxInd [E103]:");
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& os, AvgPxInd::Value m)
{
return os << AvgPxInd::c_str(m);
}
};
}
#endif
@@ -0,0 +1,138 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_BOOLEANFLAG_H_
#define _ILINKBINARY_BOOLEANFLAG_H_
#if defined(SBE_HAVE_CMATH)
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
# include <cmath>
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
#else
/* math.h needed for NAN */
# include <math.h>
# define SBE_FLOAT_NAN NAN
# define SBE_DOUBLE_NAN NAN
#endif
#if __cplusplus >= 201103L
# include <cstdint>
# include <string>
# include <cstring>
#endif
#if __cplusplus >= 201103L
# define SBE_CONSTEXPR constexpr
# define SBE_NOEXCEPT noexcept
#else
# define SBE_CONSTEXPR
# define SBE_NOEXCEPT
#endif
#if __cplusplus >= 201703L
# define SBE_NODISCARD [[nodiscard]]
#else
# define SBE_NODISCARD
#endif
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <ostream>
#include <sstream>
#include <iomanip>
#if defined(WIN32) || defined(_WIN32)
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif
#if defined(SBE_NO_BOUNDS_CHECK)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
namespace iLinkBinary {
class BooleanFlag
{
public:
enum Value
{
False = (std::uint8_t)0,
True = (std::uint8_t)1,
NULL_VALUE = (std::uint8_t)255
};
static BooleanFlag::Value get(const std::uint8_t value)
{
switch (value)
{
case 0: return False;
case 1: return True;
case 255: return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum BooleanFlag [E103]");
}
static const char* c_str(const BooleanFlag::Value value)
{
switch (value)
{
case False: return "False";
case True: return "True";
case NULL_VALUE: return "NULL_VALUE";
}
throw std::runtime_error("unknown value for enum BooleanFlag [E103]:");
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& os, BooleanFlag::Value m)
{
return os << BooleanFlag::c_str(m);
}
};
}
#endif
@@ -0,0 +1,138 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_BOOLEANNULL_H_
#define _ILINKBINARY_BOOLEANNULL_H_
#if defined(SBE_HAVE_CMATH)
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
# include <cmath>
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
#else
/* math.h needed for NAN */
# include <math.h>
# define SBE_FLOAT_NAN NAN
# define SBE_DOUBLE_NAN NAN
#endif
#if __cplusplus >= 201103L
# include <cstdint>
# include <string>
# include <cstring>
#endif
#if __cplusplus >= 201103L
# define SBE_CONSTEXPR constexpr
# define SBE_NOEXCEPT noexcept
#else
# define SBE_CONSTEXPR
# define SBE_NOEXCEPT
#endif
#if __cplusplus >= 201703L
# define SBE_NODISCARD [[nodiscard]]
#else
# define SBE_NODISCARD
#endif
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <ostream>
#include <sstream>
#include <iomanip>
#if defined(WIN32) || defined(_WIN32)
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif
#if defined(SBE_NO_BOUNDS_CHECK)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
namespace iLinkBinary {
class BooleanNULL
{
public:
enum Value
{
False = (std::uint8_t)0,
True = (std::uint8_t)1,
NULL_VALUE = (std::uint8_t)255
};
static BooleanNULL::Value get(const std::uint8_t value)
{
switch (value)
{
case 0: return False;
case 1: return True;
case 255: return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum BooleanNULL [E103]");
}
static const char* c_str(const BooleanNULL::Value value)
{
switch (value)
{
case False: return "False";
case True: return "True";
case NULL_VALUE: return "NULL_VALUE";
}
throw std::runtime_error("unknown value for enum BooleanNULL [E103]:");
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& os, BooleanNULL::Value m)
{
return os << BooleanNULL::c_str(m);
}
};
}
#endif
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,138 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_CLEARINGACCTTYPE_H_
#define _ILINKBINARY_CLEARINGACCTTYPE_H_
#if defined(SBE_HAVE_CMATH)
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
# include <cmath>
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
#else
/* math.h needed for NAN */
# include <math.h>
# define SBE_FLOAT_NAN NAN
# define SBE_DOUBLE_NAN NAN
#endif
#if __cplusplus >= 201103L
# include <cstdint>
# include <string>
# include <cstring>
#endif
#if __cplusplus >= 201103L
# define SBE_CONSTEXPR constexpr
# define SBE_NOEXCEPT noexcept
#else
# define SBE_CONSTEXPR
# define SBE_NOEXCEPT
#endif
#if __cplusplus >= 201703L
# define SBE_NODISCARD [[nodiscard]]
#else
# define SBE_NODISCARD
#endif
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <ostream>
#include <sstream>
#include <iomanip>
#if defined(WIN32) || defined(_WIN32)
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif
#if defined(SBE_NO_BOUNDS_CHECK)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
namespace iLinkBinary {
class ClearingAcctType
{
public:
enum Value
{
Customer = (std::uint8_t)0,
Firm = (std::uint8_t)1,
NULL_VALUE = (std::uint8_t)255
};
static ClearingAcctType::Value get(const std::uint8_t value)
{
switch (value)
{
case 0: return Customer;
case 1: return Firm;
case 255: return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum ClearingAcctType [E103]");
}
static const char* c_str(const ClearingAcctType::Value value)
{
switch (value)
{
case Customer: return "Customer";
case Firm: return "Firm";
case NULL_VALUE: return "NULL_VALUE";
}
throw std::runtime_error("unknown value for enum ClearingAcctType [E103]:");
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& os, ClearingAcctType::Value m)
{
return os << ClearingAcctType::c_str(m);
}
};
}
#endif
@@ -0,0 +1,138 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_CMTAGIVEUPCD_H_
#define _ILINKBINARY_CMTAGIVEUPCD_H_
#if defined(SBE_HAVE_CMATH)
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
# include <cmath>
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
#else
/* math.h needed for NAN */
# include <math.h>
# define SBE_FLOAT_NAN NAN
# define SBE_DOUBLE_NAN NAN
#endif
#if __cplusplus >= 201103L
# include <cstdint>
# include <string>
# include <cstring>
#endif
#if __cplusplus >= 201103L
# define SBE_CONSTEXPR constexpr
# define SBE_NOEXCEPT noexcept
#else
# define SBE_CONSTEXPR
# define SBE_NOEXCEPT
#endif
#if __cplusplus >= 201703L
# define SBE_NODISCARD [[nodiscard]]
#else
# define SBE_NODISCARD
#endif
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <ostream>
#include <sstream>
#include <iomanip>
#if defined(WIN32) || defined(_WIN32)
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif
#if defined(SBE_NO_BOUNDS_CHECK)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
namespace iLinkBinary {
class CmtaGiveUpCD
{
public:
enum Value
{
GiveUp = (char)71,
SGXoffset = (char)83,
NULL_VALUE = (char)0
};
static CmtaGiveUpCD::Value get(const char value)
{
switch (value)
{
case 71: return GiveUp;
case 83: return SGXoffset;
case 0: return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum CmtaGiveUpCD [E103]");
}
static const char* c_str(const CmtaGiveUpCD::Value value)
{
switch (value)
{
case GiveUp: return "GiveUp";
case SGXoffset: return "SGXoffset";
case NULL_VALUE: return "NULL_VALUE";
}
throw std::runtime_error("unknown value for enum CmtaGiveUpCD [E103]:");
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& os, CmtaGiveUpCD::Value m)
{
return os << CmtaGiveUpCD::c_str(m);
}
};
}
#endif
@@ -0,0 +1,150 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_CUSTORDHANDLINST_H_
#define _ILINKBINARY_CUSTORDHANDLINST_H_
#if defined(SBE_HAVE_CMATH)
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
# include <cmath>
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
#else
/* math.h needed for NAN */
# include <math.h>
# define SBE_FLOAT_NAN NAN
# define SBE_DOUBLE_NAN NAN
#endif
#if __cplusplus >= 201103L
# include <cstdint>
# include <string>
# include <cstring>
#endif
#if __cplusplus >= 201103L
# define SBE_CONSTEXPR constexpr
# define SBE_NOEXCEPT noexcept
#else
# define SBE_CONSTEXPR
# define SBE_NOEXCEPT
#endif
#if __cplusplus >= 201703L
# define SBE_NODISCARD [[nodiscard]]
#else
# define SBE_NODISCARD
#endif
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <ostream>
#include <sstream>
#include <iomanip>
#if defined(WIN32) || defined(_WIN32)
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif
#if defined(SBE_NO_BOUNDS_CHECK)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
namespace iLinkBinary {
class CustOrdHandlInst
{
public:
enum Value
{
FCMprovidedscreen = (char)67,
Otherprovidedscreen = (char)68,
FCMAPIorFIX = (char)71,
AlgoEngine = (char)72,
DeskElectronic = (char)87,
ClientElectronic = (char)89,
NULL_VALUE = (char)0
};
static CustOrdHandlInst::Value get(const char value)
{
switch (value)
{
case 67: return FCMprovidedscreen;
case 68: return Otherprovidedscreen;
case 71: return FCMAPIorFIX;
case 72: return AlgoEngine;
case 87: return DeskElectronic;
case 89: return ClientElectronic;
case 0: return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum CustOrdHandlInst [E103]");
}
static const char* c_str(const CustOrdHandlInst::Value value)
{
switch (value)
{
case FCMprovidedscreen: return "FCMprovidedscreen";
case Otherprovidedscreen: return "Otherprovidedscreen";
case FCMAPIorFIX: return "FCMAPIorFIX";
case AlgoEngine: return "AlgoEngine";
case DeskElectronic: return "DeskElectronic";
case ClientElectronic: return "ClientElectronic";
case NULL_VALUE: return "NULL_VALUE";
}
throw std::runtime_error("unknown value for enum CustOrdHandlInst [E103]:");
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& os, CustOrdHandlInst::Value m)
{
return os << CustOrdHandlInst::c_str(m);
}
};
}
#endif
@@ -0,0 +1,144 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_CUSTORDERCAPACITY_H_
#define _ILINKBINARY_CUSTORDERCAPACITY_H_
#if defined(SBE_HAVE_CMATH)
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
# include <cmath>
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
#else
/* math.h needed for NAN */
# include <math.h>
# define SBE_FLOAT_NAN NAN
# define SBE_DOUBLE_NAN NAN
#endif
#if __cplusplus >= 201103L
# include <cstdint>
# include <string>
# include <cstring>
#endif
#if __cplusplus >= 201103L
# define SBE_CONSTEXPR constexpr
# define SBE_NOEXCEPT noexcept
#else
# define SBE_CONSTEXPR
# define SBE_NOEXCEPT
#endif
#if __cplusplus >= 201703L
# define SBE_NODISCARD [[nodiscard]]
#else
# define SBE_NODISCARD
#endif
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <ostream>
#include <sstream>
#include <iomanip>
#if defined(WIN32) || defined(_WIN32)
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif
#if defined(SBE_NO_BOUNDS_CHECK)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
namespace iLinkBinary {
class CustOrderCapacity
{
public:
enum Value
{
Membertradingfortheirownaccount = (std::uint8_t)1,
Clearingfirmtradingforitsproprietaryaccount = (std::uint8_t)2,
Membertradingforanothermember = (std::uint8_t)3,
Allother = (std::uint8_t)4,
NULL_VALUE = (std::uint8_t)255
};
static CustOrderCapacity::Value get(const std::uint8_t value)
{
switch (value)
{
case 1: return Membertradingfortheirownaccount;
case 2: return Clearingfirmtradingforitsproprietaryaccount;
case 3: return Membertradingforanothermember;
case 4: return Allother;
case 255: return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum CustOrderCapacity [E103]");
}
static const char* c_str(const CustOrderCapacity::Value value)
{
switch (value)
{
case Membertradingfortheirownaccount: return "Membertradingfortheirownaccount";
case Clearingfirmtradingforitsproprietaryaccount: return "Clearingfirmtradingforitsproprietaryaccount";
case Membertradingforanothermember: return "Membertradingforanothermember";
case Allother: return "Allother";
case NULL_VALUE: return "NULL_VALUE";
}
throw std::runtime_error("unknown value for enum CustOrderCapacity [E103]:");
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& os, CustOrderCapacity::Value m)
{
return os << CustOrderCapacity::c_str(m);
}
};
}
#endif
@@ -0,0 +1,343 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_DATA_H_
#define _ILINKBINARY_DATA_H_
#if defined(SBE_HAVE_CMATH)
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
# include <cmath>
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
#else
/* math.h needed for NAN */
# include <math.h>
# define SBE_FLOAT_NAN NAN
# define SBE_DOUBLE_NAN NAN
#endif
#if __cplusplus >= 201103L
# include <cstdint>
# include <string>
# include <cstring>
#endif
#if __cplusplus >= 201103L
# define SBE_CONSTEXPR constexpr
# define SBE_NOEXCEPT noexcept
#else
# define SBE_CONSTEXPR
# define SBE_NOEXCEPT
#endif
#if __cplusplus >= 201703L
# define SBE_NODISCARD [[nodiscard]]
#else
# define SBE_NODISCARD
#endif
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <ostream>
#include <sstream>
#include <iomanip>
#if defined(WIN32) || defined(_WIN32)
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif
#if defined(SBE_NO_BOUNDS_CHECK)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
namespace iLinkBinary {
class DATA
{
private:
char *m_buffer = nullptr;
std::uint64_t m_bufferLength = 0;
std::uint64_t m_offset = 0;
std::uint64_t m_actingVersion = 0;
public:
enum MetaAttribute
{
EPOCH, TIME_UNIT, SEMANTIC_TYPE, PRESENCE
};
union sbe_float_as_uint_u
{
float fp_value;
std::uint32_t uint_value;
};
union sbe_double_as_uint_u
{
double fp_value;
std::uint64_t uint_value;
};
DATA() = default;
DATA(
char *buffer,
const std::uint64_t offset,
const std::uint64_t bufferLength,
const std::uint64_t actingVersion) :
m_buffer(buffer),
m_bufferLength(bufferLength),
m_offset(offset),
m_actingVersion(actingVersion)
{
if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + -1) > m_bufferLength), false))
{
throw std::runtime_error("buffer too short for flyweight [E107]");
}
}
DATA(
char *buffer,
const std::uint64_t bufferLength,
const std::uint64_t actingVersion) :
DATA(buffer, 0, bufferLength, actingVersion)
{
}
DATA(
char *buffer,
const std::uint64_t bufferLength) :
DATA(buffer, 0, bufferLength, sbeSchemaVersion())
{
}
DATA &wrap(
char *buffer,
const std::uint64_t offset,
const std::uint64_t actingVersion,
const std::uint64_t bufferLength)
{
return *this = DATA(buffer, offset, bufferLength, actingVersion);
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t encodedLength() SBE_NOEXCEPT
{
return -1;
}
SBE_NODISCARD std::uint64_t offset() const SBE_NOEXCEPT
{
return m_offset;
}
SBE_NODISCARD const char * buffer() const SBE_NOEXCEPT
{
return m_buffer;
}
SBE_NODISCARD char * buffer() SBE_NOEXCEPT
{
return m_buffer;
}
SBE_NODISCARD std::uint64_t bufferLength() const SBE_NOEXCEPT
{
return m_bufferLength;
}
SBE_NODISCARD std::uint64_t actingVersion() const SBE_NOEXCEPT
{
return m_actingVersion;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaId() SBE_NOEXCEPT
{
return (std::uint16_t)8;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return (std::uint16_t)2;
}
SBE_NODISCARD static const char * lengthMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::EPOCH: return "";
case MetaAttribute::TIME_UNIT: return "";
case MetaAttribute::SEMANTIC_TYPE: return "";
case MetaAttribute::PRESENCE: return "required";
}
return "";
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t lengthSinceVersion() SBE_NOEXCEPT
{
return 0;
}
SBE_NODISCARD bool lengthInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= lengthSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t lengthEncodingOffset() SBE_NOEXCEPT
{
return 0;
}
static SBE_CONSTEXPR std::uint16_t lengthNullValue() SBE_NOEXCEPT
{
return SBE_NULLVALUE_UINT16;
}
static SBE_CONSTEXPR std::uint16_t lengthMinValue() SBE_NOEXCEPT
{
return (std::uint16_t)0;
}
static SBE_CONSTEXPR std::uint16_t lengthMaxValue() SBE_NOEXCEPT
{
return (std::uint16_t)65534;
}
static SBE_CONSTEXPR std::size_t lengthEncodingLength() SBE_NOEXCEPT
{
return 2;
}
SBE_NODISCARD std::uint16_t length() const SBE_NOEXCEPT
{
std::uint16_t val;
std::memcpy(&val, m_buffer + m_offset + 0, sizeof(std::uint16_t));
return SBE_LITTLE_ENDIAN_ENCODE_16(val);
}
DATA &length(const std::uint16_t value) SBE_NOEXCEPT
{
std::uint16_t val = SBE_LITTLE_ENDIAN_ENCODE_16(value);
std::memcpy(m_buffer + m_offset + 0, &val, sizeof(std::uint16_t));
return *this;
}
SBE_NODISCARD static const char * varDataMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::EPOCH: return "";
case MetaAttribute::TIME_UNIT: return "";
case MetaAttribute::SEMANTIC_TYPE: return "";
case MetaAttribute::PRESENCE: return "required";
}
return "";
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t varDataSinceVersion() SBE_NOEXCEPT
{
return 0;
}
SBE_NODISCARD bool varDataInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= varDataSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t varDataEncodingOffset() SBE_NOEXCEPT
{
return 2;
}
static SBE_CONSTEXPR char varDataNullValue() SBE_NOEXCEPT
{
return (char)0;
}
static SBE_CONSTEXPR char varDataMinValue() SBE_NOEXCEPT
{
return (char)32;
}
static SBE_CONSTEXPR char varDataMaxValue() SBE_NOEXCEPT
{
return (char)126;
}
static SBE_CONSTEXPR std::size_t varDataEncodingLength() SBE_NOEXCEPT
{
return -1;
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& builder, DATA writer)
{
builder << '{';
builder << R"("length": )";
builder << +writer.length();
builder << '}';
return builder;
}
};
}
#endif
@@ -0,0 +1,156 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_DKREASON_H_
#define _ILINKBINARY_DKREASON_H_
#if defined(SBE_HAVE_CMATH)
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
# include <cmath>
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
#else
/* math.h needed for NAN */
# include <math.h>
# define SBE_FLOAT_NAN NAN
# define SBE_DOUBLE_NAN NAN
#endif
#if __cplusplus >= 201103L
# include <cstdint>
# include <string>
# include <cstring>
#endif
#if __cplusplus >= 201103L
# define SBE_CONSTEXPR constexpr
# define SBE_NOEXCEPT noexcept
#else
# define SBE_CONSTEXPR
# define SBE_NOEXCEPT
#endif
#if __cplusplus >= 201703L
# define SBE_NODISCARD [[nodiscard]]
#else
# define SBE_NODISCARD
#endif
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <ostream>
#include <sstream>
#include <iomanip>
#if defined(WIN32) || defined(_WIN32)
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif
#if defined(SBE_NO_BOUNDS_CHECK)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
namespace iLinkBinary {
class DKReason
{
public:
enum Value
{
UnknownSecurity = (char)65,
WrongSide = (char)66,
QuantityExceedsOrder = (char)67,
NoMatchingOrder = (char)68,
PriceExceedsLimit = (char)69,
CalculationDifference = (char)70,
NoMatchingExecutionReport = (char)71,
Other = (char)90,
NULL_VALUE = (char)0
};
static DKReason::Value get(const char value)
{
switch (value)
{
case 65: return UnknownSecurity;
case 66: return WrongSide;
case 67: return QuantityExceedsOrder;
case 68: return NoMatchingOrder;
case 69: return PriceExceedsLimit;
case 70: return CalculationDifference;
case 71: return NoMatchingExecutionReport;
case 90: return Other;
case 0: return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum DKReason [E103]");
}
static const char* c_str(const DKReason::Value value)
{
switch (value)
{
case UnknownSecurity: return "UnknownSecurity";
case WrongSide: return "WrongSide";
case QuantityExceedsOrder: return "QuantityExceedsOrder";
case NoMatchingOrder: return "NoMatchingOrder";
case PriceExceedsLimit: return "PriceExceedsLimit";
case CalculationDifference: return "CalculationDifference";
case NoMatchingExecutionReport: return "NoMatchingExecutionReport";
case Other: return "Other";
case NULL_VALUE: return "NULL_VALUE";
}
throw std::runtime_error("unknown value for enum DKReason [E103]:");
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& os, DKReason::Value m)
{
return os << DKReason::c_str(m);
}
};
}
#endif
@@ -0,0 +1,361 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_DECIMAL32NULL_H_
#define _ILINKBINARY_DECIMAL32NULL_H_
#if defined(SBE_HAVE_CMATH)
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
# include <cmath>
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
#else
/* math.h needed for NAN */
# include <math.h>
# define SBE_FLOAT_NAN NAN
# define SBE_DOUBLE_NAN NAN
#endif
#if __cplusplus >= 201103L
# include <cstdint>
# include <string>
# include <cstring>
#endif
#if __cplusplus >= 201103L
# define SBE_CONSTEXPR constexpr
# define SBE_NOEXCEPT noexcept
#else
# define SBE_CONSTEXPR
# define SBE_NOEXCEPT
#endif
#if __cplusplus >= 201703L
# define SBE_NODISCARD [[nodiscard]]
#else
# define SBE_NODISCARD
#endif
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <ostream>
#include <sstream>
#include <iomanip>
#if defined(WIN32) || defined(_WIN32)
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif
#if defined(SBE_NO_BOUNDS_CHECK)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
namespace iLinkBinary {
class Decimal32NULL
{
private:
char *m_buffer = nullptr;
std::uint64_t m_bufferLength = 0;
std::uint64_t m_offset = 0;
std::uint64_t m_actingVersion = 0;
public:
enum MetaAttribute
{
EPOCH, TIME_UNIT, SEMANTIC_TYPE, PRESENCE
};
union sbe_float_as_uint_u
{
float fp_value;
std::uint32_t uint_value;
};
union sbe_double_as_uint_u
{
double fp_value;
std::uint64_t uint_value;
};
Decimal32NULL() = default;
Decimal32NULL(
char *buffer,
const std::uint64_t offset,
const std::uint64_t bufferLength,
const std::uint64_t actingVersion) :
m_buffer(buffer),
m_bufferLength(bufferLength),
m_offset(offset),
m_actingVersion(actingVersion)
{
if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + 5) > m_bufferLength), false))
{
throw std::runtime_error("buffer too short for flyweight [E107]");
}
}
Decimal32NULL(
char *buffer,
const std::uint64_t bufferLength,
const std::uint64_t actingVersion) :
Decimal32NULL(buffer, 0, bufferLength, actingVersion)
{
}
Decimal32NULL(
char *buffer,
const std::uint64_t bufferLength) :
Decimal32NULL(buffer, 0, bufferLength, sbeSchemaVersion())
{
}
Decimal32NULL &wrap(
char *buffer,
const std::uint64_t offset,
const std::uint64_t actingVersion,
const std::uint64_t bufferLength)
{
return *this = Decimal32NULL(buffer, offset, bufferLength, actingVersion);
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t encodedLength() SBE_NOEXCEPT
{
return 5;
}
SBE_NODISCARD std::uint64_t offset() const SBE_NOEXCEPT
{
return m_offset;
}
SBE_NODISCARD const char * buffer() const SBE_NOEXCEPT
{
return m_buffer;
}
SBE_NODISCARD char * buffer() SBE_NOEXCEPT
{
return m_buffer;
}
SBE_NODISCARD std::uint64_t bufferLength() const SBE_NOEXCEPT
{
return m_bufferLength;
}
SBE_NODISCARD std::uint64_t actingVersion() const SBE_NOEXCEPT
{
return m_actingVersion;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaId() SBE_NOEXCEPT
{
return (std::uint16_t)8;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return (std::uint16_t)2;
}
SBE_NODISCARD static const char * mantissaMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::EPOCH: return "";
case MetaAttribute::TIME_UNIT: return "";
case MetaAttribute::SEMANTIC_TYPE: return "";
case MetaAttribute::PRESENCE: return "optional";
}
return "";
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t mantissaSinceVersion() SBE_NOEXCEPT
{
return 0;
}
SBE_NODISCARD bool mantissaInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= mantissaSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t mantissaEncodingOffset() SBE_NOEXCEPT
{
return 0;
}
static SBE_CONSTEXPR std::int32_t mantissaNullValue() SBE_NOEXCEPT
{
return 2147483647;
}
static SBE_CONSTEXPR std::int32_t mantissaMinValue() SBE_NOEXCEPT
{
return -2147483647;
}
static SBE_CONSTEXPR std::int32_t mantissaMaxValue() SBE_NOEXCEPT
{
return 2147483647;
}
static SBE_CONSTEXPR std::size_t mantissaEncodingLength() SBE_NOEXCEPT
{
return 4;
}
SBE_NODISCARD std::int32_t mantissa() const SBE_NOEXCEPT
{
std::int32_t val;
std::memcpy(&val, m_buffer + m_offset + 0, sizeof(std::int32_t));
return SBE_LITTLE_ENDIAN_ENCODE_32(val);
}
Decimal32NULL &mantissa(const std::int32_t value) SBE_NOEXCEPT
{
std::int32_t val = SBE_LITTLE_ENDIAN_ENCODE_32(value);
std::memcpy(m_buffer + m_offset + 0, &val, sizeof(std::int32_t));
return *this;
}
SBE_NODISCARD static const char * exponentMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::EPOCH: return "";
case MetaAttribute::TIME_UNIT: return "";
case MetaAttribute::SEMANTIC_TYPE: return "";
case MetaAttribute::PRESENCE: return "optional";
}
return "";
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t exponentSinceVersion() SBE_NOEXCEPT
{
return 0;
}
SBE_NODISCARD bool exponentInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= exponentSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t exponentEncodingOffset() SBE_NOEXCEPT
{
return 4;
}
static SBE_CONSTEXPR std::int8_t exponentNullValue() SBE_NOEXCEPT
{
return (std::int8_t)127;
}
static SBE_CONSTEXPR std::int8_t exponentMinValue() SBE_NOEXCEPT
{
return (std::int8_t)-127;
}
static SBE_CONSTEXPR std::int8_t exponentMaxValue() SBE_NOEXCEPT
{
return (std::int8_t)127;
}
static SBE_CONSTEXPR std::size_t exponentEncodingLength() SBE_NOEXCEPT
{
return 1;
}
SBE_NODISCARD std::int8_t exponent() const SBE_NOEXCEPT
{
std::int8_t val;
std::memcpy(&val, m_buffer + m_offset + 4, sizeof(std::int8_t));
return (val);
}
Decimal32NULL &exponent(const std::int8_t value) SBE_NOEXCEPT
{
std::int8_t val = (value);
std::memcpy(m_buffer + m_offset + 4, &val, sizeof(std::int8_t));
return *this;
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& builder, Decimal32NULL writer)
{
builder << '{';
builder << R"("mantissa": )";
builder << +writer.mantissa();
builder << ", ";
builder << R"("exponent": )";
builder << +writer.exponent();
builder << '}';
return builder;
}
};
}
#endif
@@ -0,0 +1,361 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_DECIMAL64NULL_H_
#define _ILINKBINARY_DECIMAL64NULL_H_
#if defined(SBE_HAVE_CMATH)
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
# include <cmath>
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
#else
/* math.h needed for NAN */
# include <math.h>
# define SBE_FLOAT_NAN NAN
# define SBE_DOUBLE_NAN NAN
#endif
#if __cplusplus >= 201103L
# include <cstdint>
# include <string>
# include <cstring>
#endif
#if __cplusplus >= 201103L
# define SBE_CONSTEXPR constexpr
# define SBE_NOEXCEPT noexcept
#else
# define SBE_CONSTEXPR
# define SBE_NOEXCEPT
#endif
#if __cplusplus >= 201703L
# define SBE_NODISCARD [[nodiscard]]
#else
# define SBE_NODISCARD
#endif
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <ostream>
#include <sstream>
#include <iomanip>
#if defined(WIN32) || defined(_WIN32)
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif
#if defined(SBE_NO_BOUNDS_CHECK)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
namespace iLinkBinary {
class Decimal64NULL
{
private:
char *m_buffer = nullptr;
std::uint64_t m_bufferLength = 0;
std::uint64_t m_offset = 0;
std::uint64_t m_actingVersion = 0;
public:
enum MetaAttribute
{
EPOCH, TIME_UNIT, SEMANTIC_TYPE, PRESENCE
};
union sbe_float_as_uint_u
{
float fp_value;
std::uint32_t uint_value;
};
union sbe_double_as_uint_u
{
double fp_value;
std::uint64_t uint_value;
};
Decimal64NULL() = default;
Decimal64NULL(
char *buffer,
const std::uint64_t offset,
const std::uint64_t bufferLength,
const std::uint64_t actingVersion) :
m_buffer(buffer),
m_bufferLength(bufferLength),
m_offset(offset),
m_actingVersion(actingVersion)
{
if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + 9) > m_bufferLength), false))
{
throw std::runtime_error("buffer too short for flyweight [E107]");
}
}
Decimal64NULL(
char *buffer,
const std::uint64_t bufferLength,
const std::uint64_t actingVersion) :
Decimal64NULL(buffer, 0, bufferLength, actingVersion)
{
}
Decimal64NULL(
char *buffer,
const std::uint64_t bufferLength) :
Decimal64NULL(buffer, 0, bufferLength, sbeSchemaVersion())
{
}
Decimal64NULL &wrap(
char *buffer,
const std::uint64_t offset,
const std::uint64_t actingVersion,
const std::uint64_t bufferLength)
{
return *this = Decimal64NULL(buffer, offset, bufferLength, actingVersion);
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t encodedLength() SBE_NOEXCEPT
{
return 9;
}
SBE_NODISCARD std::uint64_t offset() const SBE_NOEXCEPT
{
return m_offset;
}
SBE_NODISCARD const char * buffer() const SBE_NOEXCEPT
{
return m_buffer;
}
SBE_NODISCARD char * buffer() SBE_NOEXCEPT
{
return m_buffer;
}
SBE_NODISCARD std::uint64_t bufferLength() const SBE_NOEXCEPT
{
return m_bufferLength;
}
SBE_NODISCARD std::uint64_t actingVersion() const SBE_NOEXCEPT
{
return m_actingVersion;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaId() SBE_NOEXCEPT
{
return (std::uint16_t)8;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return (std::uint16_t)2;
}
SBE_NODISCARD static const char * mantissaMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::EPOCH: return "";
case MetaAttribute::TIME_UNIT: return "";
case MetaAttribute::SEMANTIC_TYPE: return "";
case MetaAttribute::PRESENCE: return "optional";
}
return "";
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t mantissaSinceVersion() SBE_NOEXCEPT
{
return 0;
}
SBE_NODISCARD bool mantissaInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= mantissaSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t mantissaEncodingOffset() SBE_NOEXCEPT
{
return 0;
}
static SBE_CONSTEXPR std::int64_t mantissaNullValue() SBE_NOEXCEPT
{
return 9223372036854775807L;
}
static SBE_CONSTEXPR std::int64_t mantissaMinValue() SBE_NOEXCEPT
{
return -9223372036854775807L;
}
static SBE_CONSTEXPR std::int64_t mantissaMaxValue() SBE_NOEXCEPT
{
return 9223372036854775807L;
}
static SBE_CONSTEXPR std::size_t mantissaEncodingLength() SBE_NOEXCEPT
{
return 8;
}
SBE_NODISCARD std::int64_t mantissa() const SBE_NOEXCEPT
{
std::int64_t val;
std::memcpy(&val, m_buffer + m_offset + 0, sizeof(std::int64_t));
return SBE_LITTLE_ENDIAN_ENCODE_64(val);
}
Decimal64NULL &mantissa(const std::int64_t value) SBE_NOEXCEPT
{
std::int64_t val = SBE_LITTLE_ENDIAN_ENCODE_64(value);
std::memcpy(m_buffer + m_offset + 0, &val, sizeof(std::int64_t));
return *this;
}
SBE_NODISCARD static const char * exponentMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::EPOCH: return "";
case MetaAttribute::TIME_UNIT: return "";
case MetaAttribute::SEMANTIC_TYPE: return "";
case MetaAttribute::PRESENCE: return "optional";
}
return "";
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t exponentSinceVersion() SBE_NOEXCEPT
{
return 0;
}
SBE_NODISCARD bool exponentInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= exponentSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t exponentEncodingOffset() SBE_NOEXCEPT
{
return 8;
}
static SBE_CONSTEXPR std::int8_t exponentNullValue() SBE_NOEXCEPT
{
return (std::int8_t)127;
}
static SBE_CONSTEXPR std::int8_t exponentMinValue() SBE_NOEXCEPT
{
return (std::int8_t)-127;
}
static SBE_CONSTEXPR std::int8_t exponentMaxValue() SBE_NOEXCEPT
{
return (std::int8_t)127;
}
static SBE_CONSTEXPR std::size_t exponentEncodingLength() SBE_NOEXCEPT
{
return 1;
}
SBE_NODISCARD std::int8_t exponent() const SBE_NOEXCEPT
{
std::int8_t val;
std::memcpy(&val, m_buffer + m_offset + 8, sizeof(std::int8_t));
return (val);
}
Decimal64NULL &exponent(const std::int8_t value) SBE_NOEXCEPT
{
std::int8_t val = (value);
std::memcpy(m_buffer + m_offset + 8, &val, sizeof(std::int8_t));
return *this;
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& builder, Decimal64NULL writer)
{
builder << '{';
builder << R"("mantissa": )";
builder << +writer.mantissa();
builder << ", ";
builder << R"("exponent": )";
builder << +writer.exponent();
builder << '}';
return builder;
}
};
}
#endif
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,992 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_ESTABLISHMENTREJECT505_H_
#define _ILINKBINARY_ESTABLISHMENTREJECT505_H_
#if defined(SBE_HAVE_CMATH)
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
# include <cmath>
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
#else
/* math.h needed for NAN */
# include <math.h>
# define SBE_FLOAT_NAN NAN
# define SBE_DOUBLE_NAN NAN
#endif
#if __cplusplus >= 201103L
# include <cstdint>
# include <string>
# include <cstring>
#endif
#if __cplusplus >= 201103L
# define SBE_CONSTEXPR constexpr
# define SBE_NOEXCEPT noexcept
#else
# define SBE_CONSTEXPR
# define SBE_NOEXCEPT
#endif
#if __cplusplus >= 201703L
# define SBE_NODISCARD [[nodiscard]]
#else
# define SBE_NODISCARD
#endif
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <ostream>
#include <sstream>
#include <iomanip>
#if defined(WIN32) || defined(_WIN32)
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif
#if defined(SBE_NO_BOUNDS_CHECK)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
#include "MaturityMonthYear.h"
#include "Decimal64NULL.h"
#include "OrderTypeReq.h"
#include "BooleanNULL.h"
#include "AvgPxInd.h"
#include "OrderEventType.h"
#include "CmtaGiveUpCD.h"
#include "PRICENULL9.h"
#include "BooleanFlag.h"
#include "OrderType.h"
#include "QuoteCxlStatus.h"
#include "TimeInForce.h"
#include "PRICE9.h"
#include "MassStatusOrdTyp.h"
#include "ExecInst.h"
#include "Decimal32NULL.h"
#include "SplitMsg.h"
#include "SideReq.h"
#include "MassActionResponse.h"
#include "CustOrderCapacity.h"
#include "SideTimeInForce.h"
#include "SLEDS.h"
#include "ReqResult.h"
#include "ClearingAcctType.h"
#include "KeepAliveLapsed.h"
#include "ExecAckStatus.h"
#include "DATA.h"
#include "OFMOverrideReq.h"
#include "SideNULL.h"
#include "GroupSize.h"
#include "ListUpdAct.h"
#include "FTI.h"
#include "ExecReason.h"
#include "MassStatusReqTyp.h"
#include "DKReason.h"
#include "SecRspTyp.h"
#include "MassActionOrdTyp.h"
#include "QuoteAckStatus.h"
#include "ExpCycle.h"
#include "MassCancelTIF.h"
#include "OrderStatus.h"
#include "ShortSaleType.h"
#include "PartyDetailRole.h"
#include "MassActionScope.h"
#include "RFQSide.h"
#include "OrdStatusTrdCxl.h"
#include "TradeAddendum.h"
#include "MessageHeader.h"
#include "ManualOrdInd.h"
#include "QuoteCxlTyp.h"
#include "MassCxlReqTyp.h"
#include "ExecTypTrdCxl.h"
#include "ManualOrdIndReq.h"
#include "CustOrdHandlInst.h"
#include "OrdStatusTrd.h"
#include "MassStatusTIF.h"
#include "SMPI.h"
#include "ExecMode.h"
#include "QuoteTyp.h"
namespace iLinkBinary {
class EstablishmentReject505
{
private:
char *m_buffer = nullptr;
std::uint64_t m_bufferLength = 0;
std::uint64_t m_offset = 0;
std::uint64_t m_position = 0;
std::uint64_t m_actingVersion = 0;
inline std::uint64_t *sbePositionPtr() SBE_NOEXCEPT
{
return &m_position;
}
public:
enum MetaAttribute
{
EPOCH, TIME_UNIT, SEMANTIC_TYPE, PRESENCE
};
union sbe_float_as_uint_u
{
float fp_value;
std::uint32_t uint_value;
};
union sbe_double_as_uint_u
{
double fp_value;
std::uint64_t uint_value;
};
EstablishmentReject505() = default;
EstablishmentReject505(
char *buffer,
const std::uint64_t offset,
const std::uint64_t bufferLength,
const std::uint64_t actingBlockLength,
const std::uint64_t actingVersion) :
m_buffer(buffer),
m_bufferLength(bufferLength),
m_offset(offset),
m_position(sbeCheckPosition(offset + actingBlockLength)),
m_actingVersion(actingVersion)
{
}
EstablishmentReject505(char *buffer, const std::uint64_t bufferLength) :
EstablishmentReject505(buffer, 0, bufferLength, sbeBlockLength(), sbeSchemaVersion())
{
}
EstablishmentReject505(
char *buffer,
const std::uint64_t bufferLength,
const std::uint64_t actingBlockLength,
const std::uint64_t actingVersion) :
EstablishmentReject505(buffer, 0, bufferLength, actingBlockLength, actingVersion)
{
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeBlockLength() SBE_NOEXCEPT
{
return (std::uint16_t)72;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeTemplateId() SBE_NOEXCEPT
{
return (std::uint16_t)505;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaId() SBE_NOEXCEPT
{
return (std::uint16_t)8;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return (std::uint16_t)2;
}
SBE_NODISCARD static SBE_CONSTEXPR const char * sbeSemanticType() SBE_NOEXCEPT
{
return "EstablishmentReject";
}
SBE_NODISCARD std::uint64_t offset() const SBE_NOEXCEPT
{
return m_offset;
}
EstablishmentReject505 &wrapForEncode(char *buffer, const std::uint64_t offset, const std::uint64_t bufferLength)
{
return *this = EstablishmentReject505(buffer, offset, bufferLength, sbeBlockLength(), sbeSchemaVersion());
}
EstablishmentReject505 &wrapAndApplyHeader(char *buffer, const std::uint64_t offset, const std::uint64_t bufferLength)
{
MessageHeader hdr(buffer, offset, bufferLength, sbeSchemaVersion());
hdr
.blockLength(sbeBlockLength())
.templateId(sbeTemplateId())
.schemaId(sbeSchemaId())
.version(sbeSchemaVersion());
return *this = EstablishmentReject505(
buffer,
offset + MessageHeader::encodedLength(),
bufferLength,
sbeBlockLength(),
sbeSchemaVersion());
}
EstablishmentReject505 &wrapForDecode(
char *buffer,
const std::uint64_t offset,
const std::uint64_t actingBlockLength,
const std::uint64_t actingVersion,
const std::uint64_t bufferLength)
{
return *this = EstablishmentReject505(buffer, offset, bufferLength, actingBlockLength, actingVersion);
}
SBE_NODISCARD std::uint64_t sbePosition() const SBE_NOEXCEPT
{
return m_position;
}
std::uint64_t sbeCheckPosition(const std::uint64_t position)
{
if (SBE_BOUNDS_CHECK_EXPECT((position > m_bufferLength), false))
{
throw std::runtime_error("buffer too short [E100]");
}
return position;
}
void sbePosition(const std::uint64_t position)
{
m_position = sbeCheckPosition(position);
}
SBE_NODISCARD std::uint64_t encodedLength() const SBE_NOEXCEPT
{
return sbePosition() - m_offset;
}
SBE_NODISCARD const char * buffer() const SBE_NOEXCEPT
{
return m_buffer;
}
SBE_NODISCARD char * buffer() SBE_NOEXCEPT
{
return m_buffer;
}
SBE_NODISCARD std::uint64_t bufferLength() const SBE_NOEXCEPT
{
return m_bufferLength;
}
SBE_NODISCARD std::uint64_t actingVersion() const SBE_NOEXCEPT
{
return m_actingVersion;
}
SBE_NODISCARD static const char * ReasonMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::EPOCH: return "";
case MetaAttribute::TIME_UNIT: return "";
case MetaAttribute::SEMANTIC_TYPE: return "String";
case MetaAttribute::PRESENCE: return "optional";
}
return "";
}
static SBE_CONSTEXPR std::uint16_t reasonId() SBE_NOEXCEPT
{
return 39011;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t reasonSinceVersion() SBE_NOEXCEPT
{
return 0;
}
SBE_NODISCARD bool reasonInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= reasonSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t reasonEncodingOffset() SBE_NOEXCEPT
{
return 0;
}
static SBE_CONSTEXPR char reasonNullValue() SBE_NOEXCEPT
{
return (char)0;
}
static SBE_CONSTEXPR char reasonMinValue() SBE_NOEXCEPT
{
return (char)32;
}
static SBE_CONSTEXPR char reasonMaxValue() SBE_NOEXCEPT
{
return (char)126;
}
static SBE_CONSTEXPR std::size_t reasonEncodingLength() SBE_NOEXCEPT
{
return 48;
}
static SBE_CONSTEXPR std::uint64_t reasonLength() SBE_NOEXCEPT
{
return 48;
}
SBE_NODISCARD const char *reason() const SBE_NOEXCEPT
{
return m_buffer + m_offset + 0;
}
SBE_NODISCARD char *reason() SBE_NOEXCEPT
{
return m_buffer + m_offset + 0;
}
SBE_NODISCARD char reason(const std::uint64_t index) const
{
if (index >= 48)
{
throw std::runtime_error("index out of range for reason [E104]");
}
char val;
std::memcpy(&val, m_buffer + m_offset + 0 + (index * 1), sizeof(char));
return (val);
}
EstablishmentReject505 &reason(const std::uint64_t index, const char value)
{
if (index >= 48)
{
throw std::runtime_error("index out of range for reason [E105]");
}
char val = (value);
std::memcpy(m_buffer + m_offset + 0 + (index * 1), &val, sizeof(char));
return *this;
}
std::uint64_t getReason(char *const dst, const std::uint64_t length) const
{
if (length > 48)
{
throw std::runtime_error("length too large for getReason [E106]");
}
std::memcpy(dst, m_buffer + m_offset + 0, sizeof(char) * static_cast<size_t>(length));
return length;
}
EstablishmentReject505 &putReason(const char *const src) SBE_NOEXCEPT
{
std::memcpy(m_buffer + m_offset + 0, src, sizeof(char) * 48);
return *this;
}
std::string getReasonAsString() const
{
const char *buffer = m_buffer + m_offset + 0;
size_t length = 0;
for (; length < 48 && *(buffer + length) != '\0'; ++length);
std::string result(buffer, length);
return result;
}
std::string getReasonAsJsonEscapedString()
{
std::ostringstream oss;
std::string s = getReasonAsString();
for (auto c = s.cbegin(); c != s.cend(); c++)
{
switch (*c)
{
case '"': oss << "\\\""; break;
case '\\': oss << "\\\\"; break;
case '\b': oss << "\\b"; break;
case '\f': oss << "\\f"; break;
case '\n': oss << "\\n"; break;
case '\r': oss << "\\r"; break;
case '\t': oss << "\\t"; break;
default:
if ('\x00' <= *c && *c <= '\x1f')
{
oss << "\\u" << std::hex << std::setw(4)
<< std::setfill('0') << (int)(*c);
}
else
{
oss << *c;
}
}
}
return oss.str();
}
#if __cplusplus >= 201703L
std::string_view getReasonAsStringView() const SBE_NOEXCEPT
{
const char *buffer = m_buffer + m_offset + 0;
size_t length = 0;
for (; length < 48 && *(buffer + length) != '\0'; ++length);
std::string_view result(buffer, length);
return result;
}
#endif
#if __cplusplus >= 201703L
EstablishmentReject505 &putReason(const std::string_view str)
{
const size_t srcLength = str.length();
if (srcLength > 48)
{
throw std::runtime_error("string too large for putReason [E106]");
}
std::memcpy(m_buffer + m_offset + 0, str.data(), srcLength);
for (size_t start = srcLength; start < 48; ++start)
{
m_buffer[m_offset + 0 + start] = 0;
}
return *this;
}
#else
EstablishmentReject505 &putReason(const std::string& str)
{
const size_t srcLength = str.length();
if (srcLength > 48)
{
throw std::runtime_error("string too large for putReason [E106]");
}
std::memcpy(m_buffer + m_offset + 0, str.c_str(), srcLength);
for (size_t start = srcLength; start < 48; ++start)
{
m_buffer[m_offset + 0 + start] = 0;
}
return *this;
}
#endif
SBE_NODISCARD static const char * UUIDMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::EPOCH: return "";
case MetaAttribute::TIME_UNIT: return "";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
}
return "";
}
static SBE_CONSTEXPR std::uint16_t uUIDId() SBE_NOEXCEPT
{
return 39001;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t uUIDSinceVersion() SBE_NOEXCEPT
{
return 0;
}
SBE_NODISCARD bool uUIDInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= uUIDSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t uUIDEncodingOffset() SBE_NOEXCEPT
{
return 48;
}
static SBE_CONSTEXPR std::uint64_t uUIDNullValue() SBE_NOEXCEPT
{
return SBE_NULLVALUE_UINT64;
}
static SBE_CONSTEXPR std::uint64_t uUIDMinValue() SBE_NOEXCEPT
{
return 0x0L;
}
static SBE_CONSTEXPR std::uint64_t uUIDMaxValue() SBE_NOEXCEPT
{
return 0xfffffffffffffffeL;
}
static SBE_CONSTEXPR std::size_t uUIDEncodingLength() SBE_NOEXCEPT
{
return 8;
}
SBE_NODISCARD std::uint64_t uUID() const SBE_NOEXCEPT
{
std::uint64_t val;
std::memcpy(&val, m_buffer + m_offset + 48, sizeof(std::uint64_t));
return SBE_LITTLE_ENDIAN_ENCODE_64(val);
}
EstablishmentReject505 &uUID(const std::uint64_t value) SBE_NOEXCEPT
{
std::uint64_t val = SBE_LITTLE_ENDIAN_ENCODE_64(value);
std::memcpy(m_buffer + m_offset + 48, &val, sizeof(std::uint64_t));
return *this;
}
SBE_NODISCARD static const char * RequestTimestampMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::EPOCH: return "";
case MetaAttribute::TIME_UNIT: return "";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
}
return "";
}
static SBE_CONSTEXPR std::uint16_t requestTimestampId() SBE_NOEXCEPT
{
return 39002;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t requestTimestampSinceVersion() SBE_NOEXCEPT
{
return 0;
}
SBE_NODISCARD bool requestTimestampInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= requestTimestampSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t requestTimestampEncodingOffset() SBE_NOEXCEPT
{
return 56;
}
static SBE_CONSTEXPR std::uint64_t requestTimestampNullValue() SBE_NOEXCEPT
{
return SBE_NULLVALUE_UINT64;
}
static SBE_CONSTEXPR std::uint64_t requestTimestampMinValue() SBE_NOEXCEPT
{
return 0x0L;
}
static SBE_CONSTEXPR std::uint64_t requestTimestampMaxValue() SBE_NOEXCEPT
{
return 0xfffffffffffffffeL;
}
static SBE_CONSTEXPR std::size_t requestTimestampEncodingLength() SBE_NOEXCEPT
{
return 8;
}
SBE_NODISCARD std::uint64_t requestTimestamp() const SBE_NOEXCEPT
{
std::uint64_t val;
std::memcpy(&val, m_buffer + m_offset + 56, sizeof(std::uint64_t));
return SBE_LITTLE_ENDIAN_ENCODE_64(val);
}
EstablishmentReject505 &requestTimestamp(const std::uint64_t value) SBE_NOEXCEPT
{
std::uint64_t val = SBE_LITTLE_ENDIAN_ENCODE_64(value);
std::memcpy(m_buffer + m_offset + 56, &val, sizeof(std::uint64_t));
return *this;
}
SBE_NODISCARD static const char * NextSeqNoMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::EPOCH: return "";
case MetaAttribute::TIME_UNIT: return "";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
}
return "";
}
static SBE_CONSTEXPR std::uint16_t nextSeqNoId() SBE_NOEXCEPT
{
return 39013;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t nextSeqNoSinceVersion() SBE_NOEXCEPT
{
return 0;
}
SBE_NODISCARD bool nextSeqNoInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= nextSeqNoSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t nextSeqNoEncodingOffset() SBE_NOEXCEPT
{
return 64;
}
static SBE_CONSTEXPR std::uint32_t nextSeqNoNullValue() SBE_NOEXCEPT
{
return SBE_NULLVALUE_UINT32;
}
static SBE_CONSTEXPR std::uint32_t nextSeqNoMinValue() SBE_NOEXCEPT
{
return 0;
}
static SBE_CONSTEXPR std::uint32_t nextSeqNoMaxValue() SBE_NOEXCEPT
{
return 4294967294;
}
static SBE_CONSTEXPR std::size_t nextSeqNoEncodingLength() SBE_NOEXCEPT
{
return 4;
}
SBE_NODISCARD std::uint32_t nextSeqNo() const SBE_NOEXCEPT
{
std::uint32_t val;
std::memcpy(&val, m_buffer + m_offset + 64, sizeof(std::uint32_t));
return SBE_LITTLE_ENDIAN_ENCODE_32(val);
}
EstablishmentReject505 &nextSeqNo(const std::uint32_t value) SBE_NOEXCEPT
{
std::uint32_t val = SBE_LITTLE_ENDIAN_ENCODE_32(value);
std::memcpy(m_buffer + m_offset + 64, &val, sizeof(std::uint32_t));
return *this;
}
SBE_NODISCARD static const char * ErrorCodesMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::EPOCH: return "";
case MetaAttribute::TIME_UNIT: return "";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
}
return "";
}
static SBE_CONSTEXPR std::uint16_t errorCodesId() SBE_NOEXCEPT
{
return 39012;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t errorCodesSinceVersion() SBE_NOEXCEPT
{
return 0;
}
SBE_NODISCARD bool errorCodesInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= errorCodesSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t errorCodesEncodingOffset() SBE_NOEXCEPT
{
return 68;
}
static SBE_CONSTEXPR std::uint16_t errorCodesNullValue() SBE_NOEXCEPT
{
return SBE_NULLVALUE_UINT16;
}
static SBE_CONSTEXPR std::uint16_t errorCodesMinValue() SBE_NOEXCEPT
{
return (std::uint16_t)0;
}
static SBE_CONSTEXPR std::uint16_t errorCodesMaxValue() SBE_NOEXCEPT
{
return (std::uint16_t)65534;
}
static SBE_CONSTEXPR std::size_t errorCodesEncodingLength() SBE_NOEXCEPT
{
return 2;
}
SBE_NODISCARD std::uint16_t errorCodes() const SBE_NOEXCEPT
{
std::uint16_t val;
std::memcpy(&val, m_buffer + m_offset + 68, sizeof(std::uint16_t));
return SBE_LITTLE_ENDIAN_ENCODE_16(val);
}
EstablishmentReject505 &errorCodes(const std::uint16_t value) SBE_NOEXCEPT
{
std::uint16_t val = SBE_LITTLE_ENDIAN_ENCODE_16(value);
std::memcpy(m_buffer + m_offset + 68, &val, sizeof(std::uint16_t));
return *this;
}
SBE_NODISCARD static const char * FaultToleranceIndicatorMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::EPOCH: return "";
case MetaAttribute::TIME_UNIT: return "";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
}
return "";
}
static SBE_CONSTEXPR std::uint16_t faultToleranceIndicatorId() SBE_NOEXCEPT
{
return 39010;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t faultToleranceIndicatorSinceVersion() SBE_NOEXCEPT
{
return 0;
}
SBE_NODISCARD bool faultToleranceIndicatorInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= faultToleranceIndicatorSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t faultToleranceIndicatorEncodingOffset() SBE_NOEXCEPT
{
return 70;
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t faultToleranceIndicatorEncodingLength() SBE_NOEXCEPT
{
return 1;
}
SBE_NODISCARD FTI::Value faultToleranceIndicator() const SBE_NOEXCEPT
{
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset + 70, sizeof(std::uint8_t));
return FTI::get((val));
}
EstablishmentReject505 &faultToleranceIndicator(const FTI::Value value) SBE_NOEXCEPT
{
std::uint8_t val = (value);
std::memcpy(m_buffer + m_offset + 70, &val, sizeof(std::uint8_t));
return *this;
}
SBE_NODISCARD static const char * SplitMsgMetaAttribute(const MetaAttribute metaAttribute) SBE_NOEXCEPT
{
switch (metaAttribute)
{
case MetaAttribute::EPOCH: return "";
case MetaAttribute::TIME_UNIT: return "";
case MetaAttribute::SEMANTIC_TYPE: return "int";
case MetaAttribute::PRESENCE: return "required";
}
return "";
}
static SBE_CONSTEXPR std::uint16_t splitMsgId() SBE_NOEXCEPT
{
return 9553;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t splitMsgSinceVersion() SBE_NOEXCEPT
{
return 0;
}
SBE_NODISCARD bool splitMsgInActingVersion() SBE_NOEXCEPT
{
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
#endif
return m_actingVersion >= splitMsgSinceVersion();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t splitMsgEncodingOffset() SBE_NOEXCEPT
{
return 71;
}
SBE_NODISCARD static SBE_CONSTEXPR std::size_t splitMsgEncodingLength() SBE_NOEXCEPT
{
return 1;
}
SBE_NODISCARD SplitMsg::Value splitMsg() const SBE_NOEXCEPT
{
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset + 71, sizeof(std::uint8_t));
return SplitMsg::get((val));
}
EstablishmentReject505 &splitMsg(const SplitMsg::Value value) SBE_NOEXCEPT
{
std::uint8_t val = (value);
std::memcpy(m_buffer + m_offset + 71, &val, sizeof(std::uint8_t));
return *this;
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& builder, EstablishmentReject505 _writer)
{
EstablishmentReject505 writer(_writer.m_buffer, _writer.m_offset,
_writer.m_bufferLength, _writer.sbeBlockLength(), _writer.m_actingVersion);
builder << '{';
builder << R"("Name": "EstablishmentReject505", )";
builder << R"("sbeTemplateId": )";
builder << writer.sbeTemplateId();
builder << ", ";
builder << R"("Reason": )";
builder << '"' <<
writer.getReasonAsJsonEscapedString().c_str() << '"';
builder << ", ";
builder << R"("UUID": )";
builder << +writer.uUID();
builder << ", ";
builder << R"("RequestTimestamp": )";
builder << +writer.requestTimestamp();
builder << ", ";
builder << R"("NextSeqNo": )";
builder << +writer.nextSeqNo();
builder << ", ";
builder << R"("ErrorCodes": )";
builder << +writer.errorCodes();
builder << ", ";
builder << R"("FaultToleranceIndicator": )";
builder << '"' << writer.faultToleranceIndicator() << '"';
builder << ", ";
builder << R"("SplitMsg": )";
builder << '"' << writer.splitMsg() << '"';
builder << '}';
return builder;
}
};
}
#endif
@@ -0,0 +1,138 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_EXECACKSTATUS_H_
#define _ILINKBINARY_EXECACKSTATUS_H_
#if defined(SBE_HAVE_CMATH)
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
# include <cmath>
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
#else
/* math.h needed for NAN */
# include <math.h>
# define SBE_FLOAT_NAN NAN
# define SBE_DOUBLE_NAN NAN
#endif
#if __cplusplus >= 201103L
# include <cstdint>
# include <string>
# include <cstring>
#endif
#if __cplusplus >= 201103L
# define SBE_CONSTEXPR constexpr
# define SBE_NOEXCEPT noexcept
#else
# define SBE_CONSTEXPR
# define SBE_NOEXCEPT
#endif
#if __cplusplus >= 201703L
# define SBE_NODISCARD [[nodiscard]]
#else
# define SBE_NODISCARD
#endif
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <ostream>
#include <sstream>
#include <iomanip>
#if defined(WIN32) || defined(_WIN32)
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif
#if defined(SBE_NO_BOUNDS_CHECK)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
namespace iLinkBinary {
class ExecAckStatus
{
public:
enum Value
{
Accepted = (std::uint8_t)1,
Rejected = (std::uint8_t)2,
NULL_VALUE = (std::uint8_t)255
};
static ExecAckStatus::Value get(const std::uint8_t value)
{
switch (value)
{
case 1: return Accepted;
case 2: return Rejected;
case 255: return NULL_VALUE;
}
throw std::runtime_error("unknown value for enum ExecAckStatus [E103]");
}
static const char* c_str(const ExecAckStatus::Value value)
{
switch (value)
{
case Accepted: return "Accepted";
case Rejected: return "Rejected";
case NULL_VALUE: return "NULL_VALUE";
}
throw std::runtime_error("unknown value for enum ExecAckStatus [E103]:");
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& os, ExecAckStatus::Value m)
{
return os << ExecAckStatus::c_str(m);
}
};
}
#endif
@@ -0,0 +1,515 @@
/* Generated SBE (Simple Binary Encoding) message codec */
#ifndef _ILINKBINARY_EXECINST_H_
#define _ILINKBINARY_EXECINST_H_
#if defined(SBE_HAVE_CMATH)
/* cmath needed for std::numeric_limits<double>::quiet_NaN() */
# include <cmath>
# define SBE_FLOAT_NAN std::numeric_limits<float>::quiet_NaN()
# define SBE_DOUBLE_NAN std::numeric_limits<double>::quiet_NaN()
#else
/* math.h needed for NAN */
# include <math.h>
# define SBE_FLOAT_NAN NAN
# define SBE_DOUBLE_NAN NAN
#endif
#if __cplusplus >= 201103L
# include <cstdint>
# include <string>
# include <cstring>
#endif
#if __cplusplus >= 201103L
# define SBE_CONSTEXPR constexpr
# define SBE_NOEXCEPT noexcept
#else
# define SBE_CONSTEXPR
# define SBE_NOEXCEPT
#endif
#if __cplusplus >= 201703L
# define SBE_NODISCARD [[nodiscard]]
#else
# define SBE_NODISCARD
#endif
#if !defined(__STDC_LIMIT_MACROS)
# define __STDC_LIMIT_MACROS 1
#endif
#include <cstdint>
#include <cstring>
#include <limits>
#include <stdexcept>
#include <ostream>
#include <sstream>
#include <iomanip>
#if defined(WIN32) || defined(_WIN32)
# define SBE_BIG_ENDIAN_ENCODE_16(v) _byteswap_ushort(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) _byteswap_ulong(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) _byteswap_uint64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define SBE_BIG_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) (v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) (v)
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define SBE_LITTLE_ENDIAN_ENCODE_16(v) __builtin_bswap16(v)
# define SBE_LITTLE_ENDIAN_ENCODE_32(v) __builtin_bswap32(v)
# define SBE_LITTLE_ENDIAN_ENCODE_64(v) __builtin_bswap64(v)
# define SBE_BIG_ENDIAN_ENCODE_16(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_32(v) (v)
# define SBE_BIG_ENDIAN_ENCODE_64(v) (v)
#else
# error "Byte Ordering of platform not determined. Set __BYTE_ORDER__ manually before including this file."
#endif
#if defined(SBE_NO_BOUNDS_CHECK)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (false)
#elif defined(_MSC_VER)
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (exp)
#else
# define SBE_BOUNDS_CHECK_EXPECT(exp,c) (__builtin_expect(exp,c))
#endif
#define SBE_NULLVALUE_INT8 (std::numeric_limits<std::int8_t>::min)()
#define SBE_NULLVALUE_INT16 (std::numeric_limits<std::int16_t>::min)()
#define SBE_NULLVALUE_INT32 (std::numeric_limits<std::int32_t>::min)()
#define SBE_NULLVALUE_INT64 (std::numeric_limits<std::int64_t>::min)()
#define SBE_NULLVALUE_UINT8 (std::numeric_limits<std::uint8_t>::max)()
#define SBE_NULLVALUE_UINT16 (std::numeric_limits<std::uint16_t>::max)()
#define SBE_NULLVALUE_UINT32 (std::numeric_limits<std::uint32_t>::max)()
#define SBE_NULLVALUE_UINT64 (std::numeric_limits<std::uint64_t>::max)()
namespace iLinkBinary {
class ExecInst
{
private:
char *m_buffer = nullptr;
std::uint64_t m_bufferLength = 0;
std::uint64_t m_offset = 0;
std::uint64_t m_actingVersion = 0;
public:
enum MetaAttribute
{
EPOCH, TIME_UNIT, SEMANTIC_TYPE, PRESENCE
};
union sbe_float_as_uint_u
{
float fp_value;
std::uint32_t uint_value;
};
union sbe_double_as_uint_u
{
double fp_value;
std::uint64_t uint_value;
};
ExecInst() = default;
ExecInst(
char *buffer,
const std::uint64_t offset,
const std::uint64_t bufferLength,
const std::uint64_t actingVersion) :
m_buffer(buffer),
m_bufferLength(bufferLength),
m_offset(offset),
m_actingVersion(actingVersion)
{
if (SBE_BOUNDS_CHECK_EXPECT(((m_offset + 1) > m_bufferLength), false))
{
throw std::runtime_error("buffer too short for flyweight [E107]");
}
}
ExecInst(
char *buffer,
const std::uint64_t bufferLength,
const std::uint64_t actingVersion) :
ExecInst(buffer, 0, bufferLength, actingVersion)
{
}
ExecInst(
char *buffer,
const std::uint64_t bufferLength) :
ExecInst(buffer, 0, bufferLength, sbeSchemaVersion())
{
}
ExecInst &wrap(
char *buffer,
const std::uint64_t offset,
const std::uint64_t actingVersion,
const std::uint64_t bufferLength)
{
return *this = ExecInst(buffer, offset, bufferLength, actingVersion);
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint64_t encodedLength() SBE_NOEXCEPT
{
return 1;
}
SBE_NODISCARD std::uint64_t offset() const SBE_NOEXCEPT
{
return m_offset;
}
SBE_NODISCARD const char * buffer() const SBE_NOEXCEPT
{
return m_buffer;
}
SBE_NODISCARD char * buffer() SBE_NOEXCEPT
{
return m_buffer;
}
SBE_NODISCARD std::uint64_t bufferLength() const SBE_NOEXCEPT
{
return m_bufferLength;
}
SBE_NODISCARD std::uint64_t actingVersion() const SBE_NOEXCEPT
{
return m_actingVersion;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaId() SBE_NOEXCEPT
{
return (std::uint16_t)8;
}
SBE_NODISCARD static SBE_CONSTEXPR std::uint16_t sbeSchemaVersion() SBE_NOEXCEPT
{
return (std::uint16_t)2;
}
ExecInst &clear()
{
std::uint8_t zero = 0;
std::memcpy(m_buffer + m_offset, &zero, sizeof(std::uint8_t));
return *this;
}
SBE_NODISCARD bool isEmpty() const
{
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
return 0 == val;
}
SBE_NODISCARD std::uint8_t rawValue() const
{
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
return val;
}
ExecInst &rawValue(std::uint8_t value)
{
std::memcpy(m_buffer + m_offset, &value, sizeof(std::uint8_t));
return *this;
}
static bool aON(const std::uint8_t bits)
{
return (bits & (1u << 0u)) != 0;
}
static std::uint8_t aON(const std::uint8_t bits, const bool value)
{
return value ? static_cast<std::uint8_t>(bits | (1u << 0u)) : static_cast<std::uint8_t>(bits & ~(1u << 0u));
}
SBE_NODISCARD bool aON() const
{
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
return ((val) & (1u << 0u)) != 0;
}
ExecInst &aON(const bool value)
{
std::uint8_t bits;
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 0u)) : static_cast<std::uint8_t>((bits) & ~(1u << 0u)));
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
return *this;
}
static bool oB(const std::uint8_t bits)
{
return (bits & (1u << 1u)) != 0;
}
static std::uint8_t oB(const std::uint8_t bits, const bool value)
{
return value ? static_cast<std::uint8_t>(bits | (1u << 1u)) : static_cast<std::uint8_t>(bits & ~(1u << 1u));
}
SBE_NODISCARD bool oB() const
{
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
return ((val) & (1u << 1u)) != 0;
}
ExecInst &oB(const bool value)
{
std::uint8_t bits;
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 1u)) : static_cast<std::uint8_t>((bits) & ~(1u << 1u)));
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
return *this;
}
static bool nH(const std::uint8_t bits)
{
return (bits & (1u << 2u)) != 0;
}
static std::uint8_t nH(const std::uint8_t bits, const bool value)
{
return value ? static_cast<std::uint8_t>(bits | (1u << 2u)) : static_cast<std::uint8_t>(bits & ~(1u << 2u));
}
SBE_NODISCARD bool nH() const
{
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
return ((val) & (1u << 2u)) != 0;
}
ExecInst &nH(const bool value)
{
std::uint8_t bits;
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 2u)) : static_cast<std::uint8_t>((bits) & ~(1u << 2u)));
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
return *this;
}
static bool reserved1(const std::uint8_t bits)
{
return (bits & (1u << 3u)) != 0;
}
static std::uint8_t reserved1(const std::uint8_t bits, const bool value)
{
return value ? static_cast<std::uint8_t>(bits | (1u << 3u)) : static_cast<std::uint8_t>(bits & ~(1u << 3u));
}
SBE_NODISCARD bool reserved1() const
{
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
return ((val) & (1u << 3u)) != 0;
}
ExecInst &reserved1(const bool value)
{
std::uint8_t bits;
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 3u)) : static_cast<std::uint8_t>((bits) & ~(1u << 3u)));
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
return *this;
}
static bool reserved2(const std::uint8_t bits)
{
return (bits & (1u << 4u)) != 0;
}
static std::uint8_t reserved2(const std::uint8_t bits, const bool value)
{
return value ? static_cast<std::uint8_t>(bits | (1u << 4u)) : static_cast<std::uint8_t>(bits & ~(1u << 4u));
}
SBE_NODISCARD bool reserved2() const
{
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
return ((val) & (1u << 4u)) != 0;
}
ExecInst &reserved2(const bool value)
{
std::uint8_t bits;
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 4u)) : static_cast<std::uint8_t>((bits) & ~(1u << 4u)));
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
return *this;
}
static bool reserved3(const std::uint8_t bits)
{
return (bits & (1u << 5u)) != 0;
}
static std::uint8_t reserved3(const std::uint8_t bits, const bool value)
{
return value ? static_cast<std::uint8_t>(bits | (1u << 5u)) : static_cast<std::uint8_t>(bits & ~(1u << 5u));
}
SBE_NODISCARD bool reserved3() const
{
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
return ((val) & (1u << 5u)) != 0;
}
ExecInst &reserved3(const bool value)
{
std::uint8_t bits;
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 5u)) : static_cast<std::uint8_t>((bits) & ~(1u << 5u)));
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
return *this;
}
static bool reserved4(const std::uint8_t bits)
{
return (bits & (1u << 6u)) != 0;
}
static std::uint8_t reserved4(const std::uint8_t bits, const bool value)
{
return value ? static_cast<std::uint8_t>(bits | (1u << 6u)) : static_cast<std::uint8_t>(bits & ~(1u << 6u));
}
SBE_NODISCARD bool reserved4() const
{
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
return ((val) & (1u << 6u)) != 0;
}
ExecInst &reserved4(const bool value)
{
std::uint8_t bits;
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 6u)) : static_cast<std::uint8_t>((bits) & ~(1u << 6u)));
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
return *this;
}
static bool reserved5(const std::uint8_t bits)
{
return (bits & (1u << 7u)) != 0;
}
static std::uint8_t reserved5(const std::uint8_t bits, const bool value)
{
return value ? static_cast<std::uint8_t>(bits | (1u << 7u)) : static_cast<std::uint8_t>(bits & ~(1u << 7u));
}
SBE_NODISCARD bool reserved5() const
{
std::uint8_t val;
std::memcpy(&val, m_buffer + m_offset, sizeof(std::uint8_t));
return ((val) & (1u << 7u)) != 0;
}
ExecInst &reserved5(const bool value)
{
std::uint8_t bits;
std::memcpy(&bits, m_buffer + m_offset, sizeof(std::uint8_t));
bits = (value ? static_cast<std::uint8_t>((bits) | (1u << 7u)) : static_cast<std::uint8_t>((bits) & ~(1u << 7u)));
std::memcpy(m_buffer + m_offset, &bits, sizeof(std::uint8_t));
return *this;
}
template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& builder, ExecInst writer)
{
builder << '[';
bool atLeastOne = false;
if (writer.aON())
{
builder << R"("aON")";
atLeastOne = true;
}
if (writer.oB())
{
if (atLeastOne)
{
builder << ",";
}
builder << R"("oB")";
atLeastOne = true;
}
if (writer.nH())
{
if (atLeastOne)
{
builder << ",";
}
builder << R"("nH")";
atLeastOne = true;
}
if (writer.reserved1())
{
if (atLeastOne)
{
builder << ",";
}
builder << R"("reserved1")";
atLeastOne = true;
}
if (writer.reserved2())
{
if (atLeastOne)
{
builder << ",";
}
builder << R"("reserved2")";
atLeastOne = true;
}
if (writer.reserved3())
{
if (atLeastOne)
{
builder << ",";
}
builder << R"("reserved3")";
atLeastOne = true;
}
if (writer.reserved4())
{
if (atLeastOne)
{
builder << ",";
}
builder << R"("reserved4")";
atLeastOne = true;
}
if (writer.reserved5())
{
if (atLeastOne)
{
builder << ",";
}
builder << R"("reserved5")";
}
builder << ']';
return builder;
}
};
}
#endif
Loaded 100 of 250 files, more files were not shown because too many files have changed in this diff. Show more