[DEV] add v1.76.0

This commit is contained in:
2021-10-05 21:37:46 +02:00
parent a97e9ae7d4
commit d0115b733d
45133 changed files with 4744437 additions and 1026325 deletions

View File

@@ -0,0 +1,77 @@
//
// basic_logger.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 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 SERVICES_BASIC_LOGGER_HPP
#define SERVICES_BASIC_LOGGER_HPP
#include <boost/asio.hpp>
#include <boost/noncopyable.hpp>
#include <string>
namespace services {
/// Class to provide simple logging functionality. Use the services::logger
/// typedef.
template <typename Service>
class basic_logger
: private boost::noncopyable
{
public:
/// The type of the service that will be used to provide timer operations.
typedef Service service_type;
/// The native implementation type of the timer.
typedef typename service_type::impl_type impl_type;
/// Constructor.
/**
* This constructor creates a logger.
*
* @param context The execution context used to locate the logger service.
*
* @param identifier An identifier for this logger.
*/
explicit basic_logger(boost::asio::execution_context& context,
const std::string& identifier)
: service_(boost::asio::use_service<Service>(context)),
impl_(service_.null())
{
service_.create(impl_, identifier);
}
/// Destructor.
~basic_logger()
{
service_.destroy(impl_);
}
/// Set the output file for all logger instances.
void use_file(const std::string& file)
{
service_.use_file(impl_, file);
}
/// Log a message.
void log(const std::string& message)
{
service_.log(impl_, message);
}
private:
/// The backend service implementation.
service_type& service_;
/// The underlying native implementation.
impl_type impl_;
};
} // namespace services
#endif // SERVICES_BASIC_LOGGER_HPP

View File

@@ -0,0 +1,101 @@
//
// daytime_client.cpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 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)
//
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <iostream>
#include "logger.hpp"
using boost::asio::ip::tcp;
char read_buffer[1024];
void read_handler(const boost::system::error_code& e,
std::size_t bytes_transferred, tcp::socket* s)
{
if (!e)
{
std::cout.write(read_buffer, bytes_transferred);
s->async_read_some(boost::asio::buffer(read_buffer),
boost::bind(read_handler, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred, s));
}
else
{
boost::asio::execution_context& context = boost::asio::query(
s->get_executor(), boost::asio::execution::context);
services::logger logger(context, "read_handler");
std::string msg = "Read error: ";
msg += e.message();
logger.log(msg);
}
}
void connect_handler(const boost::system::error_code& e, tcp::socket* s)
{
boost::asio::execution_context& context = boost::asio::query(
s->get_executor(), boost::asio::execution::context);
services::logger logger(context, "connect_handler");
if (!e)
{
logger.log("Connection established");
s->async_read_some(boost::asio::buffer(read_buffer),
boost::bind(read_handler, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred, s));
}
else
{
std::string msg = "Unable to establish connection: ";
msg += e.message();
logger.log(msg);
}
}
int main(int argc, char* argv[])
{
try
{
if (argc != 2)
{
std::cerr << "Usage: daytime_client <host>" << std::endl;
return 1;
}
boost::asio::io_context io_context;
// Set the name of the file that all logger instances will use.
services::logger logger(io_context, "");
logger.use_file("log.txt");
// Resolve the address corresponding to the given host.
tcp::resolver resolver(io_context);
tcp::resolver::results_type endpoints =
resolver.resolve(argv[1], "daytime");
// Start an asynchronous connect.
tcp::socket socket(io_context);
boost::asio::async_connect(socket, endpoints,
boost::bind(connect_handler,
boost::asio::placeholders::error, &socket));
// Run the io_context until all operations have finished.
io_context.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}

View File

@@ -0,0 +1,24 @@
//
// logger.hpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2021 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 SERVICES_LOGGER_HPP
#define SERVICES_LOGGER_HPP
#include "basic_logger.hpp"
#include "logger_service.hpp"
namespace services {
/// Typedef for typical logger usage.
typedef basic_logger<logger_service> logger;
} // namespace services
#endif // SERVICES_LOGGER_HPP

View File

@@ -0,0 +1,11 @@
//
// logger_service.cpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 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)
//
#include "logger_service.hpp"

View File

@@ -0,0 +1,146 @@
//
// logger_service.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 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 SERVICES_LOGGER_SERVICE_HPP
#define SERVICES_LOGGER_SERVICE_HPP
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/bind/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
#include <fstream>
#include <sstream>
#include <string>
namespace services {
/// Service implementation for the logger.
class logger_service
: public boost::asio::execution_context::service
{
public:
/// The type used to identify this service in the execution context.
typedef logger_service key_type;
/// The backend implementation of a logger.
struct logger_impl
{
explicit logger_impl(const std::string& ident) : identifier(ident) {}
std::string identifier;
};
/// The type for an implementation of the logger.
typedef logger_impl* impl_type;
/// Constructor creates a thread to run a private io_context.
logger_service(boost::asio::execution_context& context)
: boost::asio::execution_context::service(context),
work_io_context_(),
work_(boost::asio::require(work_io_context_.get_executor(),
boost::asio::execution::outstanding_work.tracked)),
work_thread_(new boost::thread(
boost::bind(&boost::asio::io_context::run, &work_io_context_)))
{
}
/// Destructor shuts down the private io_context.
~logger_service()
{
/// Indicate that we have finished with the private io_context. Its
/// io_context::run() function will exit once all other work has completed.
work_ = boost::asio::any_io_executor();
if (work_thread_)
work_thread_->join();
}
/// Destroy all user-defined handler objects owned by the service.
void shutdown()
{
}
/// Return a null logger implementation.
impl_type null() const
{
return 0;
}
/// Create a new logger implementation.
void create(impl_type& impl, const std::string& identifier)
{
impl = new logger_impl(identifier);
}
/// Destroy a logger implementation.
void destroy(impl_type& impl)
{
delete impl;
impl = null();
}
/// Set the output file for the logger. The current implementation sets the
/// output file for all logger instances, and so the impl parameter is not
/// actually needed. It is retained here to illustrate how service functions
/// are typically defined.
void use_file(impl_type& /*impl*/, const std::string& file)
{
// Pass the work of opening the file to the background thread.
boost::asio::post(work_io_context_, boost::bind(
&logger_service::use_file_impl, this, file));
}
/// Log a message.
void log(impl_type& impl, const std::string& message)
{
// Format the text to be logged.
std::ostringstream os;
os << impl->identifier << ": " << message;
// Pass the work of writing to the file to the background thread.
boost::asio::post(work_io_context_, boost::bind(
&logger_service::log_impl, this, os.str()));
}
private:
/// Helper function used to open the output file from within the private
/// io_context's thread.
void use_file_impl(const std::string& file)
{
ofstream_.close();
ofstream_.clear();
ofstream_.open(file.c_str());
}
/// Helper function used to log a message from within the private io_context's
/// thread.
void log_impl(const std::string& text)
{
ofstream_ << text << std::endl;
}
/// Private io_context used for performing logging operations.
boost::asio::io_context work_io_context_;
/// A work-tracking executor giving work for the private io_context to
/// perform. If we do not give the io_context some work to do then the
/// io_context::run() function will exit immediately.
boost::asio::any_io_executor work_;
/// Thread used for running the work io_context's run loop.
boost::scoped_ptr<boost::thread> work_thread_;
/// The file to which log messages will be written.
std::ofstream ofstream_;
};
} // namespace services
#endif // SERVICES_LOGGER_SERVICE_HPP