| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- //
- // impl/config.ipp
- // ~~~~~~~~~~~~~~~
- //
- // Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef BOOST_ASIO_IMPL_CONFIG_IPP
- #define BOOST_ASIO_IMPL_CONFIG_IPP
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- # pragma once
- #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
- #include <boost/asio/config.hpp>
- #include <boost/asio/detail/concurrency_hint.hpp>
- #include <cctype>
- #include <cstdio>
- #include <cstring>
- #include <cstdlib>
- #include <vector>
- #include <utility>
- #include <boost/asio/detail/push_options.hpp>
- namespace boost {
- namespace asio {
- config_service::config_service(execution_context& ctx)
- : detail::execution_context_service_base<config_service>(ctx)
- {
- }
- void config_service::shutdown()
- {
- }
- const char* config_service::get_value(const char* /*section*/,
- const char* /*key_name*/, char* /*value*/, std::size_t /*value_len*/) const
- {
- return nullptr;
- }
- namespace detail {
- class config_from_concurrency_hint_service : public config_service
- {
- public:
- explicit config_from_concurrency_hint_service(
- execution_context& ctx, int concurrency_hint)
- : config_service(ctx),
- concurrency_hint_(concurrency_hint)
- {
- }
- const char* get_value(const char* section, const char* key_name,
- char* value, std::size_t value_len) const override
- {
- if (std::strcmp(section, "scheduler") == 0)
- {
- if (std::strcmp(key_name, "concurrency_hint") == 0)
- {
- if (BOOST_ASIO_CONCURRENCY_HINT_IS_SPECIAL(concurrency_hint_))
- {
- return
- !BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(
- SCHEDULER, concurrency_hint_) ||
- !BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(
- REACTOR_IO, concurrency_hint_) ? "1" : "-1";
- }
- else
- {
- std::snprintf(value, value_len, "%d", concurrency_hint_);
- return value;
- }
- }
- else if (std::strcmp(key_name, "locking") == 0)
- {
- return BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(
- SCHEDULER, concurrency_hint_) ? "1" : "0";
- }
- }
- else if (std::strcmp(section, "reactor") == 0)
- {
- if (std::strcmp(key_name, "io_locking") == 0)
- {
- return BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(
- REACTOR_IO, concurrency_hint_) ? "1" : "0";
- }
- else if (std::strcmp(key_name, "registration_locking") == 0)
- {
- return BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(
- REACTOR_REGISTRATION, concurrency_hint_) ? "1" : "0";
- }
- }
- return nullptr;
- }
- private:
- int concurrency_hint_;
- };
- } // namespace detail
- config_from_concurrency_hint::config_from_concurrency_hint()
- : concurrency_hint_(BOOST_ASIO_CONCURRENCY_HINT_DEFAULT)
- {
- }
- void config_from_concurrency_hint::make(execution_context& ctx) const
- {
- (void)make_service<detail::config_from_concurrency_hint_service>(ctx,
- concurrency_hint_ == 1
- ? BOOST_ASIO_CONCURRENCY_HINT_1 : concurrency_hint_);
- }
- namespace detail {
- class config_from_string_service : public config_service
- {
- public:
- config_from_string_service(execution_context& ctx,
- std::string s, std::string prefix)
- : config_service(ctx),
- string_(static_cast<std::string&&>(s)),
- prefix_(static_cast<std::string&&>(prefix))
- {
- enum
- {
- expecting_key_name,
- key_name,
- expecting_equals,
- expecting_value,
- value,
- expecting_eol
- } state = expecting_key_name;
- std::pair<const char*, const char*> entry{};
- for (char& c : string_)
- {
- switch (state)
- {
- case expecting_key_name:
- switch (c)
- {
- case ' ': case '\t': case '\n':
- break;
- case '#':
- state = expecting_eol;
- break;
- default:
- entry.first = &c;
- state = key_name;
- break;
- }
- break;
- case key_name:
- switch (c)
- {
- case ' ': case '\t':
- c = 0;
- state = expecting_equals;
- break;
- case '=':
- c = 0;
- state = expecting_value;
- break;
- case '\n':
- entry.first = nullptr;
- state = expecting_key_name;
- break;
- case '#':
- entry.first = nullptr;
- state = expecting_eol;
- break;
- default:
- break;
- }
- break;
- case expecting_equals:
- switch (c)
- {
- case ' ': case '\t':
- break;
- case '=':
- state = expecting_value;
- break;
- case '\n':
- entry.first = nullptr;
- state = expecting_key_name;
- break;
- default:
- entry.first = nullptr;
- state = expecting_eol;
- break;
- }
- break;
- case expecting_value:
- switch (c)
- {
- case ' ': case '\t':
- break;
- case '\n':
- entry.first = nullptr;
- state = expecting_key_name;
- break;
- case '#':
- entry.first = nullptr;
- state = expecting_eol;
- break;
- default:
- entry.second = &c;
- state = value;
- break;
- }
- break;
- case value:
- switch (c)
- {
- case '\n':
- c = 0;
- entries_.push_back(entry);
- entry.first = entry.second = nullptr;
- state = expecting_key_name;
- break;
- case '#':
- c = 0;
- entries_.push_back(entry);
- entry.first = entry.second = nullptr;
- state = expecting_eol;
- break;
- default:
- break;
- }
- break;
- case expecting_eol:
- switch (c)
- {
- case '\n':
- state = expecting_key_name;
- break;
- default:
- break;
- }
- break;
- }
- }
- if (entry.first && entry.second)
- entries_.push_back(entry);
- }
- const char* get_value(const char* section, const char* key_name,
- char* /*value*/, std::size_t /*value_len*/) const override
- {
- std::string entry_key;
- entry_key.reserve(prefix_.length() + 1
- + std::strlen(section) + 1
- + std::strlen(key_name) + 1);
- entry_key.append(prefix_);
- if (!entry_key.empty())
- entry_key.append(".");
- entry_key.append(section);
- entry_key.append(".");
- entry_key.append(key_name);
- for (const std::pair<const char*, const char*>& entry : entries_)
- if (entry_key == entry.first)
- return entry.second;
- return nullptr;
- }
- private:
- std::string string_;
- std::string prefix_;
- std::vector<std::pair<const char*, const char*>> entries_;
- };
- } // namespace detail
- void config_from_string::make(execution_context& ctx) const
- {
- (void)make_service<detail::config_from_string_service>(ctx, string_, prefix_);
- }
- namespace detail {
- #if defined(BOOST_ASIO_MSVC)
- # pragma warning (push)
- # pragma warning (disable:4996) // suppress unsafe warning for std::getenv
- #endif // defined(BOOST_ASIO_MSVC)
- class config_from_env_service : public config_service
- {
- public:
- explicit config_from_env_service(
- execution_context& ctx, std::string prefix)
- : config_service(ctx),
- prefix_(static_cast<std::string&&>(prefix))
- {
- }
- const char* get_value(const char* section, const char* key_name,
- char* /*value*/, std::size_t /*value_len*/) const override
- {
- std::string env_var;
- env_var.reserve(prefix_.length() + 1
- + std::strlen(section) + 1
- + std::strlen(key_name) + 1);
- env_var.append(prefix_);
- if (!env_var.empty())
- env_var.append("_");
- env_var.append(section);
- env_var.append("_");
- env_var.append(key_name);
- for (char& c : env_var)
- c = static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
- return std::getenv(env_var.c_str());
- }
- private:
- std::string prefix_;
- };
- #if defined(BOOST_ASIO_MSVC)
- # pragma warning (pop)
- #endif // defined(BOOST_ASIO_MSVC)
- } // namespace detail
- config_from_env::config_from_env()
- : prefix_("asio")
- {
- }
- void config_from_env::make(execution_context& ctx) const
- {
- (void)make_service<detail::config_from_env_service>(ctx, prefix_);
- }
- } // namespace asio
- } // namespace boost
- #include <boost/asio/detail/pop_options.hpp>
- #endif // BOOST_ASIO_IMPL_CONFIG_IPP
|