OnixS C++ ICE Binary Order Entry Handler 1.1.1
API Documentation
Loading...
Searching...
No Matches
Options.h
Go to the documentation of this file.
1// Copyright Onix Solutions Limited [OnixS]. All rights reserved.
2//
3// This software owned by Onix Solutions Limited [OnixS] and is
4// protected by copyright law and international copyright treaties.
5//
6// Access to and use of the software is governed by the terms of the applicable
7// OnixS Software Services Agreement (the Agreement) and Customer end user license
8// agreements granting a non-assignable, non-transferable and non-exclusive license
9// to use the software for it's own data processing purposes under the terms defined
10// in the Agreement.
11//
12// Except as otherwise granted within the terms of the Agreement, copying or
13// reproduction of any part of this source code or associated reference material
14// to any other location for further reproduction or redistribution, and any
15// amendments to this copyright notice, are expressly prohibited.
16//
17// Any reproduction or redistribution for sale or hiring of the Software not in
18// accordance with the terms of the Agreement is a violation of copyright law.
19//
20
21#pragma once
22
24
25#include <map>
26#include <iostream>
27#include <sstream>
28
30
31namespace Samples {
32
33typedef std::string Option;
34typedef std::string OptionArg;
35typedef std::vector<OptionArg> OptionArgs;
36
37// Implements a carriage over command line arguments.
39{
40public:
41 ArgCarriage(size_t qty, char** args) noexcept
42 : qty_(qty)
43 , args_(args)
44 {
45 }
46
47 // Checks whether the carriage is in a valid state.
48 operator bool() const
49 {
50 return (0 < qty_);
51 }
52
53 // If valid, provides access to the argument
54 // which the carriage currently points to.
55 const char* operator*() const
56 {
57 assert(0 < qty_);
58
59 return *args_;
60 }
61
62 // Advances the carriage to the next argument.
63 void advance()
64 {
65 --qty_;
66 ++args_;
67 }
68
69private:
70 size_t qty_;
71 char** args_;
72};
73
74[[noreturn]] inline void throwBadOption(const Char* arg)
75{
76 assert(arg);
77
78 std::string issue;
79
80 issue += "The given argument [";
81 issue += arg;
82 issue += "] does not represent an option which must begin with the '--' prefix. ";
83
84 throw std::runtime_error(issue);
85}
86
87[[noreturn]] inline void throwDuplicatedOption(const Char* option)
88{
89 std::string issue;
90
91 issue += "The given option [";
92 issue += option;
93 issue += "] is defined twice in the argument list. ";
94
95 throw std::runtime_error(issue);
96}
97
98// Groups the command line arguments by options.
100{
101public:
102 // Processes application input arguments and builds the option-to-values map.
103 Options(size_t qty, char** args)
104 {
105 assert(0 < qty);
106 assert(args);
107
108 ArgCarriage carriage(qty, args);
109
110 // Cuts application name.
111 carriage.advance();
112
113 // If there are arguments except the application name.
114 if (carriage)
115 {
116 std::string option;
117
118 if (isOption(*carriage, &option))
119 {
120 do
121 {
122 carriage.advance();
123
124 const std::pair<Items::iterator, bool> inserted =
125 items_.insert(std::make_pair(option, OptionArgs()));
126
127 if (inserted.second)
128 {
129 OptionArgs& optionArgs = inserted.first->second;
130
131 while (carriage && !isOption(*carriage, &option))
132 {
133 optionArgs.push_back(*carriage);
134
135 carriage.advance();
136 }
137 }
138 else
139 {
140 throwDuplicatedOption(option.c_str());
141 }
142 }
143 while (carriage);
144 }
145 else
146 {
147 throwBadOption(*carriage);
148 }
149 }
150 }
151
152 // Transforms available options into the given destination.
153 template <class Iterator>
154 void get(Iterator target) const
155 {
156 std::transform(items_.begin(), items_.end(), target, PairFirst<Option, OptionArgs>());
157 }
158
159 // Exposes arguments for the given option. Returns null if option is not present.
160 const OptionArgs* args(const char* option) const
161 {
162 return args(option ? std::string(option) : std::string());
163 }
164
165 // Exposes arguments for the given option. Returns null if option is not present.
166 const OptionArgs* args(const std::string& option) const
167 {
168 const auto foundItem = items_.find(option);
169 return (foundItem != items_.end() ? &foundItem->second : nullptr);
170 }
171
172private:
173 template <typename First, typename Second>
174 struct PairFirst
175 {
176 typedef std::pair<First, Second> Pair;
177
178 inline First operator()(const Pair& item) const
179 {
180 return item.first;
181 }
182 };
183
184 typedef std::map<Option, OptionArgs> Items;
185 Items items_;
186
187 // Checks whether the given argument represents an option. Extracts the option (cuts prefix) upon request.
188 static bool isOption(const char* arg, std::string* option = nullptr)
189 {
190 assert(arg);
191
192 const size_t argLength = strlen(arg);
193
194 static const StrRef prefix = toStrRef("--");
195
196 if (argLength > prefix.size() && prefix == StrRef(arg, prefix.size()) && prefix[0] != arg[prefix.size()])
197 {
198 if (option)
199 option->assign(arg + prefix.size(), argLength - prefix.size());
200
201 return true;
202 }
203
204 return false;
205 }
206};
207
208// Enhances options manipulation services with data conversion facilities.
209[[noreturn]] inline void throwOptionArgConversionFailed(const Char* option)
210{
211 assert(nullptr != option);
212
213 std::string issue;
214
215 issue += "Value for the option [";
216 issue += option;
217 issue += "] is not recognized. Run application help for information on valid values for the option. ";
218
219 throw std::runtime_error(issue);
220}
221
222
223template <typename T>
224bool fromStr(T& result, const std::string& s)
225{
226 return Messaging::fromStr(result, s.data(), s.size());
227}
228
229inline
230bool fromStr(SessionStorageType::Enum& result, const std::string& s)
231{
232 try
233 {
234 result = SessionStorageType::parse(s);
235 return true;
236 }
237 catch(...)
238 {
239 return false;
240 }
241}
242
243template <typename Value>
245{
246public:
247 OptionArgConverter(const Char* option = nullptr)
248 : option_(option)
249 {
250 }
251
252 Value operator()(const std::string& str) const
253 {
254 Value value = Value();
255
256 if (!fromStr(value, str))
258
259 return value;
260 }
261
262private:
263 const Char* option_;
264};
265
266template <>
267class OptionArgConverter<std::string>
268{
269public:
270 OptionArgConverter(const Char* = nullptr) {}
271
272 std::string operator()(const std::string& str) const
273 {
274 return str;
275 }
276};
277
278template <>
280{
281public:
282 OptionArgConverter(const Char* = nullptr) {}
283
284 const Char* operator()(const std::string& str) const
285 {
286 return str.c_str();
287 }
288};
289
290template <typename Value>
291inline void convertOptionArg(Value& value, const Char* option, const std::string& str)
292{
293 const OptionArgConverter<Value> converter(option);
294
295 value = converter(str);
296}
297
298inline void throwBadOptionArgQty(const Char* option, size_t argQty, size_t minQty, size_t maxQty)
299{
300 assert(nullptr != option);
301
302 std::string issue;
303
304 issue += "Number of arguments for the option [";
305
306 issue += option;
307
308 issue += "] does not meet the requirements. "
309 "It must be not less than ";
310
311 toStr(issue, minQty);
312
313 if (maxQty != static_cast<size_t>(-1))
314 {
315 issue += " and not greater than ";
316
317 toStr(issue, maxQty);
318 }
319
320 issue += ". Meanwhile, the actual number is ";
321
322 toStr(issue, argQty);
323
324 issue += ". ";
325
326 throw std::runtime_error(issue);
327}
328
329[[noreturn]] inline void throwReqiredOptionArgMissing(const Char* option)
330{
331 assert(nullptr != option);
332
333 std::string issue;
334
335 issue += "The required option [";
336
337 issue += option;
338
339 issue += "] or its argument is missing. ";
340
341 throw std::runtime_error(issue);
342}
343
344template <typename Value, typename Iterator>
345inline bool args(
346 const Options& options,
347 const Char* option,
348 Iterator target,
349 size_t minQty = 0,
350 size_t maxQty = static_cast<size_t>(-1)
351)
352{
353 if (const OptionArgs* args = options.args(option))
354 {
355 const size_t argQty = args->size();
356
357 if (minQty <= argQty && maxQty >= argQty)
358 {
359 const OptionArgConverter<Value> converter(option);
360
361 std::transform(args->begin(), args->end(), target, converter);
362
363 return true;
364 }
365 else
366 {
367 throwBadOptionArgQty(option, argQty, minQty, maxQty);
368 }
369 }
370
371 return false;
372}
373
374template <typename Value>
375inline Value argOrDefault(const Options& options, const Char* option, const Value& defaultValue = Value())
376{
377 Value value = defaultValue;
378
379 args<Value>(options, option, &value, 1, 1);
380
381 return value;
382}
383
384template <typename Value, size_t Length>
385inline const Value* argOrDefault(const Options& options, const Char* option, Value (&defaultValue)[Length])
386{
387 return argOrDefault<const Value*>(options, option, static_cast<const Value*>(defaultValue));
388}
389
390template <typename Value>
391inline Value requiredArg(const Options& options, const Char* option)
392{
393 const OptionArgs* args = options.args(option);
394
395 if (nullptr == args || 1 != args->size())
396 {
398 }
399
400 const OptionArgConverter<Value> converter(option);
401
402 return converter((*args)[0]);
403}
404
405
407{
408public:
409 bool show() const
410 {
411 return exist(options(), "help");
412 }
413
414 void show(std::ostream& out) const
415 {
416 out << "Options affecting the application behavior: " << std::endl;
417 showOptions(out);
418 out << " --help" << std::endl << "\tDisplays this message. " << std::endl;
419 }
420
421 virtual ~ConfigurationBase() = default;
422
423protected:
424 ConfigurationBase(size_t qty, char** args) noexcept
425 : opts_(qty, args)
426 {
427 }
428
429 const Options& options() const noexcept
430 {
431 return opts_;
432 }
433
434 virtual void showOptions(std::ostream&) const = 0;
435
436 static bool exist(const Options& options, const Char* option)
437 {
438 assert(nullptr != option);
439
440 return (nullptr != options.args(option));
441 }
442
443private:
444 Options opts_;
445};
446
447
449{
450public:
451 std::string host() const
452 {
453 return argOrDefault(options(), "host", "127.0.0.1");
454 }
455
456 Port port() const
457 {
458 return argOrDefault(options(), "port", 10000);
459 }
460
461 bool useEmulator() const
462 {
463 return argOrDefault<std::string>(options(), "host", {}).empty();
464 }
465
466 bool useTLS() const
467 {
468 return !useEmulator() && port() == Default::TlsPort;
469 }
470
471protected:
472 ConnectivityConfiguration(size_t qty, char** args)
473 : ConfigurationBase(qty, args)
474 {
475 }
476
477 void showOptions(std::ostream& out) const override
478 {
479 out
480 << " --host [host]" << std::endl
481 << "\tIf not specified, an emulator is used." << std::endl
482 << " --port [port]" << std::endl;
483 }
484};
485
487{
488public:
489 std::string settingsFile() const
490 {
491 return argOrDefault(options(), "settings", "");
492 }
493
494protected:
495 SettingsConfiguration(size_t qty, char** args)
496 : ConfigurationBase(qty, args)
497 {
498 }
499
500 void showOptions(std::ostream& out) const override
501 {
502 out
503 << " --settings [settings]" << std::endl
504 << "\tSettings file." << std::endl;
505 }
506};
507
509{
510public:
511 std::string nif() const
512 {
513 return requiredArg<std::string>(options(), "nif");
514 }
515
516protected:
518 : ConfigurationBase(qty, args)
519 {
520 }
521
522 void showOptions(std::ostream& out) const override
523 {
524 out
525 << " --nif <nif>" << std::endl
526 << "\tNetwork interface." << std::endl;
527 }
528};
529
531{
532public:
533 int clientId() const
534 {
535 return argOrDefault(options(), "clientId", Default::ClientId);
536 }
537
538 std::string userId() const
539 {
540 return argOrDefault(options(), "userId", Default::UserId);
541 }
542
543 std::string password() const
544 {
545 return argOrDefault(options(), "password", Default::Password);
546 }
547
548 std::string traderId() const
549 {
550 return argOrDefault(options(), "traderId", Default::TraderId);
551 }
552
553 std::string traderPwd() const
554 {
555 return argOrDefault(options(), "traderPwd", Default::TraderPassword);
556 }
557
558protected:
559 LogonConfiguration(size_t qty, char** args)
560 : ConfigurationBase(qty, args)
561 {
562 }
563
564 void showOptions(std::ostream& out) const override
565 {
566 out
567 << " --clientId [clientId]" << std::endl
568 << " --userId [userId]" << std::endl
569 << " --password [password]" << std::endl
570 << " --traderId [traderId]" << std::endl
571 << " --traderPwd [traderPwd]" << std::endl;
572 }
573};
574
576{
577public:
578 ONIXS_ICEBOE_NAMESPACE::SessionStorageType::Enum storage() const
579 {
580 return argOrDefault(options(), "storage", defaultStorage());
581 }
582
583 ONIXS_ICEBOE_NAMESPACE::CpuIndex storageAffinity() const
584 {
586 return requiredArg<CpuIndex>(options(), "storageCpu");
587
588 return 0;
589 }
590
591protected:
592 StorageConfigurationBase(size_t qty, char** args)
593 : ConfigurationBase(qty, args)
594 {
595 }
596
597 virtual ONIXS_ICEBOE_NAMESPACE::SessionStorageType::Enum defaultStorage() const = 0;
598
599 void showOptions(std::ostream& out) const override
600 {
601 out
602 << " --storage [FileBased|AsyncFileBased|MemoryBased]" << std::endl
603 << "\tDefault value is [" << SessionStorageType::toString(defaultStorage()) << "]" << std::endl
604 << " --storageCpu <cpu>" << std::endl
605 << "\tAsyncFileBased storage CPU affinity" << std::endl
606 ;
607 }
608};
609
610template <ONIXS_ICEBOE_NAMESPACE::SessionStorageType::Enum DefaultStorage>
612{
613protected:
614 ONIXS_ICEBOE_NAMESPACE::SessionStorageType::Enum defaultStorage() const override
615 {
616 return DefaultStorage;
617 }
618
619 StorageConfiguration(size_t qty, char** args)
620 : ConfigurationBase(qty, args)
622 {
623 }
624};
625
627{
628public:
630 {
631 return argOrDefault(options(), "mainThreadCpu", Default::MainThreadCpuAffinity);
632 }
633
634protected:
636 : ConfigurationBase(qty, args)
637 {
638 }
639
640 void showOptions(std::ostream& out) const override
641 {
642 out
643 << " --mainThreadCpu [mainThreadCpu]" << std::endl
644 << "\tDefault value is [" << toStr(Default::MainThreadCpuAffinity) << "]" << std::endl;
645 }
646};
647
649{
650public:
652 {
653 return argOrDefault(options(), "receivingThreadCpu", Default::ReceivingThreadCpuAffinity);
654 }
655
656protected:
658 : ConfigurationBase(qty, args)
659 {
660 }
661
662 void showOptions(std::ostream& out) const override
663 {
664 out
665 << " --receivingThreadCpu [mainThreadCpu]" << std::endl
666 << "\tDefault value is [" << toStr(Default::ReceivingThreadCpuAffinity) << "]" << std::endl;
667 }
668};
669
671{
672public:
673 size_t numberOfMessages() const
674 {
675 return argOrDefault(options(), "numberOfMessages", Default::NumberOfMessages);
676 }
677
678 size_t warmupInterval() const
679 {
680 return argOrDefault(options(), "warmupInterval", Default::WarmupInterval);
681 }
682
684 {
685 return argOrDefault(options(), "intervalBetweenSending", Default::IntervalBetweenSending);
686 }
687
688protected:
689 BenchmarkConfiguration(size_t qty, char** args)
690 : ConfigurationBase(qty, args)
691 {
692 if (!this->show())
693 {
694 if (Utils::BuildInfo::library().debug() || Utils::consumerBuildInfo().debug())
695 {
696 std::cerr << "Please use the RELEASE build for benchmarking." << std::endl;
697
698#if !defined(ONIXS_DEBUGGING)
699 exit(1);
700#endif
701 }
702 }
703 }
704
705 void showOptions(std::ostream& out) const override
706 {
707 out
708 << " --numberOfMessages [number]" << std::endl
709 << "\tDefault value is [" << toStr(Default::NumberOfMessages) << "]" << std::endl
710 << " --warmupInterval [number]" << std::endl
711 << "\tMicroseconds, Default value is [" << toStr(Default::WarmupInterval) << "]" << std::endl
712 << " --warmupInterval [number]" << std::endl
713 << "\tMicroseconds, Default value is [" << toStr(Default::IntervalBetweenSending) << "]" << std::endl;
714 }
715};
716
717
718template <typename... Bases>
719struct AppConfiguration final : public Bases...
720{
721 AppConfiguration(const char* name, int argc, char** argv, std::ostream& out = std::clog)
722 : ConfigurationBase(argc, argv)
723 , Bases(argc, argv)...
724 {
725 out << "OnixS ICE Binary Order Entry C++ '" << name << "' Sample, version " << Session::version() << '.' << std::endl;
726
727 if (this->show())
728 {
729 this->show(out);
730 exit(0);
731 }
732 }
733
734 void showOptions(std::ostream& out) const override
735 {
736 ONIXS_ICEBOE_UNUSED const int _[] = {0, ((void)Bases::showOptions(out), 0)...};
737 }
738};
739
741{
742public:
743 std::string location() const
744 {
745 return Samples::requiredArg<std::string>(options(), "location");
746 }
747
748protected:
749 InputLogFileConfiguration(size_t qty, char** args)
750 : ConfigurationBase(qty, args)
751 {
752 }
753
754 void showOptions(std::ostream& out) const override
755 {
756 out
757 << " --location <FileName|DirectoryName>" << std::endl;
758 }
759};
760
761}
#define ONIXS_ICEBOE_UNUSED
Definition Compiler.h:164
static const char * version() noexcept
static BuildInfo library() noexcept
Returns build info for the library binary itself.
const char * operator*() const
Definition Options.h:55
ArgCarriage(size_t qty, char **args) noexcept
Definition Options.h:41
size_t intervalBetweenSending() const
Definition Options.h:683
size_t numberOfMessages() const
Definition Options.h:673
BenchmarkConfiguration(size_t qty, char **args)
Definition Options.h:689
size_t warmupInterval() const
Definition Options.h:678
void showOptions(std::ostream &out) const override
Definition Options.h:705
virtual ~ConfigurationBase()=default
const Options & options() const noexcept
Definition Options.h:429
virtual void showOptions(std::ostream &) const =0
ConfigurationBase(size_t qty, char **args) noexcept
Definition Options.h:424
static bool exist(const Options &options, const Char *option)
Definition Options.h:436
void show(std::ostream &out) const
Definition Options.h:414
ConnectivityConfiguration(size_t qty, char **args)
Definition Options.h:472
void showOptions(std::ostream &out) const override
Definition Options.h:477
InputLogFileConfiguration(size_t qty, char **args)
Definition Options.h:749
void showOptions(std::ostream &out) const override
Definition Options.h:754
std::string location() const
Definition Options.h:743
LogonConfiguration(size_t qty, char **args)
Definition Options.h:559
std::string traderPwd() const
Definition Options.h:553
std::string password() const
Definition Options.h:543
std::string traderId() const
Definition Options.h:548
std::string userId() const
Definition Options.h:538
void showOptions(std::ostream &out) const override
Definition Options.h:564
Threading::CpuIndex mainThreadCpu() const
Definition Options.h:629
MainThreadAffinityConfiguration(size_t qty, char **args)
Definition Options.h:635
void showOptions(std::ostream &out) const override
Definition Options.h:640
NetworkInterfaceConfiguration(size_t qty, char **args)
Definition Options.h:517
void showOptions(std::ostream &out) const override
Definition Options.h:522
OptionArgConverter(const Char *=nullptr)
Definition Options.h:282
const Char * operator()(const std::string &str) const
Definition Options.h:284
OptionArgConverter(const Char *=nullptr)
Definition Options.h:270
std::string operator()(const std::string &str) const
Definition Options.h:272
Value operator()(const std::string &str) const
Definition Options.h:252
OptionArgConverter(const Char *option=nullptr)
Definition Options.h:247
const OptionArgs * args(const std::string &option) const
Definition Options.h:166
const OptionArgs * args(const char *option) const
Definition Options.h:160
Options(size_t qty, char **args)
Definition Options.h:103
void get(Iterator target) const
Definition Options.h:154
ReceivingThreadAffinityConfiguration(size_t qty, char **args)
Definition Options.h:657
Threading::CpuIndex receivingThreadCpu() const
Definition Options.h:651
void showOptions(std::ostream &out) const override
Definition Options.h:662
SettingsConfiguration(size_t qty, char **args)
Definition Options.h:495
void showOptions(std::ostream &out) const override
Definition Options.h:500
std::string settingsFile() const
Definition Options.h:489
OnixS::ICE::BOE::CpuIndex storageAffinity() const
Definition Options.h:583
virtual OnixS::ICE::BOE::SessionStorageType::Enum defaultStorage() const =0
StorageConfigurationBase(size_t qty, char **args)
Definition Options.h:592
OnixS::ICE::BOE::SessionStorageType::Enum storage() const
Definition Options.h:578
void showOptions(std::ostream &out) const override
Definition Options.h:599
OnixS::ICE::BOE::SessionStorageType::Enum defaultStorage() const override
Definition Options.h:614
StorageConfiguration(size_t qty, char **args)
Definition Options.h:619
char Char
Character type alias.
Definition String.h:31
std::basic_string_view< Char > StrRef
Definition StrRef.h:46
StrRef toStrRef(const std::string &str)
Constructs a StrRef instance over th std::string content.
Definition StrRef.h:392
bool fromStr(Decimal &, const Char *, size_t) noexcept
Deserializes a decimal number from the given text presentation.
size_t CpuIndex
Logical processors that a thread is allowed to run on (first logical CPU has index 0).
Definition Thread.h:31
unsigned short Port
Definition Defines.h:41
constexpr Threading::CpuIndex ReceivingThreadCpuAffinity
Definition Defaults.h:41
constexpr Threading::CpuIndex NumberOfMessages
Definition Defaults.h:53
constexpr Threading::CpuIndex MainThreadCpuAffinity
Definition Defaults.h:40
constexpr const char * UserId
Definition Defaults.h:35
constexpr Port TlsPort
Definition Defaults.h:32
constexpr size_t IntervalBetweenSending
Definition Defaults.h:55
constexpr const char * TraderId
Definition Defaults.h:37
constexpr size_t WarmupInterval
Definition Defaults.h:54
constexpr const char * Password
Definition Defaults.h:36
constexpr const char * TraderPassword
Definition Defaults.h:38
constexpr int ClientId
Definition Defaults.h:34
Value argOrDefault(const Options &options, const Char *option, const Value &defaultValue=Value())
Definition Options.h:375
std::vector< OptionArg > OptionArgs
Definition Options.h:35
Value requiredArg(const Options &options, const Char *option)
Definition Options.h:391
bool args(const Options &options, const Char *option, Iterator target, size_t minQty=0, size_t maxQty=static_cast< size_t >(-1))
Definition Options.h:345
void throwOptionArgConversionFailed(const Char *option)
Definition Options.h:209
void throwDuplicatedOption(const Char *option)
Definition Options.h:87
std::string toStr(Order::PriceOptional value)
Definition Order.cpp:34
void convertOptionArg(Value &value, const Char *option, const std::string &str)
Definition Options.h:291
void throwBadOptionArgQty(const Char *option, size_t argQty, size_t minQty, size_t maxQty)
Definition Options.h:298
void throwBadOption(const Char *arg)
Definition Options.h:74
std::string Option
Definition Options.h:33
std::string OptionArg
Definition Options.h:34
void throwReqiredOptionArgMissing(const Char *option)
Definition Options.h:329
T fromStr(const std::string &s)
Definition Helpers.h:142
static Enum parse(const std::string &)
@ AsyncFileBased
Asynchronous File-Based Session Storage.
static const char * toString(SessionStorageType::Enum)
AppConfiguration(const char *name, int argc, char **argv, std::ostream &out=std::clog)
Definition Options.h:721
void showOptions(std::ostream &out) const override
Definition Options.h:734