SNode.C
Loading...
Searching...
No Matches
utils Namespace Reference

Namespaces

namespace  CallForCommandline
namespace  system

Classes

struct  AppWithPtr
class  Uuid
class  Timeval
class  Config
class  DaemonFailure
class  DaemonError
class  DaemonSignaled
class  Daemon
class  PreserveErrno
class  Random
struct  fixed_string
class  AttributeProxy
class  SingleAttributeInjector
class  MultibleAttributeInjector
class  SHA1

Concepts

concept  InjectableAttribute

Functions

static std::shared_ptr< CLI::App > makeApp ()
static std::string createCommandLineTemplate (CLI::App *app, utils::CallForCommandline::Mode mode)
static std::string bash_backslash_escape_no_whitespace (std::string_view s)
static void createCommandLineOptions (std::stringstream &out, CLI::App *app, utils::CallForCommandline::Mode mode)
static std::string createCommandLineOptions (CLI::App *app, utils::CallForCommandline::Mode mode)
static void createCommandLineTemplate (std::stringstream &out, CLI::App *app, utils::CallForCommandline::Mode mode)
static std::string createCommandLineSubcommands (CLI::App *app, utils::CallForCommandline::Mode mode)
static std::string getCommandLine (CLI::App *commandlineTriggerApp)
static std::string getConfig (CLI::App *configTriggeredApp)
static std::string doWriteConfig (CLI::App *app)
static std::string getHelp (CLI::App *app, CLI::App *helpTriggerApp)
static std::shared_ptr< CLI::HelpFormattermakeSectionFormatter ()
std::string hexDump (const std::vector< char > &bytes, int prefixLength, bool prefixAtFirstLine)
std::string hexDump (const std::string &string, int prefixLength, bool prefixAtFirstLine)
std::string hexDump (const char *bytes, uint64_t length, int prefixLength, bool prefixAtFirstLine)
static std::vector< unsigned char > transform_to_binary (const std::string &string)
std::vector< unsigned char > sha1 (const std::string &string)
std::ostream & operator<< (std::ostream &ostream, const utils::Timeval &timeVal)
Timeval operator* (double mul, const utils::Timeval &timeVal)
template<unsigned N>
 fixed_string (char const (&)[N]) -> fixed_string< N - 1 >

Function Documentation

◆ bash_backslash_escape_no_whitespace()

std::string utils::bash_backslash_escape_no_whitespace ( std::string_view s)
static

Definition at line 453 of file Config.cpp.

453 {
454 static const std::unordered_set<char> special{
455 '\\', '\'', // quoting/escape
456 '`', '$', // substitution
457 '|', '&', ';', '<', '>', '(', ')', '{', '}', // operators
458 '*', '?', '[', ']', '~', '!', '#', '=' // globbing/history/others
459 };
460
461 std::string out;
462 out.reserve(s.size() * 3);
463
464 for (const char c : s) {
465 if (special.contains(c)) {
466 out.push_back('\\');
467 }
468 out.push_back(c);
469 }
470 return out;
471 }

Referenced by createCommandLineOptions().

Here is the caller graph for this function:

◆ createCommandLineOptions() [1/2]

std::string utils::createCommandLineOptions ( CLI::App * app,
utils::CallForCommandline::Mode mode )
static

Definition at line 553 of file Config.cpp.

553 {
554 std::stringstream out;
555
556 createCommandLineOptions(out, app, mode);
557
558 std::string optionString = out.str();
559 if (!optionString.empty() && optionString.back() == ' ') {
560 optionString.pop_back();
561 }
562
563 return optionString;
564 }
static void createCommandLineOptions(std::stringstream &out, CLI::App *app, utils::CallForCommandline::Mode mode)
Definition Config.cpp:473

References createCommandLineOptions().

Referenced by createCommandLineTemplate(), and createCommandLineTemplate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ createCommandLineOptions() [2/2]

void utils::createCommandLineOptions ( std::stringstream & out,
CLI::App * app,
utils::CallForCommandline::Mode mode )
static

Definition at line 473 of file Config.cpp.

473 {
474 const CLI::Option* disabledOpt = app->get_option_no_throw("--disabled");
475 const bool disabled = disabledOpt != nullptr ? disabledOpt->as<bool>() : false;
476 if (!disabled || mode == utils::CallForCommandline::Mode::COMPLETE) {
477 for (const CLI::Option* option : app->get_options()) {
478 if (option->get_configurable()) {
479 std::string value;
480
481 switch (mode) {
483 if (option->count() > 0) {
484 try {
485 for (const auto& result : option->reduced_results()) {
486 value += (!result.empty() ? result : "\"\"") + " ";
487 }
488 value.pop_back();
489 } catch (CLI::ParseError& e) {
490 value = std::string{"<["} + Color::Code::FG_RED + e.get_name() + Color::Code::FG_DEFAULT + "] " +
491 e.what() + ">";
492 }
493 } else if (option->get_required()) {
494 value = "<REQUIRED>";
495 }
496 break;
498 if (option->get_required()) {
499 if (option->count() > 0) {
500 try {
501 for (const auto& result : option->reduced_results()) {
502 value += (!result.empty() ? result : "\"\"") + " ";
503 }
504 value.pop_back();
505 } catch (CLI::ParseError& e) {
506 value = std::string{"<["} + Color::Code::FG_RED + e.get_name() + Color::Code::FG_DEFAULT + "] " +
507 e.what() + ">";
508 }
509 } else {
510 value = "<REQUIRED>";
511 }
512 }
513 break;
516 if (option->count() > 0) {
517 try {
518 for (const auto& result : option->reduced_results()) {
519 value += (!result.empty() ? result : "\"\"") + " ";
520 }
521 value.pop_back();
522 } catch (CLI::ParseError& e) {
523 value = std::string{"<["} + Color::Code::FG_RED + e.get_name() + Color::Code::FG_DEFAULT + "] " +
524 e.what() + ">";
525 }
526 } else if (!option->get_default_str().empty()) {
527 value = option->get_default_str();
528 } else if (!option->get_required()) {
529 value = "\"\"";
530 } else {
531 value = "<REQUIRED>";
532 }
533 break;
534 }
535
536 if (!value.empty()) {
537 if (value.starts_with("[") && value.ends_with("]")) {
538 value = value.substr(1, value.size() - 2);
539 }
540
541 if (value != "<REQUIRED>" && value != "\"\"" && !value.starts_with("<[")) {
543 }
544 out << "--" << option->get_single_name() << ((option->get_items_expected_max() == 0) ? "=" : " ") << value << " ";
545 }
546 }
547 }
548 } else if (disabledOpt->get_default_str() == "false") {
549 out << "--disabled=true ";
550 }
551 }
@ FG_DEFAULT
Definition Logger.h:69
static std::string bash_backslash_escape_no_whitespace(std::string_view s)
Definition Config.cpp:453

References utils::CallForCommandline::ACTIVE, bash_backslash_escape_no_whitespace(), utils::CallForCommandline::COMPLETE, Color::FG_DEFAULT, Color::FG_RED, Color::operator+(), utils::CallForCommandline::REQUIRED, and utils::CallForCommandline::STANDARD.

Referenced by createCommandLineOptions().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ createCommandLineSubcommands()

std::string utils::createCommandLineSubcommands ( CLI::App * app,
utils::CallForCommandline::Mode mode )
static

Definition at line 568 of file Config.cpp.

568 {
569 std::stringstream out;
570
571 const CLI::Option* disabledOpt = app->get_option_no_throw("--disabled");
572 if (disabledOpt == nullptr || !disabledOpt->as<bool>() || mode == utils::CallForCommandline::Mode::COMPLETE) {
573 for (CLI::App* subcommand : app->get_subcommands({})) {
574 if (!subcommand->get_name().empty()) {
575 createCommandLineTemplate(out, subcommand, mode);
576 }
577 }
578 }
579
580 return out.str();
581 }
static std::string createCommandLineTemplate(CLI::App *app, utils::CallForCommandline::Mode mode)
Definition Config.cpp:598

References utils::CallForCommandline::COMPLETE, and createCommandLineTemplate().

Referenced by createCommandLineTemplate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ createCommandLineTemplate() [1/2]

std::string utils::createCommandLineTemplate ( CLI::App * app,
utils::CallForCommandline::Mode mode )
static

Definition at line 598 of file Config.cpp.

598 {
599 std::stringstream out;
600
601 createCommandLineTemplate(out, app, mode);
602
603 std::string outString = out.str();
604 while (app->get_parent() != nullptr) {
605 app = app->get_parent();
606 std::string parentOptions = createCommandLineOptions(app, mode);
607 outString =
608 std::string(app->get_name()).append(" ").append(!parentOptions.empty() ? parentOptions.append(" ") : "").append(outString);
609 }
610
611 if (outString.empty()) {
612 outString = Config::getApplicationName();
613 }
614
615 return outString;
616 }
static std::string getApplicationName()
Definition Config.cpp:434

References createCommandLineOptions(), createCommandLineTemplate(), and utils::Config::getApplicationName().

Referenced by getCommandLine().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ createCommandLineTemplate() [2/2]

void utils::createCommandLineTemplate ( std::stringstream & out,
CLI::App * app,
utils::CallForCommandline::Mode mode )
static

Definition at line 583 of file Config.cpp.

583 {
584 std::string outString;
585
586 outString = createCommandLineOptions(app, mode);
587 if (!outString.empty()) {
588 outString += " ";
589 }
590
591 outString += createCommandLineSubcommands(app, mode);
592
593 if (!outString.empty()) {
594 out << app->get_name() << " " << outString;
595 }
596 }
static std::string createCommandLineSubcommands(CLI::App *app, utils::CallForCommandline::Mode mode)
Definition Config.cpp:568

References createCommandLineOptions(), and createCommandLineSubcommands().

Referenced by createCommandLineSubcommands(), and createCommandLineTemplate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ doWriteConfig()

std::string utils::doWriteConfig ( CLI::App * app)
static

Definition at line 676 of file Config.cpp.

676 {
677 std::stringstream out;
678
679 std::ofstream confFile((*app)["--write-config"]->as<std::string>());
680 if (confFile.is_open()) {
681 try {
682 confFile << app->config_to_str(true, true);
683 confFile.close();
684 out << "[" << Color::Code::FG_GREEN << "SUCCESS" << Color::Code::FG_DEFAULT
685 << "] Writing config file: " + app->get_option_no_throw("--write-config")->as<std::string>() << std::endl
686 << std::endl;
687 } catch (const CLI::ParseError& e) {
688 confFile.close();
689 out << "[" << Color::Code::FG_RED << "Error" << Color::Code::FG_DEFAULT << "] Writing config file: " << e.get_name() << " "
690 << e.what() << std::endl;
691 }
692 confFile.close();
693 } else {
694 out << "[" << Color::Code::FG_RED << "Error" << Color::Code::FG_DEFAULT << "] Writing config file: " << std::strerror(errno)
695 << std::endl;
696 }
697
698 return out.str();
699 }

References Color::FG_DEFAULT, Color::FG_GREEN, and Color::FG_RED.

Referenced by utils::Config::parse2().

Here is the caller graph for this function:

◆ fixed_string()

template<unsigned N>
utils::fixed_string ( char const(&)[N]) ->fixed_string< N-1 >

◆ getCommandLine()

std::string utils::getCommandLine ( CLI::App * commandlineTriggerApp)
static

Definition at line 618 of file Config.cpp.

618 {
619 const std::string modeString = commandlineTriggerApp->get_option("--command-line")->as<std::string>();
620
622 std::ostringstream out;
623
624 if (modeString == "standard") {
625 out << "Below is a command line viewing all non-default and required options:\n"
626 "* Options show their configured value\n"
627 "* Required but not yet configured options show <REQUIRED> as value\n"
628 "* Options marked as <REQUIRED> need to be configured for a successful bootstrap"
629 << std::endl;
631
632 } else if (modeString == "active") {
633 out << "Below is a command line viewing the active set of options with their default or configured values:\n"
634 "* Options show either their configured or default value\n"
635 "* Required but not yet configured options show <REQUIRED> as value\n"
636 "* Options marked as <REQUIRED> need to be configured for a successful bootstrap"
637 << std::endl;
639 } else if (modeString == "complete") {
640 out << "Below is a command line viewing the complete set of options with their default values\n"
641 "* Options show their default value\n"
642 "* Required but not yet configured options show <REQUIRED> as value\n"
643 "* Options marked as <REQUIRED> need to be configured for a successful bootstrap"
644 << std::endl;
646 } else if (modeString == "required") {
647 out << "Below is a command line viewing required options only:\n"
648 "* Options show either their configured or default value\n"
649 "* Required but not yet configured options show <REQUIRED> as value\n"
650 "* Options marked as <REQUIRED> need to be configured for a successful bootstrap"
651 << std::endl;
653 }
654
655 out << std::endl
656 << Color::Code::FG_GREEN << "command@line" << Color::Code::FG_DEFAULT << ":" << Color::Code::FG_BLUE << "~/> "
657 << Color::Code::FG_DEFAULT << createCommandLineTemplate(commandlineTriggerApp, mode) << std::endl
658 << std::endl;
659
660 return out.str();
661 }

References utils::CallForCommandline::ACTIVE, utils::CallForCommandline::COMPLETE, createCommandLineTemplate(), Color::FG_BLUE, Color::FG_DEFAULT, Color::FG_GREEN, utils::CallForCommandline::REQUIRED, and utils::CallForCommandline::STANDARD.

Referenced by utils::Config::parse2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getConfig()

std::string utils::getConfig ( CLI::App * configTriggeredApp)
static

Definition at line 663 of file Config.cpp.

663 {
664 std::stringstream out;
665
666 try {
667 out << configTriggeredApp->config_to_str(true, true);
668 } catch (const CLI::ParseError& e) {
669 out << "[" << Color::Code::FG_RED << "Error" << Color::Code::FG_DEFAULT
670 << "] Showing current config: " << configTriggeredApp->get_name() << " " << e.get_name() << " " << e.what();
671 }
672
673 return out.str();
674 }

References Color::FG_DEFAULT, and Color::FG_RED.

Referenced by utils::Config::parse2().

Here is the caller graph for this function:

◆ getHelp()

std::string utils::getHelp ( CLI::App * app,
CLI::App * helpTriggerApp )
static

Definition at line 701 of file Config.cpp.

701 {
702 std::stringstream out;
703
704 const std::string helpMode = (helpTriggerApp != nullptr ? helpTriggerApp : app)->get_option("--help")->as<std::string>();
705
706 const CLI::App* helpApp = nullptr;
707 CLI::AppFormatMode mode = CLI::AppFormatMode::Normal;
708 if (helpMode == "exact") {
709 helpApp = helpTriggerApp;
710 } else if (helpMode == "expanded") {
711 helpApp = helpTriggerApp;
712 mode = CLI::AppFormatMode::All;
713 }
714 try {
715 out << app->help(helpApp, "", mode);
716 } catch (CLI::ParseError& e) {
717 out << "[" << Color::Code::FG_RED << "Error" << Color::Code::FG_DEFAULT << "] Show help: " << e.get_name() << " " << e.what();
718 }
719
720 return out.str();
721 }

References Color::FG_DEFAULT, and Color::FG_RED.

Referenced by utils::Config::parse2().

Here is the caller graph for this function:

◆ hexDump() [1/3]

std::string utils::hexDump ( const char * bytes,
uint64_t length,
int prefixLength = 0,
bool prefixAtFirstLine = false )

Definition at line 66 of file hexdump.cpp.

66 {
67 std::stringstream hexStream;
68
69 if (length > 0) {
70 uint8_t buff[17];
71 size_t i = 0;
72
73 hexStream << std::hex;
74
75 int currentPrefixLength = prefixAtFirstLine ? prefixLength : 0;
76
77 // Process every byte in the data.
78 for (i = 0; i < length; i++) {
79 // Multiple of 16 means new line (with line offset).
80
81 if ((i % 16) == 0) {
82 // Just don't print ASCII for the zeroth line.
83 if (i != 0) {
84 hexStream << " " << buff << std::endl;
85 }
86
87 // Output the offset.
88 hexStream << Color::Code::FG_BLUE;
89 hexStream << std::setw(currentPrefixLength) << std::setfill(' ') << ""
90 << ": " << std::setw(8) << std::setfill('0') << static_cast<unsigned int>(i);
91 hexStream << Color::Code::FG_DEFAULT << " ";
92 }
93
94 // Now the hex code for the specific character.
95 hexStream << Color::Code::FG_GREEN;
96 hexStream << " " << std::setw(2) << std::setfill('0') << static_cast<unsigned int>(static_cast<unsigned char>(bytes[i]));
97 hexStream << Color::Code::FG_DEFAULT;
98
99 // And store a printable ASCII character for later.
100 if ((bytes[i] < 0x20) || (bytes[i] > 0x7e)) {
101 buff[i % 16] = '.';
102 } else {
103 buff[i % 16] = static_cast<uint8_t>(bytes[i]);
104 }
105 buff[(i % 16) + 1] = '\0';
106
107 currentPrefixLength = prefixLength;
108 }
109
110 hexStream << std::dec;
111
112 // Pad out last line if not exactly 16 characters.
113 while ((i % 16) != 0) {
114 hexStream << " ";
115 i++;
116 }
117
118 // And print the final ASCII bit.
119 hexStream << " " << buff;
120 }
121
122 return hexStream.str();
123 }

References Color::FG_BLUE, Color::FG_DEFAULT, and Color::FG_GREEN.

Referenced by hexDump(), hexDump(), web::websocket::Receiver::readPayload(), and web::websocket::Transmitter::sendFrame().

Here is the caller graph for this function:

◆ hexDump() [2/3]

std::string utils::hexDump ( const std::string & string,
int prefixLength = 0,
bool prefixAtFirstLine = false )

Definition at line 62 of file hexdump.cpp.

62 {
63 return hexDump(string.data(), string.length(), prefixLength, prefixAtFirstLine);
64 }
std::string hexDump(const std::vector< char > &bytes, int prefixLength, bool prefixAtFirstLine)
Definition hexdump.cpp:58

References hexDump().

Here is the call graph for this function:

◆ hexDump() [3/3]

std::string utils::hexDump ( const std::vector< char > & bytes,
int prefixLength = 0,
bool prefixAtFirstLine = false )

Definition at line 58 of file hexdump.cpp.

58 {
59 return hexDump(bytes.data(), bytes.size(), prefixLength, prefixAtFirstLine);
60 }

References hexDump().

Referenced by iot::mqtt::SubProtocol< WSSubProtocolRoleT >::onMessageData(), iot::mqtt::Mqtt::toHexString(), httputils::toString(), and httputils::toString().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ makeApp()

std::shared_ptr< CLI::App > utils::makeApp ( )
static

Definition at line 102 of file Config.cpp.

102 { // NO_LINT
103 const std::shared_ptr<CLI::App> app = std::make_shared<CLI::App>();
104
105 app->configurable(false);
106 app->allow_extras();
107
108 const std::shared_ptr<CLI::HelpFormatter> helpFormatter = std::make_shared<CLI::HelpFormatter>();
109
110 helpFormatter->label("SUBCOMMAND", "INSTANCE");
111 helpFormatter->label("SUBCOMMANDS", "INSTANCES");
112 helpFormatter->label("PERSISTENT", "");
113 helpFormatter->label("Persistent Options", "Options (persistent)");
114 helpFormatter->label("Nonpersistent Options", "Options (nonpersistent)");
115 helpFormatter->label("Usage", "\nUsage");
116 helpFormatter->label("bool:{true,false}", "{true,false}");
117 helpFormatter->label(":{standard,active,complete,required}", "{standard,active,complete,required}");
118 helpFormatter->label(":{standard,exact,expanded}", "{standard,exact,expanded}");
119 helpFormatter->column_width(7);
120
121 app->formatter(helpFormatter);
122
123 app->config_formatter(std::make_shared<CLI::ConfigFormatter>());
124 app->get_config_formatter_base()->arrayDelimiter(' ');
125
126 app->option_defaults()->take_last();
127 app->option_defaults()->group(app->get_formatter()->get_label("Nonpersistent Options"));
128
130
131 return app;
132 }
static void init()
Definition Logger.cpp:54

References logger::Logger::init().

Here is the call graph for this function:

◆ makeSectionFormatter()

std::shared_ptr< CLI::HelpFormatter > utils::makeSectionFormatter ( )
static

Definition at line 853 of file Config.cpp.

853 {
854 const std::shared_ptr<CLI::HelpFormatter> sectionFormatter = std::make_shared<CLI::HelpFormatter>();
855
856 sectionFormatter->label("SUBCOMMAND", "SECTION");
857 sectionFormatter->label("SUBCOMMANDS", "SECTIONS");
858 sectionFormatter->label("PERSISTENT", "");
859 sectionFormatter->label("Persistent Options", "Options (persistent)");
860 sectionFormatter->label("Nonpersistent Options", "Options (nonpersistent)");
861 sectionFormatter->label("Usage", "\nUsage");
862 sectionFormatter->label("bool:{true,false}", "{true,false}");
863 sectionFormatter->label(":{standard,active,complete,required}", "{standard,active,complete,required}");
864 sectionFormatter->label(":{standard,exact,expanded}", "{standard,exact,expanded}");
865 sectionFormatter->column_width(7);
866
867 return sectionFormatter;
868 }

◆ operator*()

Timeval utils::operator* ( double mul,
const utils::Timeval & timeVal )

Definition at line 223 of file Timeval.cpp.

223 {
224 utils::Timeval help;
225
226 help.timeVal.tv_sec = static_cast<time_t>(static_cast<double>(timeVal.timeVal.tv_sec) * mul);
227 help.timeVal.tv_usec = static_cast<suseconds_t>(static_cast<double>(timeVal.timeVal.tv_usec) * mul);
228
229 return help.normalize();
230 }
timeval timeVal
Definition Timeval.h:99
const Timeval & normalize()
Definition Timeval.cpp:204

◆ operator<<()

std::ostream & utils::operator<< ( std::ostream & ostream,
const utils::Timeval & timeVal )

Definition at line 218 of file Timeval.cpp.

218 {
219 return ostream << std::string("{") + std::to_string(timeVal.timeVal.tv_sec) + std::string(":") +
220 std::to_string(timeVal.timeVal.tv_usec) + std::string("}");
221 }

◆ sha1()

std::vector< unsigned char > utils::sha1 ( const std::string & string)

Definition at line 267 of file sha1.cpp.

267 {
268 SHA1 checksum;
269 checksum.update(string);
270 return transform_to_binary(checksum.final());
271 }
std::string final()
Definition sha1.cpp:79
void update(const std::string &s)
Definition sha1.cpp:57
static std::vector< unsigned char > transform_to_binary(const std::string &string)
Definition sha1.cpp:251

References utils::SHA1::final(), transform_to_binary(), and utils::SHA1::update().

Referenced by base64::serverWebSocketKey().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transform_to_binary()

std::vector< unsigned char > utils::transform_to_binary ( const std::string & string)
static

Definition at line 251 of file sha1.cpp.

251 {
252 std::vector<unsigned char> buf;
253
254 char hex_byte[3];
255 hex_byte[2] = 0;
256
257 for (std::size_t i = 0, j = 0; i < string.size(); i += 2, j += 1) {
258 hex_byte[0] = string.at(i);
259 hex_byte[1] = string.at(i + 1);
260 char* end_ptr = nullptr;
261 buf.push_back(static_cast<unsigned char>(strtoul(hex_byte, &end_ptr, 16)));
262 }
263
264 return buf;
265 }

Referenced by sha1().

Here is the caller graph for this function: