Merge branch 'feature/update-dependencies' into develop

This commit is contained in:
Sergey Abramchuk
2017-04-09 16:12:52 +03:00
1655 changed files with 255798 additions and 34784 deletions
+7 -7
View File
@@ -1,15 +1,15 @@
PRODUCT_NAME = OpenVPNAdapter
PRODUCT_BUNDLE_IDENTIFIER = me.ss-abramchuk.openvpn-adapter
INFOPLIST_FILE = Configuration/Info-Framework.plist
MODULEMAP_FILE = OpenVPN Adapter/module.modulemap
MODULEMAP_FILE = OpenVPN Adapter/OpenVPNAdapter.modulemap
DYLIB_CURRENT_VERSION = $(CURRENT_PROJECT_VERSION)
APPLICATION_EXTENSION_API_ONLY = YES
CLANG_CXX_LANGUAGE_STANDARD = gnu++14
CLANG_CXX_LIBRARY = libc++
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/asio" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/lz4/include" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/polarssl/include" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/openvpn"
LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*] = "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/lz4/lib/sim" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/polarssl/lib/sim"
LIBRARY_SEARCH_PATHS[sdk=iphoneos*] = "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/lz4/lib/ios" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/polarssl/lib/ios"
LIBRARY_SEARCH_PATHS[sdk=macosx*] = "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/lz4/lib/macos" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/polarssl/lib/macos"
OTHER_LDFLAGS = -lmbedtls -llz4
OTHER_CPLUSPLUSFLAGS = $(OTHER_CFLAGS) -DASIO_STANDALONE -DASIO_NO_DEPRECATED -DHAVE_LZ4 -DUSE_POLARSSL -DOPENVPN_FORCE_TUN_NULL -DUSE_TUN_BUILDER
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/asio/asio/include" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/lz4/include" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/mbedtls/include" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/openvpn"
LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*] = "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/lz4/lib/sim" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/mbedtls/lib/sim"
LIBRARY_SEARCH_PATHS[sdk=iphoneos*] = "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/lz4/lib/ios" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/mbedtls/lib/ios"
LIBRARY_SEARCH_PATHS[sdk=macosx*] = "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/lz4/lib/macos" "$(PROJECT_DIR)/OpenVPN Adapter/Vendors/mbedtls/lib/macos"
OTHER_LDFLAGS = -lmbedtls -lmbedx509 -lmbedcrypto -llz4
OTHER_CPLUSPLUSFLAGS = $(OTHER_CFLAGS) -DUSE_ASIO -DASIO_STANDALONE -DASIO_NO_DEPRECATED -DHAVE_LZ4 -DUSE_MBEDTLS -DOPENVPN_FORCE_TUN_NULL -DUSE_TUN_BUILDER
GCC_WARN_64_TO_32_BIT_CONVERSION = NO
+45 -9
View File
@@ -10,8 +10,6 @@
C90BAD311E73FF6C00DEFB32 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C90BAD301E73FF6C00DEFB32 /* SystemConfiguration.framework */; };
C912BB251E7C3339002B9414 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C912BB241E7C3339002B9414 /* NetworkExtension.framework */; };
C9BB47601E71663A00F3F98C /* Umbrella-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BB475E1E71663A00F3F98C /* Umbrella-Header.h */; settings = {ATTRIBUTES = (Public, ); }; };
C9BB476C1E716AEE00F3F98C /* ovpncli.hpp in Headers */ = {isa = PBXBuildFile; fileRef = C9BB476A1E716AEE00F3F98C /* ovpncli.hpp */; };
C9BB476D1E716AEE00F3F98C /* ovpncli.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C9BB476B1E716AEE00F3F98C /* ovpncli.cpp */; };
C9BB47711E7171A100F3F98C /* OpenVPNError.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BB476F1E7171A100F3F98C /* OpenVPNError.h */; settings = {ATTRIBUTES = (Public, ); }; };
C9BB47721E7171A100F3F98C /* OpenVPNEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BB47701E7171A100F3F98C /* OpenVPNEvent.h */; settings = {ATTRIBUTES = (Public, ); }; };
C9BB47751E7171D900F3F98C /* TUNConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = C9BB47731E7171D900F3F98C /* TUNConfiguration.h */; };
@@ -26,6 +24,8 @@
C9BB47931E71821A00F3F98C /* OpenVPNAdapter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9BB475C1E71663A00F3F98C /* OpenVPNAdapter.framework */; };
C9BB479C1E71836100F3F98C /* free_openvpn_udp.ovpn in Resources */ = {isa = PBXBuildFile; fileRef = C9BB479B1E71836100F3F98C /* free_openvpn_udp.ovpn */; };
C9BB47A21E7183DB00F3F98C /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9BB47A11E7183DB00F3F98C /* Bundle.swift */; };
C9FD921A1E9A667600374FC4 /* ovpncli.hpp in Headers */ = {isa = PBXBuildFile; fileRef = C9FD92181E9A667600374FC4 /* ovpncli.hpp */; };
C9FD921B1E9A667600374FC4 /* ovpncli.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C9FD92191E9A667600374FC4 /* ovpncli.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -50,8 +50,6 @@
C912BB241E7C3339002B9414 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; };
C9BB475C1E71663A00F3F98C /* OpenVPNAdapter.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OpenVPNAdapter.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C9BB475E1E71663A00F3F98C /* Umbrella-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Umbrella-Header.h"; sourceTree = "<group>"; };
C9BB476A1E716AEE00F3F98C /* ovpncli.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ovpncli.hpp; path = Vendors/openvpn/openvpn/client/ovpncli.hpp; sourceTree = "<group>"; };
C9BB476B1E716AEE00F3F98C /* ovpncli.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ovpncli.cpp; path = Vendors/openvpn/openvpn/client/ovpncli.cpp; sourceTree = "<group>"; };
C9BB476F1E7171A100F3F98C /* OpenVPNError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = OpenVPNError.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
C9BB47701E7171A100F3F98C /* OpenVPNEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpenVPNEvent.h; sourceTree = "<group>"; };
C9BB47731E7171D900F3F98C /* TUNConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TUNConfiguration.h; sourceTree = "<group>"; };
@@ -66,6 +64,8 @@
C9BB47901E71821A00F3F98C /* OpenVPNAdapterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVPNAdapterTests.swift; sourceTree = "<group>"; };
C9BB479B1E71836100F3F98C /* free_openvpn_udp.ovpn */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = free_openvpn_udp.ovpn; sourceTree = "<group>"; };
C9BB47A11E7183DB00F3F98C /* Bundle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bundle.swift; sourceTree = "<group>"; };
C9FD92181E9A667600374FC4 /* ovpncli.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ovpncli.hpp; path = Vendors/openvpn/client/ovpncli.hpp; sourceTree = "<group>"; };
C9FD92191E9A667600374FC4 /* ovpncli.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ovpncli.cpp; path = Vendors/openvpn/client/ovpncli.cpp; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -186,8 +186,8 @@
C9BB47691E716AC500F3F98C /* OpenVPN */ = {
isa = PBXGroup;
children = (
C9BB476A1E716AEE00F3F98C /* ovpncli.hpp */,
C9BB476B1E716AEE00F3F98C /* ovpncli.cpp */,
C9FD92181E9A667600374FC4 /* ovpncli.hpp */,
C9FD92191E9A667600374FC4 /* ovpncli.cpp */,
);
name = OpenVPN;
sourceTree = "<group>";
@@ -251,12 +251,12 @@
files = (
C9BB47791E7171ED00F3F98C /* OpenVPNClient.h in Headers */,
C9BB47721E7171A100F3F98C /* OpenVPNEvent.h in Headers */,
C9BB476C1E716AEE00F3F98C /* ovpncli.hpp in Headers */,
C9BB477F1E7173C700F3F98C /* OpenVPNAdapter.h in Headers */,
C9BB47601E71663A00F3F98C /* Umbrella-Header.h in Headers */,
C9BB47811E7173C700F3F98C /* OpenVPNAdapter+Public.h in Headers */,
C9BB47711E7171A100F3F98C /* OpenVPNError.h in Headers */,
C9BB47801E7173C700F3F98C /* OpenVPNAdapter+Internal.h in Headers */,
C9FD921A1E9A667600374FC4 /* ovpncli.hpp in Headers */,
C9BB47751E7171D900F3F98C /* TUNConfiguration.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -308,7 +308,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0820;
LastUpgradeCheck = 0820;
LastUpgradeCheck = 0830;
TargetAttributes = {
C9BB475B1E71663A00F3F98C = {
CreatedOnToolsVersion = 8.2.1;
@@ -383,7 +383,7 @@
C9BB47821E7173C700F3F98C /* OpenVPNAdapter.mm in Sources */,
C9BB477A1E7171ED00F3F98C /* OpenVPNClient.mm in Sources */,
C9BB47761E7171D900F3F98C /* TUNConfiguration.m in Sources */,
C9BB476D1E716AEE00F3F98C /* ovpncli.cpp in Sources */,
C9FD921B1E9A667600374FC4 /* ovpncli.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -411,7 +411,26 @@
isa = XCBuildConfiguration;
baseConfigurationReference = C90BAD2A1E73F5AF00DEFB32 /* Project.xcconfig */;
buildSettings = {
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
ONLY_ACTIVE_ARCH = YES;
};
name = Debug;
};
@@ -419,6 +438,23 @@
isa = XCBuildConfiguration;
baseConfigurationReference = C90BAD2A1E73F5AF00DEFB32 /* Project.xcconfig */;
buildSettings = {
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
};
name = Release;
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
LastUpgradeVersion = "0830"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
+1 -1
View File
@@ -6,7 +6,7 @@
//
//
#import <openvpn/client/ovpncli.hpp>
#import <client/ovpncli.hpp>
#import "OpenVPNAdapter.h"
+1 -1
View File
@@ -6,7 +6,7 @@
//
//
#import <openvpn/client/ovpncli.hpp>
#import <client/ovpncli.hpp>
using namespace openvpn;
+3 -2
View File
@@ -1,2 +1,3 @@
Makefile
Makefile.in
/*.cpp
/*.hpp
/boost
@@ -0,0 +1,22 @@
Makefile
Makefile.in
aclocal.m4
autom4te.cache
compile
config.guess
config.log
config.status
config.sub
configure
depcomp
install-sh
missing
test-driver
/doc
/lib
/boostified
*.gz
*.bz2
*.zip
/*.cpp
/*.hpp
@@ -0,0 +1,4 @@
Copyright (c) 2003-2016 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)
@@ -0,0 +1,5 @@
See doc/index.html for information on:
- External dependencies
- Using asio
- Supported platforms
- How to build the tests and examples
@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
AUTOMAKE_OPTIONS = foreign dist-bzip2 dist-zip
SUBDIRS = include src
MAINTAINERCLEANFILES = \
$(srcdir)/aclocal.m4 \
$(srcdir)/configure \
$(srcdir)/config.guess \
$(srcdir)/config.sub \
$(srcdir)/depcomp \
$(srcdir)/install-sh \
$(srcdir)/missing \
$(srcdir)/mkinstalldirs \
$(srcdir)/Makefile.in \
asio-*.tar.gz
EXTRA_DIST = \
LICENSE_1_0.txt \
doc
+4
View File
@@ -0,0 +1,4 @@
asio version 1.11.0
Released Monday, 16 February 2015.
See doc/index.html for API documentation and a tutorial.
File diff suppressed because it is too large Load Diff
@@ -1,125 +0,0 @@
//
// async_result.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 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 ASIO_ASYNC_RESULT_HPP
#define ASIO_ASYNC_RESULT_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/handler_type.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
/// An interface for customising the behaviour of an initiating function.
/**
* This template may be specialised for user-defined handler types.
*/
template <typename Handler>
class async_result
{
public:
/// The return type of the initiating function.
typedef void type;
/// Construct an async result from a given handler.
/**
* When using a specalised async_result, the constructor has an opportunity
* to initialise some state associated with the handler, which is then
* returned from the initiating function.
*/
explicit async_result(Handler&)
{
}
/// Obtain the value to be returned from the initiating function.
type get()
{
}
};
/// Helper template to deduce the real type of a handler, capture a local copy
/// of the handler, and then create an async_result for the handler.
template <typename Handler, typename Signature>
struct async_completion
{
/// The real handler type to be used for the asynchronous operation.
typedef typename asio::handler_type<
Handler, Signature>::type handler_type;
/// Constructor.
/**
* The constructor creates the concrete handler and makes the link between
* the handler and the asynchronous result.
*/
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
explicit async_completion(
Handler& orig_handler)
: handler(static_cast<typename conditional<
is_same<Handler, handler_type>::value,
handler_type&, Handler&&>::type>(orig_handler)),
result(handler)
{
}
#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
explicit async_completion(const Handler& orig_handler)
: handler(orig_handler),
result(handler)
{
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// A copy of, or reference to, a real handler object.
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
typename conditional<
is_same<Handler, handler_type>::value,
handler_type&, handler_type>::type handler;
#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
typename asio::handler_type<Handler, Signature>::type handler;
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// The result of the asynchronous operation's initiating function.
async_result<typename asio::handler_type<
Handler, Signature>::type> result;
};
namespace detail {
template <typename Handler, typename Signature>
struct async_result_type_helper
{
typedef typename async_result<
typename handler_type<Handler, Signature>::type
>::type type;
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#if defined(GENERATING_DOCUMENTATION)
# define ASIO_INITFN_RESULT_TYPE(h, sig) \
void_or_deduced
#elif defined(_MSC_VER) && (_MSC_VER < 1500)
# define ASIO_INITFN_RESULT_TYPE(h, sig) \
typename ::asio::detail::async_result_type_helper<h, sig>::type
#else
# define ASIO_INITFN_RESULT_TYPE(h, sig) \
typename ::asio::async_result< \
typename ::asio::handler_type<h, sig>::type>::type
#endif
#endif // ASIO_ASYNC_RESULT_HPP
+55
View File
@@ -0,0 +1,55 @@
#!/bin/sh
# Helps bootstrapping the application when checked out from CVS.
# Requires GNU autoconf, GNU automake and GNU which.
#
# Copyright (C) 2004, by
#
# Carlo Wood, Run on IRC <carlo@alinoe.com>
# RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt
# Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61
#
# Do sanity checks.
# Directory check.
if [ ! -f autogen.sh ]; then
echo "Run ./autogen.sh from the directory it exists in."
exit 1
fi
AUTOMAKE=${AUTOMAKE:-automake}
ACLOCAL=${ACLOCAL:-aclocal}
AUTOCONF=${AUTOCONF:-autoconf}
($AUTOCONF --version) >/dev/null 2>/dev/null || (echo "You need GNU autoconf to install from CVS (ftp://ftp.gnu.org/gnu/autoconf/)"; exit 1) || exit 1
($AUTOMAKE --version) >/dev/null 2>/dev/null || (echo "You need GNU automake 1.7 or higher to install from CVS (ftp://ftp.gnu.org/gnu/automake/)"; exit 1) || exit 1
# Determine the version of automake.
automake_version=`$AUTOMAKE --version | head -n 1 | sed -e 's/[^12]*\([12]\.[0-9][^ ]*\).*/\1/'`
automake_major=`echo $automake_version | cut -f1 -d.`
automake_minor=`echo $automake_version | cut -f2 -d.`
automake_version_number=`expr "$automake_major" \* 1000 \+ "$automake_minor"`
# Require automake 1.7.
if expr "1007" \> "$automake_version_number" >/dev/null; then
$AUTOMAKE --version | head -n 1
echo ""
echo "Fatal error: automake 1.7 or higher is required. Please set \$AUTOMAKE"
echo "to point to a newer automake, or upgrade."
echo ""
exit 1
fi
run()
{
echo "Running $1 ..."
$1
}
# This is needed when someone just upgraded automake and this cache is still generated by an old version.
rm -rf autom4te.cache config.cache
run "$ACLOCAL"
run "$AUTOCONF"
run "$AUTOMAKE --add-missing --foreign"
@@ -1,624 +0,0 @@
//
// basic_socket_streambuf.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 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 ASIO_BASIC_SOCKET_STREAMBUF_HPP
#define ASIO_BASIC_SOCKET_STREAMBUF_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#if !defined(ASIO_NO_IOSTREAM)
#include <streambuf>
#include "asio/basic_socket.hpp"
#include "asio/detail/array.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/io_context.hpp"
#include "asio/stream_socket_service.hpp"
#if defined(ASIO_HAS_BOOST_DATE_TIME)
# include "asio/deadline_timer_service.hpp"
#else
# include "asio/steady_timer.hpp"
#endif
#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)
# include "asio/detail/variadic_templates.hpp"
// A macro that should expand to:
// template <typename T1, ..., typename Tn>
// basic_socket_streambuf* connect(T1 x1, ..., Tn xn)
// {
// init_buffers();
// this->basic_socket<Protocol ASIO_SVC_TARG>::close(ec_);
// typedef typename Protocol::resolver resolver_type;
// resolver_type resolver(detail::socket_streambuf_base::io_context_);
// connect_to_endpoints(
// resolver.resolve(x1, ..., xn, ec_));
// return !ec_ ? this : 0;
// }
// This macro should only persist within this file.
# define ASIO_PRIVATE_CONNECT_DEF(n) \
template <ASIO_VARIADIC_TPARAMS(n)> \
basic_socket_streambuf* connect(ASIO_VARIADIC_BYVAL_PARAMS(n)) \
{ \
init_buffers(); \
this->basic_socket<Protocol ASIO_SVC_TARG>::close(ec_); \
typedef typename Protocol::resolver resolver_type; \
resolver_type resolver(detail::socket_streambuf_base::io_context_); \
connect_to_endpoints( \
resolver.resolve(ASIO_VARIADIC_BYVAL_ARGS(n), ec_)); \
return !ec_ ? this : 0; \
} \
/**/
#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)
#if !defined(ASIO_ENABLE_OLD_SERVICES)
# define ASIO_SVC_T1 detail::deadline_timer_service<traits_helper>
#endif // !defined(ASIO_ENABLE_OLD_SERVICES)
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
// A separate base class is used to ensure that the io_context is initialised
// prior to the basic_socket_streambuf's basic_socket base class.
class socket_streambuf_base
{
protected:
io_context io_context_;
};
} // namespace detail
/// Iostream streambuf for a socket.
template <typename Protocol
ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
#if defined(ASIO_HAS_BOOST_DATE_TIME) \
|| defined(GENERATING_DOCUMENTATION)
typename Time = boost::posix_time::ptime,
typename TimeTraits = asio::time_traits<Time>
ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Time, TimeTraits>)>
#else
typename Time = steady_timer::clock_type,
typename TimeTraits = steady_timer::traits_type
ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
#endif
class basic_socket_streambuf
: public std::streambuf,
private detail::socket_streambuf_base,
public basic_socket<Protocol ASIO_SVC_TARG>
{
private:
// These typedefs are intended keep this class's implementation independent
// of whether it's using Boost.DateTime, Boost.Chrono or std::chrono.
#if defined(ASIO_HAS_BOOST_DATE_TIME)
typedef TimeTraits traits_helper;
#else
typedef detail::chrono_time_traits<Time, TimeTraits> traits_helper;
#endif
public:
/// The endpoint type.
typedef typename Protocol::endpoint endpoint_type;
#if defined(GENERATING_DOCUMENTATION)
/// (Deprecated: Use time_point.) The time type.
typedef typename TimeTraits::time_type time_type;
/// The time type.
typedef typename TimeTraits::time_point time_point;
/// (Deprecated: Use duration.) The duration type.
typedef typename TimeTraits::duration_type duration_type;
/// The duration type.
typedef typename TimeTraits::duration duration;
#else
# if !defined(ASIO_NO_DEPRECATED)
typedef typename traits_helper::time_type time_type;
typedef typename traits_helper::duration_type duration_type;
# endif // !defined(ASIO_NO_DEPRECATED)
typedef typename traits_helper::time_type time_point;
typedef typename traits_helper::duration_type duration;
#endif
/// Construct a basic_socket_streambuf without establishing a connection.
basic_socket_streambuf()
: basic_socket<Protocol ASIO_SVC_TARG>(
this->detail::socket_streambuf_base::io_context_),
unbuffered_(false),
timer_service_(0),
timer_state_(no_timer)
{
init_buffers();
}
/// Destructor flushes buffered data.
virtual ~basic_socket_streambuf()
{
if (pptr() != pbase())
overflow(traits_type::eof());
destroy_timer();
}
/// Establish a connection.
/**
* This function establishes a connection to the specified endpoint.
*
* @return \c this if a connection was successfully established, a null
* pointer otherwise.
*/
basic_socket_streambuf* connect(const endpoint_type& endpoint)
{
init_buffers();
this->basic_socket<Protocol ASIO_SVC_TARG>::close(ec_);
if (timer_state_ == timer_has_expired)
{
ec_ = asio::error::operation_aborted;
return 0;
}
io_handler handler = { this };
this->basic_socket<Protocol ASIO_SVC_TARG>::async_connect(
endpoint, handler);
ec_ = asio::error::would_block;
this->get_service().get_io_context().restart();
do this->get_service().get_io_context().run_one();
while (ec_ == asio::error::would_block);
return !ec_ ? this : 0;
}
#if defined(GENERATING_DOCUMENTATION)
/// Establish a connection.
/**
* This function automatically establishes a connection based on the supplied
* resolver query parameters. The arguments are used to construct a resolver
* query object.
*
* @return \c this if a connection was successfully established, a null
* pointer otherwise.
*/
template <typename T1, ..., typename TN>
basic_socket_streambuf* connect(T1 t1, ..., TN tn);
#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)
template <typename... T>
basic_socket_streambuf* connect(T... x)
{
init_buffers();
this->basic_socket<Protocol ASIO_SVC_TARG>::close(ec_);
typedef typename Protocol::resolver resolver_type;
resolver_type resolver(detail::socket_streambuf_base::io_context_);
connect_to_endpoints(resolver.resolve(x..., ec_));
return !ec_ ? this : 0;
}
#else
ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CONNECT_DEF)
#endif
/// Close the connection.
/**
* @return \c this if a connection was successfully established, a null
* pointer otherwise.
*/
basic_socket_streambuf* close()
{
sync();
this->basic_socket<Protocol ASIO_SVC_TARG>::close(ec_);
if (!ec_)
init_buffers();
return !ec_ ? this : 0;
}
/// Get the last error associated with the stream buffer.
/**
* @return An \c error_code corresponding to the last error from the stream
* buffer.
*/
const asio::error_code& puberror() const
{
return error();
}
#if !defined(ASIO_NO_DEPRECATED)
/// (Deprecated: Use expiry().) Get the stream buffer's expiry time as an
/// absolute time.
/**
* @return An absolute time value representing the stream buffer's expiry
* time.
*/
time_point expires_at() const
{
return timer_service_
? timer_service_->expires_at(timer_implementation_)
: time_point();
}
#endif // !defined(ASIO_NO_DEPRECATED)
/// Get the stream buffer's expiry time as an absolute time.
/**
* @return An absolute time value representing the stream buffer's expiry
* time.
*/
time_point expiry() const
{
return timer_service_
#if defined(ASIO_HAS_BOOST_DATE_TIME)
? timer_service_->expires_at(timer_implementation_)
#else // defined(ASIO_HAS_BOOST_DATE_TIME)
? timer_service_->expiry(timer_implementation_)
#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
: time_point();
}
/// Set the stream buffer's expiry time as an absolute time.
/**
* This function sets the expiry time associated with the stream. Stream
* operations performed after this time (where the operations cannot be
* completed using the internal buffers) will fail with the error
* asio::error::operation_aborted.
*
* @param expiry_time The expiry time to be used for the stream.
*/
void expires_at(const time_point& expiry_time)
{
construct_timer();
asio::error_code ec;
timer_service_->expires_at(timer_implementation_, expiry_time, ec);
asio::detail::throw_error(ec, "expires_at");
start_timer();
}
/// Set the stream buffer's expiry time relative to now.
/**
* This function sets the expiry time associated with the stream. Stream
* operations performed after this time (where the operations cannot be
* completed using the internal buffers) will fail with the error
* asio::error::operation_aborted.
*
* @param expiry_time The expiry time to be used for the timer.
*/
void expires_after(const duration& expiry_time)
{
construct_timer();
asio::error_code ec;
#if defined(ASIO_HAS_BOOST_DATE_TIME)
timer_service_->expires_from_now(timer_implementation_, expiry_time, ec);
#else // defined(ASIO_HAS_BOOST_DATE_TIME)
timer_service_->expires_after(timer_implementation_, expiry_time, ec);
#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
asio::detail::throw_error(ec, "expires_after");
start_timer();
}
#if !defined(ASIO_NO_DEPRECATED)
/// (Deprecated: Use expiry().) Get the stream buffer's expiry time relative
/// to now.
/**
* @return A relative time value representing the stream buffer's expiry time.
*/
duration expires_from_now() const
{
return traits_helper::subtract(expires_at(), traits_helper::now());
}
/// (Deprecated: Use expires_after().) Set the stream buffer's expiry time
/// relative to now.
/**
* This function sets the expiry time associated with the stream. Stream
* operations performed after this time (where the operations cannot be
* completed using the internal buffers) will fail with the error
* asio::error::operation_aborted.
*
* @param expiry_time The expiry time to be used for the timer.
*/
void expires_from_now(const duration& expiry_time)
{
construct_timer();
asio::error_code ec;
timer_service_->expires_from_now(timer_implementation_, expiry_time, ec);
asio::detail::throw_error(ec, "expires_from_now");
start_timer();
}
#endif // !defined(ASIO_NO_DEPRECATED)
protected:
int_type underflow()
{
if (gptr() == egptr())
{
if (timer_state_ == timer_has_expired)
{
ec_ = asio::error::operation_aborted;
return traits_type::eof();
}
io_handler handler = { this };
this->get_service().async_receive(this->get_implementation(),
asio::buffer(asio::buffer(get_buffer_) + putback_max),
0, handler);
ec_ = asio::error::would_block;
this->get_service().get_io_context().restart();
do this->get_service().get_io_context().run_one();
while (ec_ == asio::error::would_block);
if (ec_)
return traits_type::eof();
setg(&get_buffer_[0], &get_buffer_[0] + putback_max,
&get_buffer_[0] + putback_max + bytes_transferred_);
return traits_type::to_int_type(*gptr());
}
else
{
return traits_type::eof();
}
}
int_type overflow(int_type c)
{
if (unbuffered_)
{
if (traits_type::eq_int_type(c, traits_type::eof()))
{
// Nothing to do.
return traits_type::not_eof(c);
}
else
{
if (timer_state_ == timer_has_expired)
{
ec_ = asio::error::operation_aborted;
return traits_type::eof();
}
// Send the single character immediately.
char_type ch = traits_type::to_char_type(c);
io_handler handler = { this };
this->get_service().async_send(this->get_implementation(),
asio::buffer(&ch, sizeof(char_type)), 0, handler);
ec_ = asio::error::would_block;
this->get_service().get_io_context().restart();
do this->get_service().get_io_context().run_one();
while (ec_ == asio::error::would_block);
if (ec_)
return traits_type::eof();
return c;
}
}
else
{
// Send all data in the output buffer.
asio::const_buffer buffer =
asio::buffer(pbase(), pptr() - pbase());
while (buffer.size() > 0)
{
if (timer_state_ == timer_has_expired)
{
ec_ = asio::error::operation_aborted;
return traits_type::eof();
}
io_handler handler = { this };
this->get_service().async_send(this->get_implementation(),
asio::buffer(buffer), 0, handler);
ec_ = asio::error::would_block;
this->get_service().get_io_context().restart();
do this->get_service().get_io_context().run_one();
while (ec_ == asio::error::would_block);
if (ec_)
return traits_type::eof();
buffer = buffer + bytes_transferred_;
}
setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());
// If the new character is eof then our work here is done.
if (traits_type::eq_int_type(c, traits_type::eof()))
return traits_type::not_eof(c);
// Add the new character to the output buffer.
*pptr() = traits_type::to_char_type(c);
pbump(1);
return c;
}
}
int sync()
{
return overflow(traits_type::eof());
}
std::streambuf* setbuf(char_type* s, std::streamsize n)
{
if (pptr() == pbase() && s == 0 && n == 0)
{
unbuffered_ = true;
setp(0, 0);
return this;
}
return 0;
}
/// Get the last error associated with the stream buffer.
/**
* @return An \c error_code corresponding to the last error from the stream
* buffer.
*/
virtual const asio::error_code& error() const
{
return ec_;
}
private:
void init_buffers()
{
setg(&get_buffer_[0],
&get_buffer_[0] + putback_max,
&get_buffer_[0] + putback_max);
if (unbuffered_)
setp(0, 0);
else
setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());
}
template <typename EndpointSequence>
void connect_to_endpoints(const EndpointSequence& endpoints)
{
if (!ec_)
{
typename EndpointSequence::iterator i = endpoints.begin();
typename EndpointSequence::iterator end = endpoints.end();
ec_ = asio::error::host_not_found;
while (ec_ && i != end)
{
this->basic_socket<Protocol ASIO_SVC_TARG>::close(ec_);
if (timer_state_ == timer_has_expired)
{
ec_ = asio::error::operation_aborted;
return;
}
io_handler handler = { this };
this->basic_socket<Protocol ASIO_SVC_TARG>::async_connect(
*i, handler);
ec_ = asio::error::would_block;
this->get_service().get_io_context().restart();
do this->get_service().get_io_context().run_one();
while (ec_ == asio::error::would_block);
++i;
}
}
}
struct io_handler;
friend struct io_handler;
struct io_handler
{
basic_socket_streambuf* this_;
void operator()(const asio::error_code& ec,
std::size_t bytes_transferred = 0)
{
this_->ec_ = ec;
this_->bytes_transferred_ = bytes_transferred;
}
};
struct timer_handler;
friend struct timer_handler;
struct timer_handler
{
basic_socket_streambuf* this_;
void operator()(const asio::error_code&)
{
time_point now = traits_helper::now();
#if defined(ASIO_HAS_BOOST_DATE_TIME)
time_point expiry_time = this_->timer_service_->expires_at(
this_->timer_implementation_);
#else // defined(ASIO_HAS_BOOST_DATE_TIME)
time_point expiry_time = this_->timer_service_->expiry(
this_->timer_implementation_);
#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
if (traits_helper::less_than(now, expiry_time))
{
this_->timer_state_ = timer_is_pending;
this_->timer_service_->async_wait(this_->timer_implementation_, *this);
}
else
{
this_->timer_state_ = timer_has_expired;
asio::error_code ec;
this_->basic_socket<Protocol ASIO_SVC_TARG>::close(ec);
}
}
};
void construct_timer()
{
if (timer_service_ == 0)
{
ASIO_SVC_T1& timer_service = use_service<ASIO_SVC_T1>(
detail::socket_streambuf_base::io_context_);
timer_service.construct(timer_implementation_);
timer_service_ = &timer_service;
}
}
void destroy_timer()
{
if (timer_service_)
timer_service_->destroy(timer_implementation_);
}
void start_timer()
{
if (timer_state_ != timer_is_pending)
{
timer_handler handler = { this };
handler(asio::error_code());
}
}
enum { putback_max = 8 };
enum { buffer_size = 512 };
asio::detail::array<char, buffer_size> get_buffer_;
asio::detail::array<char, buffer_size> put_buffer_;
bool unbuffered_;
asio::error_code ec_;
std::size_t bytes_transferred_;
ASIO_SVC_T1* timer_service_;
typename ASIO_SVC_T1::implementation_type timer_implementation_;
enum state { no_timer, timer_is_pending, timer_has_expired } timer_state_;
};
} // namespace asio
#include "asio/detail/pop_options.hpp"
#if !defined(ASIO_ENABLE_OLD_SERVICES)
# undef ASIO_SVC_T1
#endif // !defined(ASIO_ENABLE_OLD_SERVICES)
#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)
# undef ASIO_PRIVATE_CONNECT_DEF
#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)
#endif // !defined(ASIO_NO_IOSTREAM)
#endif // ASIO_BASIC_SOCKET_STREAMBUF_HPP
File diff suppressed because it is too large Load Diff
+583
View File
@@ -0,0 +1,583 @@
#!/usr/bin/perl -w
use strict;
use File::Path;
our $boost_dir = "boostified";
sub print_line
{
my ($output, $line, $from, $lineno) = @_;
# Warn if the resulting line is >80 characters wide.
if (length($line) > 80)
{
if ($from =~ /\.[chi]pp$/)
{
print("Warning: $from:$lineno: output >80 characters wide.\n");
}
}
# Write the output.
print($output $line . "\n");
}
sub source_contains_asio_thread_usage
{
my ($from) = @_;
# Open the input file.
open(my $input, "<$from") or die("Can't open $from for reading");
# Check file for use of asio::thread.
while (my $line = <$input>)
{
chomp($line);
if ($line =~ /asio::thread/)
{
close($input);
return 1;
}
elsif ($line =~ /^ *thread /)
{
close($input);
return 1;
}
}
close($input);
return 0;
}
sub source_contains_asio_include
{
my ($from) = @_;
# Open the input file.
open(my $input, "<$from") or die("Can't open $from for reading");
# Check file for inclusion of asio.hpp.
while (my $line = <$input>)
{
chomp($line);
if ($line =~ /# *include [<"]asio\.hpp[>"]/)
{
close($input);
return 1;
}
}
close($input);
return 0;
}
sub copy_source_file
{
my ($from, $to) = @_;
# Ensure the output directory exists.
my $dir = $to;
$dir =~ s/[^\/]*$//;
mkpath($dir);
# First determine whether the file makes any use of asio::thread.
my $uses_asio_thread = source_contains_asio_thread_usage($from);
my $includes_asio = source_contains_asio_include($from);
my $is_asio_hpp = 0;
$is_asio_hpp = 1 if ($from =~ /asio\.hpp/);
my $needs_doc_link = 0;
$needs_doc_link = 1 if ($is_asio_hpp);
my $is_error_hpp = 0;
$is_error_hpp = 1 if ($from =~ /asio\/error\.hpp/);
my $is_qbk = 0;
$is_qbk = 1 if ($from =~ /.qbk$/);
my $is_xsl = 0;
$is_xsl = 1 if ($from =~ /.xsl$/);
my $is_test = 0;
$is_test = 1 if ($from =~ /tests\/unit/);
# Open the files.
open(my $input, "<$from") or die("Can't open $from for reading");
open(my $output, ">$to") or die("Can't open $to for writing");
# Copy the content.
my $lineno = 1;
while (my $line = <$input>)
{
chomp($line);
# Unconditional replacements.
$line =~ s/[\\@]ref boost_bind/boost::bind()/g;
if ($from =~ /.*\.txt$/)
{
$line =~ s/[\\@]ref async_read/boost::asio::async_read()/g;
$line =~ s/[\\@]ref async_write/boost::asio::async_write()/g;
}
if ($line =~ /asio_detail_posix_thread_function/)
{
$line =~ s/asio_detail_posix_thread_function/boost_asio_detail_posix_thread_function/g;
}
if ($line =~ /asio_signal_handler/)
{
$line =~ s/asio_signal_handler/boost_asio_signal_handler/g;
}
if ($line =~ /ASIO_/ && !($line =~ /BOOST_ASIO_/))
{
$line =~ s/ASIO_/BOOST_ASIO_/g;
}
# Extra replacements for quickbook and XSL source only.
if ($is_qbk || $is_xsl)
{
$line =~ s/asio\.examples/boost_asio.examples/g;
$line =~ s/asio\.history/boost_asio.history/g;
$line =~ s/asio\.index/boost_asio.index/g;
$line =~ s/asio\.overview/boost_asio.overview/g;
$line =~ s/asio\.reference/boost_asio.reference/g;
$line =~ s/asio\.tutorial/boost_asio.tutorial/g;
$line =~ s/asio\.using/boost_asio.using/g;
$line =~ s/Asio/Boost.Asio/g;
$line =~ s/changes made in each release/changes made in each Boost release/g;
$line =~ s/\[\$/[\$boost_asio\//g;
$line =~ s/\[@\.\.\/src\/examples/[\@boost_asio\/example/g;
$line =~ s/include\/asio/boost\/asio/g;
$line =~ s/\^asio/^boost\/asio/g;
$line =~ s/namespaceasio/namespaceboost_1_1asio/g;
$line =~ s/ \(\[\@examples\/diffs.*$//;
}
# Conditional replacements.
if ($line =~ /^( *)namespace asio {/)
{
if ($is_qbk)
{
print_line($output, $1 . "namespace boost { namespace asio {", $from, $lineno);
}
else
{
print_line($output, $1 . "namespace boost {", $from, $lineno);
print_line($output, $line, $from, $lineno);
}
}
elsif ($line =~ /^( *)} \/\/ namespace asio$/)
{
if ($is_qbk)
{
print_line($output, $1 . "} } // namespace boost::asio", $from, $lineno);
}
else
{
print_line($output, $line, $from, $lineno);
print_line($output, $1 . "} // namespace boost", $from, $lineno);
}
}
elsif ($line =~ /^(# *include )[<"](asio\.hpp)[>"]$/)
{
print_line($output, $1 . "<boost/" . $2 . ">", $from, $lineno);
if ($uses_asio_thread)
{
print_line($output, $1 . "<boost/thread/thread.hpp>", $from, $lineno) if (!$is_test);
$uses_asio_thread = 0;
}
}
elsif ($line =~ /^(# *include )[<"]boost\/.*[>"].*$/)
{
if (!$includes_asio && $uses_asio_thread)
{
print_line($output, $1 . "<boost/thread/thread.hpp>", $from, $lineno) if (!$is_test);
$uses_asio_thread = 0;
}
print_line($output, $line, $from, $lineno);
}
elsif ($line =~ /^(# *include )[<"]asio\/thread\.hpp[>"]/)
{
if ($is_test)
{
print_line($output, $1 . "<boost/asio/detail/thread.hpp>", $from, $lineno);
}
else
{
# Line is removed.
}
}
elsif ($line =~ /(# *include )[<"]asio\/error_code\.hpp[>"]/)
{
if ($is_asio_hpp)
{
# Line is removed.
}
else
{
print_line($output, $1 . "<boost/cerrno.hpp>", $from, $lineno) if ($is_error_hpp);
print_line($output, $1 . "<boost/system/error_code.hpp>", $from, $lineno);
}
}
elsif ($line =~ /# *include [<"]asio\/impl\/error_code\.[hi]pp[>"]/)
{
# Line is removed.
}
elsif ($line =~ /(# *include )[<"]asio\/system_error\.hpp[>"]/)
{
if ($is_asio_hpp)
{
# Line is removed.
}
else
{
print_line($output, $1 . "<boost/system/system_error.hpp>", $from, $lineno);
}
}
elsif ($line =~ /(^.*# *include )[<"](asio\/[^>"]*)[>"](.*)$/)
{
print_line($output, $1 . "<boost/" . $2 . ">" . $3, $from, $lineno);
}
elsif ($line =~ /#.*defined\(.*ASIO_HAS_STD_SYSTEM_ERROR\)$/)
{
# Line is removed.
}
elsif ($line =~ /asio::thread/)
{
if ($is_test)
{
$line =~ s/asio::thread/asio::detail::thread/g;
}
else
{
$line =~ s/asio::thread/boost::thread/g;
}
if (!($line =~ /boost::asio::/))
{
$line =~ s/asio::/boost::asio::/g;
}
print_line($output, $line, $from, $lineno);
}
elsif ($line =~ /^( *)thread( .*)$/ && !$is_qbk)
{
if ($is_test)
{
print_line($output, $1 . "boost::asio::detail::thread" . $2, $from, $lineno);
}
else
{
print_line($output, $1 . "boost::thread" . $2, $from, $lineno);
}
}
elsif ($line =~ /namespace std {/)
{
print_line($output, "namespace boost {", $from, $lineno);
print_line($output, "namespace system {", $from, $lineno);
}
elsif ($line =~ /std::error_code/)
{
$line =~ s/std::error_code/boost::system::error_code/g;
print_line($output, $line, $from, $lineno);
}
elsif ($line =~ /} \/\/ namespace std/)
{
print_line($output, "} // namespace system", $from, $lineno);
print_line($output, "} // namespace boost", $from, $lineno);
}
elsif ($line =~ /asio::/ && !($line =~ /boost::asio::/))
{
$line =~ s/asio::error_code/boost::system::error_code/g;
$line =~ s/asio::error_category/boost::system::error_category/g;
$line =~ s/asio::system_category/boost::system::system_category/g;
$line =~ s/asio::system_error/boost::system::system_error/g;
$line =~ s/asio::/boost::asio::/g if !$is_xsl;
print_line($output, $line, $from, $lineno);
}
elsif ($line =~ /using namespace asio/)
{
$line =~ s/using namespace asio/using namespace boost::asio/g;
print_line($output, $line, $from, $lineno);
}
elsif ($line =~ /asio_handler_alloc_helpers/)
{
$line =~ s/asio_handler_alloc_helpers/boost_asio_handler_alloc_helpers/g;
print_line($output, $line, $from, $lineno);
}
elsif ($line =~ /asio_handler_cont_helpers/)
{
$line =~ s/asio_handler_cont_helpers/boost_asio_handler_cont_helpers/g;
print_line($output, $line, $from, $lineno);
}
elsif ($line =~ /asio_handler_invoke_helpers/)
{
$line =~ s/asio_handler_invoke_helpers/boost_asio_handler_invoke_helpers/g;
print_line($output, $line, $from, $lineno);
}
elsif ($line =~ /[\\@]ref boost_bind/)
{
$line =~ s/[\\@]ref boost_bind/boost::bind()/g;
print_line($output, $line, $from, $lineno);
}
elsif ($line =~ /( *)\[category template\]/)
{
print_line($output, $1 . "[authors [Kohlhoff, Christopher]]", $from, $lineno);
print_line($output, $line, $from, $lineno);
}
elsif ($line =~ /boostify: non-boost docs start here/)
{
while ($line = <$input>)
{
last if $line =~ /boostify: non-boost docs end here/;
}
}
elsif ($line =~ /boostify: non-boost code starts here/)
{
while ($line = <$input>)
{
last if $line =~ /boostify: non-boost code ends here/;
}
}
elsif ($line =~ /^$/ && $needs_doc_link)
{
$needs_doc_link = 0;
print_line($output, "// See www.boost.org/libs/asio for documentation.", $from, $lineno);
print_line($output, "//", $from, $lineno);
print_line($output, $line, $from, $lineno);
}
else
{
print_line($output, $line, $from, $lineno);
}
++$lineno;
}
# Ok, we're done.
close($input);
close($output);
}
sub copy_include_files
{
my @dirs = (
"include",
"include/asio",
"include/asio/detail",
"include/asio/detail/impl",
"include/asio/generic",
"include/asio/generic/detail",
"include/asio/generic/detail/impl",
"include/asio/impl",
"include/asio/ip",
"include/asio/ip/impl",
"include/asio/ip/detail",
"include/asio/ip/detail/impl",
"include/asio/local",
"include/asio/local/detail",
"include/asio/local/detail/impl",
"include/asio/posix",
"include/asio/ssl",
"include/asio/ssl/detail",
"include/asio/ssl/detail/impl",
"include/asio/ssl/impl",
"include/asio/ssl/old",
"include/asio/ssl/old/detail",
"include/asio/windows");
foreach my $dir (@dirs)
{
our $boost_dir;
my @files = ( glob("$dir/*.hpp"), glob("$dir/*.ipp"), glob("$dir/*cpp") );
foreach my $file (@files)
{
if ($file ne "include/asio/thread.hpp"
and $file ne "include/asio/error_code.hpp"
and $file ne "include/asio/system_error.hpp"
and $file ne "include/asio/impl/error_code.hpp"
and $file ne "include/asio/impl/error_code.ipp")
{
my $from = $file;
my $to = $file;
$to =~ s/^include\//$boost_dir\/libs\/asio\/include\/boost\//;
copy_source_file($from, $to);
}
}
}
}
sub create_lib_directory
{
my @dirs = (
"doc",
"example",
"test");
our $boost_dir;
foreach my $dir (@dirs)
{
mkpath("$boost_dir/libs/asio/$dir");
}
}
sub copy_unit_tests
{
my @dirs = (
"src/tests/unit",
"src/tests/unit/archetypes",
"src/tests/unit/generic",
"src/tests/unit/ip",
"src/tests/unit/local",
"src/tests/unit/posix",
"src/tests/unit/ssl",
"src/tests/unit/windows");
our $boost_dir;
foreach my $dir (@dirs)
{
my @files = ( glob("$dir/*.*pp"), glob("$dir/Jamfile*") );
foreach my $file (@files)
{
if ($file ne "src/tests/unit/thread.cpp"
and $file ne "src/tests/unit/error_handler.cpp"
and $file ne "src/tests/unit/unit_test.cpp")
{
my $from = $file;
my $to = $file;
$to =~ s/^src\/tests\/unit\//$boost_dir\/libs\/asio\/test\//;
copy_source_file($from, $to);
}
}
}
}
sub copy_latency_tests
{
my @dirs = (
"src/tests/latency");
our $boost_dir;
foreach my $dir (@dirs)
{
my @files = ( glob("$dir/*.*pp"), glob("$dir/Jamfile*") );
foreach my $file (@files)
{
my $from = $file;
my $to = $file;
$to =~ s/^src\/tests\/latency\//$boost_dir\/libs\/asio\/test\/latency\//;
copy_source_file($from, $to);
}
}
}
sub copy_examples
{
my @dirs = (
"src/examples/cpp03/allocation",
"src/examples/cpp03/buffers",
"src/examples/cpp03/chat",
"src/examples/cpp03/echo",
"src/examples/cpp03/fork",
"src/examples/cpp03/http/client",
"src/examples/cpp03/http/doc_root",
"src/examples/cpp03/http/server",
"src/examples/cpp03/http/server2",
"src/examples/cpp03/http/server3",
"src/examples/cpp03/http/server4",
"src/examples/cpp03/icmp",
"src/examples/cpp03/invocation",
"src/examples/cpp03/iostreams",
"src/examples/cpp03/local",
"src/examples/cpp03/multicast",
"src/examples/cpp03/nonblocking",
"src/examples/cpp03/porthopper",
"src/examples/cpp03/serialization",
"src/examples/cpp03/services",
"src/examples/cpp03/socks4",
"src/examples/cpp03/spawn",
"src/examples/cpp03/ssl",
"src/examples/cpp03/timeouts",
"src/examples/cpp03/timers",
"src/examples/cpp03/tutorial",
"src/examples/cpp03/tutorial/daytime1",
"src/examples/cpp03/tutorial/daytime2",
"src/examples/cpp03/tutorial/daytime3",
"src/examples/cpp03/tutorial/daytime4",
"src/examples/cpp03/tutorial/daytime5",
"src/examples/cpp03/tutorial/daytime6",
"src/examples/cpp03/tutorial/daytime7",
"src/examples/cpp03/tutorial/timer1",
"src/examples/cpp03/tutorial/timer2",
"src/examples/cpp03/tutorial/timer3",
"src/examples/cpp03/tutorial/timer4",
"src/examples/cpp03/tutorial/timer5",
"src/examples/cpp03/windows",
"src/examples/cpp11/allocation",
"src/examples/cpp11/buffers",
"src/examples/cpp11/chat",
"src/examples/cpp11/echo",
"src/examples/cpp11/executors",
"src/examples/cpp11/futures",
"src/examples/cpp11/http/server",
"src/examples/cpp11/iostreams",
"src/examples/cpp11/spawn",
"src/examples/cpp14/executors");
our $boost_dir;
foreach my $dir (@dirs)
{
my @files = (
glob("$dir/*.*pp"),
glob("$dir/*.html"),
glob("$dir/Jamfile*"),
glob("$dir/*.pem"),
glob("$dir/README*"),
glob("$dir/*.txt"));
foreach my $file (@files)
{
my $from = $file;
my $to = $file;
$to =~ s/^src\/examples\//$boost_dir\/libs\/asio\/example\//;
copy_source_file($from, $to);
}
}
}
sub copy_doc
{
our $boost_dir;
my @files = (
"src/doc/asio.qbk",
"src/doc/examples.qbk",
"src/doc/reference.xsl",
"src/doc/tutorial.xsl",
glob("src/doc/overview/*.qbk"),
glob("src/doc/requirements/*.qbk"));
foreach my $file (@files)
{
my $from = $file;
my $to = $file;
$to =~ s/^src\/doc\//$boost_dir\/libs\/asio\/doc\//;
copy_source_file($from, $to);
}
}
sub copy_tools
{
our $boost_dir;
my @files = (
glob("src/tools/*.pl"));
foreach my $file (@files)
{
my $from = $file;
my $to = $file;
$to =~ s/^src\/tools\//$boost_dir\/libs\/asio\/tools\//;
copy_source_file($from, $to);
}
}
copy_include_files();
create_lib_directory();
copy_unit_tests();
copy_latency_tests();
copy_examples();
copy_doc();
copy_tools();
@@ -0,0 +1,272 @@
AC_INIT(asio, [1.11.0])
AC_CONFIG_SRCDIR(include/asio.hpp)
AM_MAINTAINER_MODE
AM_INIT_AUTOMAKE([tar-ustar])
AC_CANONICAL_HOST
AM_PROG_CC_C_O
AC_PROG_CXX
AC_LANG(C++)
AC_PROG_RANLIB
AC_DEFINE(_REENTRANT, [1], [Define this])
AC_ARG_WITH(boost,
AC_HELP_STRING([--with-boost=DIR],[location of boost distribution]),
[
if test "${withval}" = no; then
STANDALONE="yes"
else
CPPFLAGS="$CPPFLAGS -I${withval}"
LIBS="$LIBS -L${withval}/stage/lib"
fi
],
[
BOOSTDIR="`pwd`/../boost_1_55_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
LIBS="$LIBS -L${BOOSTDIR}/stage/lib"
else
BOOSTDIR="`pwd`/../boost_1_54_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
LIBS="$LIBS -L${BOOSTDIR}/stage/lib"
else
BOOSTDIR="`pwd`/../boost_1_53_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_52_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_51_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_50_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_49_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_48_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_47_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_46_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_46_1"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_45_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_44_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_43_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_42_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_41_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_40_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_39_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_38_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_37_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_36_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_35_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_34_1"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_34_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_33_1"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
else
BOOSTDIR="`pwd`/../boost_1_33_0"
if test -d "${BOOSTDIR}"; then
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR}"
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
])
AC_ARG_ENABLE(separate-compilation,
[ --enable-separate-compilation separate compilation of asio source],
[
SEPARATE_COMPILATION=yes
])
AC_ARG_ENABLE(boost-coroutine,
[ --enable-boost-coroutine use Boost.Coroutine to implement stackful coroutines],
[
HAVE_BOOST_COROUTINE=yes
])
if test "$STANDALONE" != yes; then
AC_CHECK_HEADER([boost/noncopyable.hpp],,
[
echo "Can't find boost headers. Please check the location of the boost"
echo "distribution and rerun configure using the --with-boost=DIR option."
exit 1
],[])
fi
AC_ARG_WITH(openssl,
AC_HELP_STRING([--with-openssl=DIR],[location of openssl]),
[
CPPFLAGS="$CPPFLAGS -I${withval}"
],[])
AC_CHECK_HEADER([openssl/ssl.h],,
[
OPENSSL_FOUND=no
],[])
if test x$OPENSSL_FOUND != xno; then
LIBS="$LIBS -lssl -lcrypto"
fi
AM_CONDITIONAL(HAVE_OPENSSL,test x$OPENSSL_FOUND != xno)
WINDOWS=no
case $host in
*-*-linux*)
CXXFLAGS="$CXXFLAGS -pthread"
LDFLAGS="$LDFLAGS -pthread"
;;
*-*-solaris*)
if test "$GXX" = yes; then
CXXFLAGS="$CXXFLAGS -D_PTHREADS"
else
# We'll assume Sun's CC.
CXXFLAGS="$CXXFLAGS -mt"
fi
LIBS="$LIBS -lsocket -lnsl -lpthread"
;;
*-*-mingw32*)
CXXFLAGS="$CXXFLAGS -mthreads"
LDFLAGS="$LDFLAGS -mthreads"
LIBS="$LIBS -lws2_32 -lmswsock"
WINDOWS=yes
;;
*-*-mingw64*)
CXXFLAGS="$CXXFLAGS -mthreads"
LDFLAGS="$LDFLAGS -mthreads"
LIBS="$LIBS -lws2_32 -lmswsock"
WINDOWS=yes
;;
*-pc-cygwin*)
CXXFLAGS="$CXXFLAGS -D__USE_W32_SOCKETS -D_WIN32_WINNT=0x0501"
LIBS="$LIBS -lws2_32 -lmswsock"
WINDOWS=yes
;;
*-apple-darwin*)
CXXFLAGS="$CXXFLAGS"
LDFLAGS="$LDFLAGS"
;;
*-*-freebsd*)
CXXFLAGS="$CXXFLAGS -pthread"
LDFLAGS="$LDFLAGS -pthread"
;;
*-*-netbsd*)
CXXFLAGS="$CXXFLAGS -pthread"
LDFLAGS="$LDFLAGS -pthread"
;;
esac
if test "$GXX" = yes; then
CXXFLAGS="$CXXFLAGS -ftemplate-depth-256"
if test "$STANDALONE" = yes; then
CPPFLAGS="-std=c++0x $CPPFLAGS"
fi
fi
if test "$STANDALONE" = yes; then
CPPFLAGS="$CPPFLAGS -DASIO_STANDALONE"
fi
if test "$SEPARATE_COMPILATION" = yes; then
CPPFLAGS="$CPPFLAGS -DASIO_SEPARATE_COMPILATION"
fi
AM_CONDITIONAL(STANDALONE,test x$STANDALONE = xyes)
AM_CONDITIONAL(SEPARATE_COMPILATION,test x$SEPARATE_COMPILATION = xyes)
AM_CONDITIONAL(HAVE_BOOST_COROUTINE,test x$HAVE_BOOST_COROUTINE = xyes)
AM_CONDITIONAL(WINDOWS_TARGET,test x$WINDOWS != xno)
AC_OUTPUT([
Makefile
include/Makefile
src/Makefile
src/tests/Makefile
src/examples/cpp03/Makefile
src/examples/cpp11/Makefile
src/examples/cpp14/Makefile])
@@ -1,291 +0,0 @@
//
// detail/consuming_buffers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 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 ASIO_DETAIL_CONSUMING_BUFFERS_HPP
#define ASIO_DETAIL_CONSUMING_BUFFERS_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include <cstddef>
#include <iterator>
#include "asio/buffer.hpp"
#include "asio/detail/limits.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
// A proxy iterator for a sub-range in a list of buffers.
template <typename Buffer, typename Buffer_Iterator>
class consuming_buffers_iterator
{
public:
/// The type used for the distance between two iterators.
typedef std::ptrdiff_t difference_type;
/// The type of the value pointed to by the iterator.
typedef Buffer value_type;
/// The type of the result of applying operator->() to the iterator.
typedef const Buffer* pointer;
/// The type of the result of applying operator*() to the iterator.
typedef const Buffer& reference;
/// The iterator category.
typedef std::forward_iterator_tag iterator_category;
// Default constructor creates an end iterator.
consuming_buffers_iterator()
: at_end_(true)
{
}
// Construct with a buffer for the first entry and an iterator
// range for the remaining entries.
consuming_buffers_iterator(bool at_end, const Buffer& first,
Buffer_Iterator begin_remainder, Buffer_Iterator end_remainder,
std::size_t max_size)
: at_end_(max_size > 0 ? at_end : true),
first_(buffer(first, max_size)),
begin_remainder_(begin_remainder),
end_remainder_(end_remainder),
offset_(0),
max_size_(max_size)
{
}
// Dereference an iterator.
const Buffer& operator*() const
{
return dereference();
}
// Dereference an iterator.
const Buffer* operator->() const
{
return &dereference();
}
// Increment operator (prefix).
consuming_buffers_iterator& operator++()
{
increment();
return *this;
}
// Increment operator (postfix).
consuming_buffers_iterator operator++(int)
{
consuming_buffers_iterator tmp(*this);
++*this;
return tmp;
}
// Test two iterators for equality.
friend bool operator==(const consuming_buffers_iterator& a,
const consuming_buffers_iterator& b)
{
return a.equal(b);
}
// Test two iterators for inequality.
friend bool operator!=(const consuming_buffers_iterator& a,
const consuming_buffers_iterator& b)
{
return !a.equal(b);
}
private:
void increment()
{
if (!at_end_)
{
if (begin_remainder_ == end_remainder_
|| offset_ + first_.size() >= max_size_)
{
at_end_ = true;
}
else
{
offset_ += first_.size();
first_ = buffer(*begin_remainder_++, max_size_ - offset_);
}
}
}
bool equal(const consuming_buffers_iterator& other) const
{
if (at_end_ && other.at_end_)
return true;
return !at_end_ && !other.at_end_
&& first_.data() == other.first_.data()
&& first_.size() == other.first_.size()
&& begin_remainder_ == other.begin_remainder_
&& end_remainder_ == other.end_remainder_;
}
const Buffer& dereference() const
{
return first_;
}
bool at_end_;
Buffer first_;
Buffer_Iterator begin_remainder_;
Buffer_Iterator end_remainder_;
std::size_t offset_;
std::size_t max_size_;
};
// A proxy for a sub-range in a list of buffers.
template <typename Buffer, typename Buffers>
class consuming_buffers
{
public:
// The type for each element in the list of buffers.
typedef Buffer value_type;
// A forward-only iterator type that may be used to read elements.
typedef consuming_buffers_iterator<Buffer, typename Buffers::const_iterator>
const_iterator;
// Construct to represent the entire list of buffers.
consuming_buffers(const Buffers& buffers)
: buffers_(buffers),
at_end_(buffers_.begin() == buffers_.end()),
begin_remainder_(buffers_.begin()),
max_size_((std::numeric_limits<std::size_t>::max)())
{
if (!at_end_)
{
first_ = *buffers_.begin();
++begin_remainder_;
}
}
// Copy constructor.
consuming_buffers(const consuming_buffers& other)
: buffers_(other.buffers_),
at_end_(other.at_end_),
first_(other.first_),
begin_remainder_(buffers_.begin()),
max_size_(other.max_size_)
{
typename Buffers::const_iterator first = other.buffers_.begin();
typename Buffers::const_iterator second = other.begin_remainder_;
std::advance(begin_remainder_, std::distance(first, second));
}
// Assignment operator.
consuming_buffers& operator=(const consuming_buffers& other)
{
buffers_ = other.buffers_;
at_end_ = other.at_end_;
first_ = other.first_;
begin_remainder_ = buffers_.begin();
typename Buffers::const_iterator first = other.buffers_.begin();
typename Buffers::const_iterator second = other.begin_remainder_;
std::advance(begin_remainder_, std::distance(first, second));
max_size_ = other.max_size_;
return *this;
}
// Get a forward-only iterator to the first element.
const_iterator begin() const
{
return const_iterator(at_end_, first_,
begin_remainder_, buffers_.end(), max_size_);
}
// Get a forward-only iterator for one past the last element.
const_iterator end() const
{
return const_iterator();
}
// Set the maximum size for a single transfer.
void prepare(std::size_t max_size)
{
max_size_ = max_size;
}
// Consume the specified number of bytes from the buffers.
void consume(std::size_t size)
{
// Remove buffers from the start until the specified size is reached.
while (size > 0 && !at_end_)
{
if (first_.size() <= size)
{
size -= first_.size();
if (begin_remainder_ == buffers_.end())
at_end_ = true;
else
first_ = *begin_remainder_++;
}
else
{
first_ = first_ + size;
size = 0;
}
}
// Remove any more empty buffers at the start.
while (!at_end_ && first_.size() == 0)
{
if (begin_remainder_ == buffers_.end())
at_end_ = true;
else
first_ = *begin_remainder_++;
}
}
private:
Buffers buffers_;
bool at_end_;
Buffer first_;
typename Buffers::const_iterator begin_remainder_;
std::size_t max_size_;
};
// Specialisation for null_buffers to ensure that the null_buffers type is
// always passed through to the underlying read or write operation.
template <typename Buffer>
class consuming_buffers<Buffer, asio::null_buffers>
: public asio::null_buffers
{
public:
consuming_buffers(const asio::null_buffers&)
{
// No-op.
}
void prepare(std::size_t)
{
// No-op.
}
void consume(std::size_t)
{
// No-op.
}
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_CONSUMING_BUFFERS_HPP
@@ -1,172 +0,0 @@
//
// impl/use_future.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 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 ASIO_IMPL_USE_FUTURE_HPP
#define ASIO_IMPL_USE_FUTURE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include <future>
#include "asio/async_result.hpp"
#include "asio/error_code.hpp"
#include "asio/handler_type.hpp"
#include "asio/system_error.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
// Completion handler to adapt a promise as a completion handler.
template <typename T>
class promise_handler
{
public:
// Construct from use_future special value.
template <typename Allocator>
promise_handler(use_future_t<Allocator> uf)
: promise_(std::allocate_shared<std::promise<T> >(
uf.get_allocator(), std::allocator_arg, uf.get_allocator()))
{
}
void operator()(T t)
{
promise_->set_value(t);
}
void operator()(const asio::error_code& ec, T t)
{
if (ec)
promise_->set_exception(
std::make_exception_ptr(
asio::system_error(ec)));
else
promise_->set_value(t);
}
//private:
std::shared_ptr<std::promise<T> > promise_;
};
// Completion handler to adapt a void promise as a completion handler.
template <>
class promise_handler<void>
{
public:
// Construct from use_future special value. Used during rebinding.
template <typename Allocator>
promise_handler(use_future_t<Allocator> uf)
: promise_(std::allocate_shared<std::promise<void> >(
uf.get_allocator(), std::allocator_arg, uf.get_allocator()))
{
}
void operator()()
{
promise_->set_value();
}
void operator()(const asio::error_code& ec)
{
if (ec)
promise_->set_exception(
std::make_exception_ptr(
asio::system_error(ec)));
else
promise_->set_value();
}
//private:
std::shared_ptr<std::promise<void> > promise_;
};
// Ensure any exceptions thrown from the handler are propagated back to the
// caller via the future.
template <typename Function, typename T>
void asio_handler_invoke(Function f, promise_handler<T>* h)
{
std::shared_ptr<std::promise<T> > p(h->promise_);
try
{
f();
}
catch (...)
{
p->set_exception(std::current_exception());
}
}
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
// Handler traits specialisation for promise_handler.
template <typename T>
class async_result<detail::promise_handler<T> >
{
public:
// The initiating function will return a future.
typedef std::future<T> type;
// Constructor creates a new promise for the async operation, and obtains the
// corresponding future.
explicit async_result(detail::promise_handler<T>& h)
{
value_ = h.promise_->get_future();
}
// Obtain the future to be returned from the initiating function.
type get() { return std::move(value_); }
private:
type value_;
};
// Handler type specialisation for use_future.
template <typename Allocator, typename ReturnType>
struct handler_type<use_future_t<Allocator>, ReturnType()>
{
typedef detail::promise_handler<void> type;
};
// Handler type specialisation for use_future.
template <typename Allocator, typename ReturnType, typename Arg1>
struct handler_type<use_future_t<Allocator>, ReturnType(Arg1)>
{
typedef detail::promise_handler<Arg1> type;
};
// Handler type specialisation for use_future.
template <typename Allocator, typename ReturnType>
struct handler_type<use_future_t<Allocator>,
ReturnType(asio::error_code)>
{
typedef detail::promise_handler<void> type;
};
// Handler type specialisation for use_future.
template <typename Allocator, typename ReturnType, typename Arg2>
struct handler_type<use_future_t<Allocator>,
ReturnType(asio::error_code, Arg2)>
{
typedef detail::promise_handler<Arg2> type;
};
#endif // !defined(GENERATING_DOCUMENTATION)
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_IMPL_USE_FUTURE_HPP
@@ -0,0 +1,2 @@
Makefile
Makefile.in
@@ -44,8 +44,12 @@ nobase_include_HEADERS = \
asio/detail/buffer_resize_guard.hpp \
asio/detail/buffer_sequence_adapter.hpp \
asio/detail/call_stack.hpp \
asio/detail/chrono.hpp \
asio/detail/chrono_time_traits.hpp \
asio/detail/completion_handler.hpp \
asio/detail/concurrency_hint.hpp \
asio/detail/conditionally_enabled_event.hpp \
asio/detail/conditionally_enabled_mutex.hpp \
asio/detail/config.hpp \
asio/detail/consuming_buffers.hpp \
asio/detail/cstddef.hpp \
@@ -86,6 +90,7 @@ nobase_include_HEADERS = \
asio/detail/impl/handler_tracking.ipp \
asio/detail/impl/kqueue_reactor.hpp \
asio/detail/impl/kqueue_reactor.ipp \
asio/detail/impl/null_event.ipp \
asio/detail/impl/pipe_select_interrupter.ipp \
asio/detail/impl/posix_event.ipp \
asio/detail/impl/posix_mutex.ipp \
@@ -127,6 +132,7 @@ nobase_include_HEADERS = \
asio/detail/impl/win_tss_ptr.ipp \
asio/detail/io_control.hpp \
asio/detail/is_buffer_sequence.hpp \
asio/detail/is_executor.hpp \
asio/detail/keyword_tss_ptr.hpp \
asio/detail/kqueue_reactor.hpp \
asio/detail/limits.hpp \
@@ -181,6 +187,7 @@ nobase_include_HEADERS = \
asio/detail/regex_fwd.hpp \
asio/detail/resolve_endpoint_op.hpp \
asio/detail/resolve_op.hpp \
asio/detail/resolve_query_op.hpp \
asio/detail/resolver_service_base.hpp \
asio/detail/resolver_service.hpp \
asio/detail/scheduler.hpp \
@@ -204,12 +211,14 @@ nobase_include_HEADERS = \
asio/detail/solaris_fenced_block.hpp \
asio/detail/static_mutex.hpp \
asio/detail/std_event.hpp \
asio/detail/std_fenced_block.hpp \
asio/detail/std_global.hpp \
asio/detail/std_mutex.hpp \
asio/detail/std_static_mutex.hpp \
asio/detail/std_thread.hpp \
asio/detail/strand_executor_service.hpp \
asio/detail/strand_service.hpp \
asio/detail/string_view.hpp \
asio/detail/thread_context.hpp \
asio/detail/thread_group.hpp \
asio/detail/thread.hpp \
@@ -337,6 +346,7 @@ nobase_include_HEADERS = \
asio/ip/basic_resolver.hpp \
asio/ip/basic_resolver_iterator.hpp \
asio/ip/basic_resolver_query.hpp \
asio/ip/basic_resolver_results.hpp \
asio/ip/detail/endpoint.hpp \
asio/ip/detail/impl/endpoint.ipp \
asio/ip/detail/socket_option.hpp \
@@ -373,10 +383,11 @@ nobase_include_HEADERS = \
asio/local/detail/endpoint.hpp \
asio/local/detail/impl/endpoint.ipp \
asio/local/stream_protocol.hpp \
asio/package.hpp \
asio/packaged_task.hpp \
asio/placeholders.hpp \
asio/posix/basic_descriptor.hpp \
asio/posix/basic_stream_descriptor.hpp \
asio/posix/descriptor.hpp \
asio/posix/descriptor_base.hpp \
asio/posix/stream_descriptor.hpp \
asio/posix/stream_descriptor_service.hpp \
@@ -436,9 +447,9 @@ nobase_include_HEADERS = \
asio/ts/executor.hpp \
asio/ts/internet.hpp \
asio/ts/io_context.hpp \
asio/ts/networking.hpp \
asio/ts/netfwd.hpp \
asio/ts/net.hpp \
asio/ts/socket.hpp \
asio/ts/thread_pool.hpp \
asio/ts/timer.hpp \
asio/unyield.hpp \
asio/use_future.hpp \
@@ -452,6 +463,7 @@ nobase_include_HEADERS = \
asio/windows/basic_stream_handle.hpp \
asio/windows/object_handle.hpp \
asio/windows/object_handle_service.hpp \
asio/windows/overlapped_handle.hpp \
asio/windows/overlapped_ptr.hpp \
asio/windows/random_access_handle.hpp \
asio/windows/random_access_handle_service.hpp \
@@ -2,7 +2,7 @@
// asio.hpp
// ~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -96,6 +96,7 @@
#include "asio/local/connect_pair.hpp"
#include "asio/local/datagram_protocol.hpp"
#include "asio/local/stream_protocol.hpp"
#include "asio/packaged_task.hpp"
#include "asio/placeholders.hpp"
#include "asio/posix/basic_descriptor.hpp"
#include "asio/posix/basic_stream_descriptor.hpp"
@@ -124,6 +125,7 @@
#include "asio/thread.hpp"
#include "asio/thread_pool.hpp"
#include "asio/time_traits.hpp"
#include "asio/use_future.hpp"
#include "asio/uses_executor.hpp"
#include "asio/version.hpp"
#include "asio/wait_traits.hpp"
@@ -2,7 +2,7 @@
// associated_allocator.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// associated_executor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -0,0 +1,221 @@
//
// async_result.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2016 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 ASIO_ASYNC_RESULT_HPP
#define ASIO_ASYNC_RESULT_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/handler_type.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
/// An interface for customising the behaviour of an initiating function.
/**
* The async_result traits class is used for determining:
*
* @li the concrete completion handler type to be called at the end of the
* asynchronous operation;
*
* @li the initiating function return type; and
*
* @li how the return value of the initiating function is obtained.
*
* The trait allows the handler and return types to be determined at the point
* where the specific completion handler signature is known.
*
* This template may be specialised for user-defined completion token types.
* The primary template assumes that the CompletionToken is the completion
* handler.
*/
#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature>
#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature = void>
#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
class async_result
{
public:
#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
/// The concrete completion handler type for the specific signature.
typedef CompletionToken completion_handler_type;
/// The return type of the initiating function.
typedef void return_type;
#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// For backward compatibility, determine the concrete completion handler type
// by using the legacy handler_type trait.
typedef typename handler_type<CompletionToken, Signature>::type
completion_handler_type;
// For backward compatibility, determine the initiating function return type
// using the legacy single-parameter version of async_result.
typedef typename async_result<completion_handler_type>::type return_type;
#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
/// Construct an async result from a given handler.
/**
* When using a specalised async_result, the constructor has an opportunity
* to initialise some state associated with the completion handler, which is
* then returned from the initiating function.
*/
explicit async_result(completion_handler_type& h)
#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// No data members to initialise.
#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
: legacy_result_(h)
#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
{
(void)h;
}
/// Obtain the value to be returned from the initiating function.
return_type get()
{
#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// Nothing to do.
#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
return legacy_result_.get();
#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
}
private:
async_result(const async_result&) ASIO_DELETED;
async_result& operator=(const async_result&) ASIO_DELETED;
#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// No data members.
#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
async_result<completion_handler_type> legacy_result_;
#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
};
#if !defined(ASIO_NO_DEPRECATED)
/// (Deprecated: Use two-parameter version of async_result.) An interface for
/// customising the behaviour of an initiating function.
/**
* This template may be specialised for user-defined handler types.
*/
template <typename Handler>
class async_result<Handler>
{
public:
/// The return type of the initiating function.
typedef void type;
/// Construct an async result from a given handler.
/**
* When using a specalised async_result, the constructor has an opportunity
* to initialise some state associated with the handler, which is then
* returned from the initiating function.
*/
explicit async_result(Handler&)
{
}
/// Obtain the value to be returned from the initiating function.
type get()
{
}
};
#endif // !defined(ASIO_NO_DEPRECATED)
/// Helper template to deduce the handler type from a CompletionToken, capture
/// a local copy of the handler, and then create an async_result for the
/// handler.
template <typename CompletionToken, typename Signature>
struct async_completion
{
/// The real handler type to be used for the asynchronous operation.
typedef typename asio::async_result<
typename decay<CompletionToken>::type,
Signature>::completion_handler_type completion_handler_type;
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Constructor.
/**
* The constructor creates the concrete completion handler and makes the link
* between the handler and the asynchronous result.
*/
explicit async_completion(CompletionToken& token)
: completion_handler(static_cast<typename conditional<
is_same<CompletionToken, completion_handler_type>::value,
completion_handler_type&, CompletionToken&&>::type>(token)),
result(completion_handler)
{
}
#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
explicit async_completion(typename decay<CompletionToken>::type& token)
: completion_handler(token),
result(completion_handler)
{
}
explicit async_completion(const typename decay<CompletionToken>::type& token)
: completion_handler(token),
result(completion_handler)
{
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// A copy of, or reference to, a real handler object.
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
typename conditional<
is_same<CompletionToken, completion_handler_type>::value,
completion_handler_type&, completion_handler_type>::type completion_handler;
#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
completion_handler_type completion_handler;
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// The result of the asynchronous operation's initiating function.
async_result<typename decay<CompletionToken>::type, Signature> result;
};
namespace detail {
template <typename CompletionToken, typename Signature>
struct async_result_helper
: async_result<typename decay<CompletionToken>::type, Signature>
{
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#if defined(GENERATING_DOCUMENTATION)
# define ASIO_INITFN_RESULT_TYPE(ct, sig) \
void_or_deduced
#elif defined(_MSC_VER) && (_MSC_VER < 1500)
# define ASIO_INITFN_RESULT_TYPE(ct, sig) \
typename ::asio::detail::async_result_helper< \
ct, sig>::return_type
#define ASIO_HANDLER_TYPE(ct, sig) \
typename ::asio::detail::async_result_helper< \
ct, sig>::completion_handler_type
#else
# define ASIO_INITFN_RESULT_TYPE(ct, sig) \
typename ::asio::async_result< \
typename ::asio::decay<ct>::type, sig>::return_type
#define ASIO_HANDLER_TYPE(ct, sig) \
typename ::asio::async_result< \
typename ::asio::decay<ct>::type, sig>::completion_handler_type
#endif
#endif // ASIO_ASYNC_RESULT_HPP
@@ -2,7 +2,7 @@
// basic_datagram_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -18,12 +18,15 @@
#include "asio/detail/config.hpp"
#include <cstddef>
#include "asio/basic_socket.hpp"
#include "asio/datagram_socket_service.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/error.hpp"
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/datagram_socket_service.hpp"
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#include "asio/detail/push_options.hpp"
namespace asio {
@@ -354,7 +357,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, 0, init.handler);
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -407,7 +410,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, flags, init.handler);
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -559,7 +562,7 @@ public:
this->get_service().async_send_to(
this->get_implementation(), buffers, destination, 0,
init.handler);
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -613,7 +616,7 @@ public:
this->get_service().async_send_to(
this->get_implementation(), buffers, destination, flags,
init.handler);
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -762,7 +765,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, 0, init.handler);
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -815,7 +818,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, flags, init.handler);
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -967,7 +970,7 @@ public:
this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, 0,
init.handler);
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -1023,7 +1026,7 @@ public:
this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, flags,
init.handler);
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -2,7 +2,7 @@
// basic_deadline_timer.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -22,16 +22,17 @@
#include <cstddef>
#include "asio/basic_io_object.hpp"
#include "asio/deadline_timer_service.hpp"
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/time_traits.hpp"
#if !defined(ASIO_ENABLE_OLD_SERVICES)
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/deadline_timer_service.hpp"
#else // defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/detail/deadline_timer_service.hpp"
# define ASIO_SVC_T detail::deadline_timer_service<TimeTraits>
#endif // !defined(ASIO_ENABLE_OLD_SERVICES)
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#include "asio/detail/push_options.hpp"
@@ -197,6 +198,40 @@ public:
asio::detail::throw_error(ec, "expires_from_now");
}
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Move-construct a basic_deadline_timer from another.
/**
* This constructor moves a timer from one object to another.
*
* @param other The other basic_deadline_timer object from which the move will
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_deadline_timer(io_context&) constructor.
*/
basic_deadline_timer(basic_deadline_timer&& other)
: basic_io_object<ASIO_SVC_T>(std::move(other))
{
}
/// Move-assign a basic_deadline_timer from another.
/**
* This assignment operator moves a timer from one object to another. Cancels
* any outstanding asynchronous operations associated with the target object.
*
* @param other The other basic_deadline_timer object from which the move will
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_deadline_timer(io_context&) constructor.
*/
basic_deadline_timer& operator=(basic_deadline_timer&& other)
{
basic_io_object<ASIO_SVC_T>::operator=(std::move(other));
return *this;
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Destroys the timer.
/**
* This function destroys the timer, cancelling any outstanding asynchronous
@@ -571,7 +606,8 @@ public:
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
this->get_service().async_wait(this->get_implementation(), init.handler);
this->get_service().async_wait(this->get_implementation(),
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -2,7 +2,7 @@
// basic_io_object.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -34,12 +34,13 @@ namespace detail
typedef typename service_type::implementation_type implementation_type;
template <typename T, typename U>
static auto eval(T* t, U* u) -> decltype(t->move_construct(*u, *u), char());
static char (&eval(...))[2];
static auto asio_service_has_move_eval(T* t, U* u)
-> decltype(t->move_construct(*u, *u), char());
static char (&asio_service_has_move_eval(...))[2];
public:
static const bool value =
sizeof(service_has_move::eval(
sizeof(asio_service_has_move_eval(
static_cast<service_type*>(0),
static_cast<implementation_type*>(0))) == 1;
};
@@ -137,6 +138,11 @@ protected:
* @note Available only for services that support movability,
*/
basic_io_object& operator=(basic_io_object&& other);
/// Perform a converting move-construction of a basic_io_object.
template <typename IoObjectService1>
basic_io_object(IoObjectService1& other_service,
typename IoObjectService1::implementation_type& other_implementation);
#endif // defined(GENERATING_DOCUMENTATION)
/// Protected destructor to prevent deletion through this type.
@@ -225,6 +231,16 @@ protected:
service_->move_construct(implementation_, other.implementation_);
}
template <typename IoObjectService1>
basic_io_object(IoObjectService1& other_service,
typename IoObjectService1::implementation_type& other_implementation)
: service_(&asio::use_service<IoObjectService>(
other_service.get_io_context()))
{
service_->converting_move_construct(implementation_,
other_service, other_implementation);
}
~basic_io_object()
{
service_->destroy(implementation_);
@@ -2,7 +2,7 @@
// basic_raw_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -22,7 +22,10 @@
#include "asio/detail/throw_error.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/error.hpp"
#include "asio/raw_socket_service.hpp"
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/raw_socket_service.hpp"
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#include "asio/detail/push_options.hpp"
@@ -346,7 +349,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, 0, init.handler);
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -399,7 +402,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, flags, init.handler);
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -549,7 +552,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send_to(this->get_implementation(),
buffers, destination, 0, init.handler);
buffers, destination, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -603,7 +606,7 @@ public:
this->get_service().async_send_to(
this->get_implementation(), buffers, destination, flags,
init.handler);
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -752,7 +755,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, 0, init.handler);
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -805,7 +808,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, flags, init.handler);
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -957,7 +960,7 @@ public:
this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, 0,
init.handler);
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -1013,7 +1016,7 @@ public:
this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, flags,
init.handler);
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -2,7 +2,7 @@
// basic_seq_packet_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -21,7 +21,10 @@
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/seq_packet_socket_service.hpp"
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/seq_packet_socket_service.hpp"
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#include "asio/detail/push_options.hpp"
@@ -332,7 +335,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, flags, init.handler);
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -531,7 +534,7 @@ public:
this->get_service().async_receive_with_flags(
this->get_implementation(), buffers, 0, out_flags,
init.handler);
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -601,7 +604,7 @@ public:
this->get_service().async_receive_with_flags(
this->get_implementation(), buffers, in_flags, out_flags,
init.handler);
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -2,7 +2,7 @@
// basic_serial_port.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -217,10 +217,11 @@ public:
*
* @param ec Set the indicate what error occurred, if any.
*/
asio::error_code open(const std::string& device,
ASIO_SYNC_OP_VOID open(const std::string& device,
asio::error_code& ec)
{
return this->get_service().open(this->get_implementation(), device, ec);
this->get_service().open(this->get_implementation(), device, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Assign an existing native serial port to the serial port.
@@ -247,11 +248,12 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
asio::error_code assign(const native_handle_type& native_serial_port,
ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port,
asio::error_code& ec)
{
return this->get_service().assign(this->get_implementation(),
this->get_service().assign(this->get_implementation(),
native_serial_port, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the serial port is open.
@@ -283,9 +285,10 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
asio::error_code close(asio::error_code& ec)
ASIO_SYNC_OP_VOID close(asio::error_code& ec)
{
return this->get_service().close(this->get_implementation(), ec);
this->get_service().close(this->get_implementation(), ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get the native serial port representation.
@@ -322,9 +325,10 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
asio::error_code cancel(asio::error_code& ec)
ASIO_SYNC_OP_VOID cancel(asio::error_code& ec)
{
return this->get_service().cancel(this->get_implementation(), ec);
this->get_service().cancel(this->get_implementation(), ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Send a break sequence to the serial port.
@@ -348,9 +352,10 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
asio::error_code send_break(asio::error_code& ec)
ASIO_SYNC_OP_VOID send_break(asio::error_code& ec)
{
return this->get_service().send_break(this->get_implementation(), ec);
this->get_service().send_break(this->get_implementation(), ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Set an option on the serial port.
@@ -392,11 +397,11 @@ public:
* asio::serial_port_base::character_size
*/
template <typename SettableSerialPortOption>
asio::error_code set_option(const SettableSerialPortOption& option,
ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option,
asio::error_code& ec)
{
return this->get_service().set_option(
this->get_implementation(), option, ec);
this->get_service().set_option(this->get_implementation(), option, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get an option from the serial port.
@@ -440,11 +445,11 @@ public:
* asio::serial_port_base::character_size
*/
template <typename GettableSerialPortOption>
asio::error_code get_option(GettableSerialPortOption& option,
ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option,
asio::error_code& ec)
{
return this->get_service().get_option(
this->get_implementation(), option, ec);
this->get_service().get_option(this->get_implementation(), option, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Write some data to the serial port.
@@ -2,7 +2,7 @@
// basic_signal_set.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -213,11 +213,10 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
asio::error_code add(int signal_number,
asio::error_code& ec)
ASIO_SYNC_OP_VOID add(int signal_number, asio::error_code& ec)
{
return this->get_service().add(
this->get_implementation(), signal_number, ec);
this->get_service().add(this->get_implementation(), signal_number, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Remove a signal from a signal_set.
@@ -251,11 +250,11 @@ public:
* @note Removes any notifications that have been queued for the specified
* signal number.
*/
asio::error_code remove(int signal_number,
ASIO_SYNC_OP_VOID remove(int signal_number,
asio::error_code& ec)
{
return this->get_service().remove(
this->get_implementation(), signal_number, ec);
this->get_service().remove(this->get_implementation(), signal_number, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Remove all signals from a signal_set.
@@ -283,9 +282,10 @@ public:
*
* @note Removes all queued notifications.
*/
asio::error_code clear(asio::error_code& ec)
ASIO_SYNC_OP_VOID clear(asio::error_code& ec)
{
return this->get_service().clear(this->get_implementation(), ec);
this->get_service().clear(this->get_implementation(), ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Cancel all operations associated with the signal set.
@@ -337,9 +337,10 @@ public:
* These handlers can no longer be cancelled, and therefore are passed an
* error code that indicates the successful completion of the wait operation.
*/
asio::error_code cancel(asio::error_code& ec)
ASIO_SYNC_OP_VOID cancel(asio::error_code& ec)
{
return this->get_service().cancel(this->get_implementation(), ec);
this->get_service().cancel(this->get_implementation(), ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Start an asynchronous operation to wait for a signal to be delivered.
@@ -2,7 +2,7 @@
// basic_socket.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -77,8 +77,10 @@ public:
/// The endpoint type.
typedef typename Protocol::endpoint endpoint_type;
#if !defined(ASIO_NO_EXTENSIONS)
/// A basic_socket is always the lowest layer.
typedef basic_socket<Protocol ASIO_SVC_TARG> lowest_layer_type;
#endif // !defined(ASIO_NO_EXTENSIONS)
/// Construct a basic_socket without opening it.
/**
@@ -211,10 +213,9 @@ public:
template <typename Protocol1 ASIO_SVC_TPARAM1>
basic_socket(basic_socket<Protocol1 ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
: basic_io_object<ASIO_SVC_T>(other.get_service().get_io_context())
: basic_io_object<ASIO_SVC_T>(
other.get_service(), other.get_implementation())
{
this->get_service().template converting_move_construct<Protocol1>(
this->get_implementation(), other.get_implementation());
}
/// Move-assign a basic_socket from a socket of another protocol type.
@@ -278,6 +279,7 @@ public:
}
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#if !defined(ASIO_NO_EXTENSIONS)
/// Get a reference to the lowest layer.
/**
* This function returns a reference to the lowest layer in a stack of
@@ -305,6 +307,7 @@ public:
{
return *this;
}
#endif // !defined(ASIO_NO_EXTENSIONS)
/// Open the socket using the specified protocol.
/**
@@ -346,10 +349,11 @@ public:
* }
* @endcode
*/
asio::error_code open(const protocol_type& protocol,
ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
asio::error_code& ec)
{
return this->get_service().open(this->get_implementation(), protocol, ec);
this->get_service().open(this->get_implementation(), protocol, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Assign an existing native socket to the socket.
@@ -381,11 +385,12 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
asio::error_code assign(const protocol_type& protocol,
ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
const native_handle_type& native_socket, asio::error_code& ec)
{
return this->get_service().assign(this->get_implementation(),
this->get_service().assign(this->get_implementation(),
protocol, native_socket, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the socket is open.
@@ -437,9 +442,62 @@ public:
* @note For portable behaviour with respect to graceful closure of a
* connected socket, call shutdown() before closing the socket.
*/
asio::error_code close(asio::error_code& ec)
ASIO_SYNC_OP_VOID close(asio::error_code& ec)
{
return this->get_service().close(this->get_implementation(), ec);
this->get_service().close(this->get_implementation(), ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Release ownership of the underlying native socket.
/**
* This function causes all outstanding asynchronous connect, send and receive
* operations to finish immediately, and the handlers for cancelled operations
* will be passed the asio::error::operation_aborted error. Ownership
* of the native socket is then transferred to the caller.
*
* @throws asio::system_error Thrown on failure.
*
* @note This function is unsupported on Windows versions prior to Windows
* 8.1, and will fail with asio::error::operation_not_supported on
* these platforms.
*/
#if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \
&& (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
__declspec(deprecated("This function always fails with "
"operation_not_supported when used on Windows versions "
"prior to Windows 8.1."))
#endif
native_handle_type release()
{
asio::error_code ec;
native_handle_type s = this->get_service().release(
this->get_implementation(), ec);
asio::detail::throw_error(ec, "release");
return s;
}
/// Release ownership of the underlying native socket.
/**
* This function causes all outstanding asynchronous connect, send and receive
* operations to finish immediately, and the handlers for cancelled operations
* will be passed the asio::error::operation_aborted error. Ownership
* of the native socket is then transferred to the caller.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note This function is unsupported on Windows versions prior to Windows
* 8.1, and will fail with asio::error::operation_not_supported on
* these platforms.
*/
#if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \
&& (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
__declspec(deprecated("This function always fails with "
"operation_not_supported when used on Windows versions "
"prior to Windows 8.1."))
#endif
native_handle_type release(asio::error_code& ec)
{
return this->get_service().release(this->get_implementation(), ec);
}
/// Get the native socket representation.
@@ -542,9 +600,10 @@ public:
"operation_not_supported when used on Windows XP, Windows Server 2003, "
"or earlier. Consult documentation for details."))
#endif
asio::error_code cancel(asio::error_code& ec)
ASIO_SYNC_OP_VOID cancel(asio::error_code& ec)
{
return this->get_service().cancel(this->get_implementation(), ec);
this->get_service().cancel(this->get_implementation(), ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the socket is at the out-of-band data mark.
@@ -662,10 +721,11 @@ public:
* }
* @endcode
*/
asio::error_code bind(const endpoint_type& endpoint,
ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
asio::error_code& ec)
{
return this->get_service().bind(this->get_implementation(), endpoint, ec);
this->get_service().bind(this->get_implementation(), endpoint, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Connect the socket to the specified endpoint.
@@ -732,20 +792,21 @@ public:
* }
* @endcode
*/
asio::error_code connect(const endpoint_type& peer_endpoint,
ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint,
asio::error_code& ec)
{
if (!is_open())
{
if (this->get_service().open(this->get_implementation(),
peer_endpoint.protocol(), ec))
this->get_service().open(this->get_implementation(),
peer_endpoint.protocol(), ec);
if (ec)
{
return ec;
ASIO_SYNC_OP_VOID_RETURN(ec);
}
}
return this->get_service().connect(
this->get_implementation(), peer_endpoint, ec);
this->get_service().connect(this->get_implementation(), peer_endpoint, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Start an asynchronous connect.
@@ -803,7 +864,8 @@ public:
{
asio::error_code ec;
const protocol_type protocol = peer_endpoint.protocol();
if (this->get_service().open(this->get_implementation(), protocol, ec))
this->get_service().open(this->get_implementation(), protocol, ec);
if (ec)
{
async_completion<ConnectHandler,
void (asio::error_code)> init(handler);
@@ -812,7 +874,7 @@ public:
asio::detail::bind_handler(
ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(
ConnectHandler, void (asio::error_code)))(
init.handler), ec));
init.completion_handler), ec));
return init.result.get();
}
@@ -826,7 +888,7 @@ public:
void (asio::error_code)> init(handler);
this->get_service().async_connect(
this->get_implementation(), peer_endpoint, init.handler);
this->get_implementation(), peer_endpoint, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -914,11 +976,11 @@ public:
* @endcode
*/
template <typename SettableSocketOption>
asio::error_code set_option(const SettableSocketOption& option,
ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
asio::error_code& ec)
{
return this->get_service().set_option(
this->get_implementation(), option, ec);
this->get_service().set_option(this->get_implementation(), option, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get an option from the socket.
@@ -1005,11 +1067,11 @@ public:
* @endcode
*/
template <typename GettableSocketOption>
asio::error_code get_option(GettableSocketOption& option,
ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
asio::error_code& ec) const
{
return this->get_service().get_option(
this->get_implementation(), option, ec);
this->get_service().get_option(this->get_implementation(), option, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Perform an IO control command on the socket.
@@ -1070,11 +1132,11 @@ public:
* @endcode
*/
template <typename IoControlCommand>
asio::error_code io_control(IoControlCommand& command,
ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
asio::error_code& ec)
{
return this->get_service().io_control(
this->get_implementation(), command, ec);
this->get_service().io_control(this->get_implementation(), command, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the socket.
@@ -1126,11 +1188,11 @@ public:
* operations. Asynchronous operations will never fail with the error
* asio::error::would_block.
*/
asio::error_code non_blocking(
ASIO_SYNC_OP_VOID non_blocking(
bool mode, asio::error_code& ec)
{
return this->get_service().non_blocking(
this->get_implementation(), mode, ec);
this->get_service().non_blocking(this->get_implementation(), mode, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the native socket implementation.
@@ -1400,11 +1462,12 @@ public:
* sock.async_wait(tcp::socket::wait_write, op);
* } @endcode
*/
asio::error_code native_non_blocking(
ASIO_SYNC_OP_VOID native_non_blocking(
bool mode, asio::error_code& ec)
{
return this->get_service().native_non_blocking(
this->get_service().native_non_blocking(
this->get_implementation(), mode, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get the local endpoint of the socket.
@@ -1553,10 +1616,11 @@ public:
* }
* @endcode
*/
asio::error_code shutdown(shutdown_type what,
ASIO_SYNC_OP_VOID shutdown(shutdown_type what,
asio::error_code& ec)
{
return this->get_service().shutdown(this->get_implementation(), what, ec);
this->get_service().shutdown(this->get_implementation(), what, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Wait for the socket to become ready to read, ready to write, or to have
@@ -1601,9 +1665,10 @@ public:
* socket.wait(asio::ip::tcp::socket::wait_read, ec);
* @endcode
*/
asio::error_code wait(wait_type w, asio::error_code& ec)
ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec)
{
return this->get_service().wait(this->get_implementation(), w, ec);
this->get_service().wait(this->get_implementation(), w, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Asynchronously wait for the socket to become ready to read, ready to
@@ -1658,7 +1723,8 @@ public:
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
this->get_service().async_wait(this->get_implementation(), w, init.handler);
this->get_service().async_wait(this->get_implementation(),
w, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -1674,6 +1740,7 @@ protected:
{
}
private:
// Disallow copying and assignment.
basic_socket(const basic_socket&) ASIO_DELETED;
basic_socket& operator=(const basic_socket&) ASIO_DELETED;
@@ -2,7 +2,7 @@
// basic_socket_acceptor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -22,14 +22,15 @@
#include "asio/detail/throw_error.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/error.hpp"
#include "asio/socket_acceptor_service.hpp"
#include "asio/socket_base.hpp"
#if defined(ASIO_HAS_MOVE)
# include <utility>
#endif // defined(ASIO_HAS_MOVE)
#if !defined(ASIO_ENABLE_OLD_SERVICES)
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/socket_acceptor_service.hpp"
#else // defined(ASIO_ENABLE_OLD_SERVICES)
# if defined(ASIO_WINDOWS_RUNTIME)
# include "asio/detail/null_socket_service.hpp"
# define ASIO_SVC_T detail::null_socket_service<Protocol>
@@ -40,7 +41,7 @@
# include "asio/detail/reactive_socket_service.hpp"
# define ASIO_SVC_T detail::reactive_socket_service<Protocol>
# endif
#endif // !defined(ASIO_ENABLE_OLD_SERVICES)
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#include "asio/detail/push_options.hpp"
@@ -169,7 +170,7 @@ public:
this->get_service().bind(this->get_implementation(), endpoint, ec);
asio::detail::throw_error(ec, "bind");
this->get_service().listen(this->get_implementation(),
socket_base::max_connections, ec);
socket_base::max_listen_connections, ec);
asio::detail::throw_error(ec, "listen");
}
@@ -250,10 +251,8 @@ public:
basic_socket_acceptor<Protocol1 ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
: basic_io_object<ASIO_SVC_T>(
other.get_service().get_io_context())
other.get_service(), other.get_implementation())
{
this->get_service().template converting_move_construct<Protocol1>(
this->get_implementation(), other.get_implementation());
}
/// Move-assign a basic_socket_acceptor from an acceptor of another protocol
@@ -370,10 +369,11 @@ public:
* }
* @endcode
*/
asio::error_code open(const protocol_type& protocol,
ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
asio::error_code& ec)
{
return this->get_service().open(this->get_implementation(), protocol, ec);
this->get_service().open(this->get_implementation(), protocol, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Assigns an existing native acceptor to the acceptor.
@@ -405,11 +405,12 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
asio::error_code assign(const protocol_type& protocol,
ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
const native_handle_type& native_acceptor, asio::error_code& ec)
{
return this->get_service().assign(this->get_implementation(),
this->get_service().assign(this->get_implementation(),
protocol, native_acceptor, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the acceptor is open.
@@ -466,10 +467,11 @@ public:
* }
* @endcode
*/
asio::error_code bind(const endpoint_type& endpoint,
ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
asio::error_code& ec)
{
return this->get_service().bind(this->get_implementation(), endpoint, ec);
this->get_service().bind(this->get_implementation(), endpoint, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Place the acceptor into the state where it will listen for new
@@ -482,7 +484,7 @@ public:
*
* @throws asio::system_error Thrown on failure.
*/
void listen(int backlog = socket_base::max_connections)
void listen(int backlog = socket_base::max_listen_connections)
{
asio::error_code ec;
this->get_service().listen(this->get_implementation(), backlog, ec);
@@ -504,16 +506,17 @@ public:
* asio::ip::tcp::acceptor acceptor(io_context);
* ...
* asio::error_code ec;
* acceptor.listen(asio::socket_base::max_connections, ec);
* acceptor.listen(asio::socket_base::max_listen_connections, ec);
* if (ec)
* {
* // An error occurred.
* }
* @endcode
*/
asio::error_code listen(int backlog, asio::error_code& ec)
ASIO_SYNC_OP_VOID listen(int backlog, asio::error_code& ec)
{
return this->get_service().listen(this->get_implementation(), backlog, ec);
this->get_service().listen(this->get_implementation(), backlog, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Close the acceptor.
@@ -555,9 +558,62 @@ public:
* }
* @endcode
*/
asio::error_code close(asio::error_code& ec)
ASIO_SYNC_OP_VOID close(asio::error_code& ec)
{
return this->get_service().close(this->get_implementation(), ec);
this->get_service().close(this->get_implementation(), ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Release ownership of the underlying native acceptor.
/**
* This function causes all outstanding asynchronous accept operations to
* finish immediately, and the handlers for cancelled operations will be
* passed the asio::error::operation_aborted error. Ownership of the
* native acceptor is then transferred to the caller.
*
* @throws asio::system_error Thrown on failure.
*
* @note This function is unsupported on Windows versions prior to Windows
* 8.1, and will fail with asio::error::operation_not_supported on
* these platforms.
*/
#if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \
&& (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
__declspec(deprecated("This function always fails with "
"operation_not_supported when used on Windows versions "
"prior to Windows 8.1."))
#endif
native_handle_type release()
{
asio::error_code ec;
native_handle_type s = this->get_service().release(
this->get_implementation(), ec);
asio::detail::throw_error(ec, "release");
return s;
}
/// Release ownership of the underlying native acceptor.
/**
* This function causes all outstanding asynchronous accept operations to
* finish immediately, and the handlers for cancelled operations will be
* passed the asio::error::operation_aborted error. Ownership of the
* native acceptor is then transferred to the caller.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note This function is unsupported on Windows versions prior to Windows
* 8.1, and will fail with asio::error::operation_not_supported on
* these platforms.
*/
#if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \
&& (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
__declspec(deprecated("This function always fails with "
"operation_not_supported when used on Windows versions "
"prior to Windows 8.1."))
#endif
native_handle_type release(asio::error_code& ec)
{
return this->get_service().release(this->get_implementation(), ec);
}
/// Get the native acceptor representation.
@@ -594,9 +650,10 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
asio::error_code cancel(asio::error_code& ec)
ASIO_SYNC_OP_VOID cancel(asio::error_code& ec)
{
return this->get_service().cancel(this->get_implementation(), ec);
this->get_service().cancel(this->get_implementation(), ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Set an option on the acceptor.
@@ -655,11 +712,11 @@ public:
* @endcode
*/
template <typename SettableSocketOption>
asio::error_code set_option(const SettableSocketOption& option,
ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
asio::error_code& ec)
{
return this->get_service().set_option(
this->get_implementation(), option, ec);
this->get_service().set_option(this->get_implementation(), option, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get an option from the acceptor.
@@ -720,11 +777,11 @@ public:
* @endcode
*/
template <typename GettableSocketOption>
asio::error_code get_option(GettableSocketOption& option,
ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
asio::error_code& ec)
{
return this->get_service().get_option(
this->get_implementation(), option, ec);
this->get_service().get_option(this->get_implementation(), option, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Perform an IO control command on the acceptor.
@@ -781,11 +838,11 @@ public:
* @endcode
*/
template <typename IoControlCommand>
asio::error_code io_control(IoControlCommand& command,
ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
asio::error_code& ec)
{
return this->get_service().io_control(
this->get_implementation(), command, ec);
this->get_service().io_control(this->get_implementation(), command, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the acceptor.
@@ -837,11 +894,11 @@ public:
* operations. Asynchronous operations will never fail with the error
* asio::error::would_block.
*/
asio::error_code non_blocking(
ASIO_SYNC_OP_VOID non_blocking(
bool mode, asio::error_code& ec)
{
return this->get_service().non_blocking(
this->get_implementation(), mode, ec);
this->get_service().non_blocking(this->get_implementation(), mode, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the native acceptor implementation.
@@ -901,11 +958,12 @@ public:
* function fails with asio::error::invalid_argument, as the
* combination does not make sense.
*/
asio::error_code native_non_blocking(
ASIO_SYNC_OP_VOID native_non_blocking(
bool mode, asio::error_code& ec)
{
return this->get_service().native_non_blocking(
this->get_service().native_non_blocking(
this->get_implementation(), mode, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get the local endpoint of the acceptor.
@@ -1001,9 +1059,10 @@ public:
* acceptor.wait(asio::ip::tcp::acceptor::wait_read, ec);
* @endcode
*/
asio::error_code wait(wait_type w, asio::error_code& ec)
ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec)
{
return this->get_service().wait(this->get_implementation(), w, ec);
this->get_service().wait(this->get_implementation(), w, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Asynchronously wait for the acceptor to become ready to read, ready to
@@ -1060,12 +1119,14 @@ public:
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
this->get_service().async_wait(this->get_implementation(), w, init.handler);
this->get_service().async_wait(this->get_implementation(),
w, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
}
#if !defined(ASIO_NO_EXTENSIONS)
/// Accept a new connection.
/**
* This function is used to accept a new connection from a peer into the
@@ -1125,19 +1186,20 @@ public:
*/
#if defined(ASIO_ENABLE_OLD_SERVICES)
template <typename Protocol1, typename SocketService>
asio::error_code accept(
ASIO_SYNC_OP_VOID accept(
basic_socket<Protocol1, SocketService>& peer,
asio::error_code& ec,
typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
#else // defined(ASIO_ENABLE_OLD_SERVICES)
template <typename Protocol1>
asio::error_code accept(
ASIO_SYNC_OP_VOID accept(
basic_socket<Protocol1>& peer, asio::error_code& ec,
typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
{
return this->get_service().accept(this->get_implementation(),
this->get_service().accept(this->get_implementation(),
peer, static_cast<endpoint_type*>(0), ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Start an asynchronous accept.
@@ -1207,7 +1269,7 @@ public:
void (asio::error_code)> init(handler);
this->get_service().async_accept(this->get_implementation(),
peer, static_cast<endpoint_type*>(0), init.handler);
peer, static_cast<endpoint_type*>(0), init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -1280,16 +1342,17 @@ public:
*/
#if defined(ASIO_ENABLE_OLD_SERVICES)
template <typename SocketService>
asio::error_code accept(
ASIO_SYNC_OP_VOID accept(
basic_socket<protocol_type, SocketService>& peer,
endpoint_type& peer_endpoint, asio::error_code& ec)
#else // defined(ASIO_ENABLE_OLD_SERVICES)
asio::error_code accept(basic_socket<protocol_type>& peer,
ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type>& peer,
endpoint_type& peer_endpoint, asio::error_code& ec)
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
{
return this->get_service().accept(
this->get_service().accept(
this->get_implementation(), peer, &peer_endpoint, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Start an asynchronous accept.
@@ -1344,11 +1407,12 @@ public:
void (asio::error_code)> init(handler);
this->get_service().async_accept(this->get_implementation(),
peer, &peer_endpoint, init.handler);
peer, &peer_endpoint, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
}
#endif // !defined(ASIO_NO_EXTENSIONS)
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Accept a new connection.
@@ -1471,7 +1535,7 @@ public:
this->get_service().async_accept(
this->get_implementation(), static_cast<asio::io_context*>(0),
static_cast<endpoint_type*>(0), init.handler);
static_cast<endpoint_type*>(0), init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -1607,7 +1671,7 @@ public:
typename Protocol::socket)> init(handler);
this->get_service().async_accept(this->get_implementation(),
&io_context, static_cast<endpoint_type*>(0), init.handler);
&io_context, static_cast<endpoint_type*>(0), init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -1748,7 +1812,8 @@ public:
typename Protocol::socket)> init(handler);
this->get_service().async_accept(this->get_implementation(),
static_cast<asio::io_context*>(0), &peer_endpoint, init.handler);
static_cast<asio::io_context*>(0), &peer_endpoint,
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -1902,7 +1967,7 @@ public:
typename Protocol::socket)> init(handler);
this->get_service().async_accept(this->get_implementation(),
&io_context, &peer_endpoint, init.handler);
&io_context, &peer_endpoint, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -2,7 +2,7 @@
// basic_socket_iostream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -22,7 +22,10 @@
#include <istream>
#include <ostream>
#include "asio/basic_socket_streambuf.hpp"
#include "asio/stream_socket_service.hpp"
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/stream_socket_service.hpp"
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)
@@ -33,8 +36,8 @@
// explicit basic_socket_iostream(T1 x1, ..., Tn xn)
// : std::basic_iostream<char>(
// &this->detail::socket_iostream_base<
// Protocol ASIO_SVC_TARG, Time,
// TimeTraits ASIO_SVC_TARG1>::streambuf_)
// Protocol ASIO_SVC_TARG, Clock,
// WaitTraits ASIO_SVC_TARG1>::streambuf_)
// {
// if (rdbuf()->connect(x1, ..., xn) == 0)
// this->setstate(std::ios_base::failbit);
@@ -46,8 +49,8 @@
explicit basic_socket_iostream(ASIO_VARIADIC_BYVAL_PARAMS(n)) \
: std::basic_iostream<char>( \
&this->detail::socket_iostream_base< \
Protocol ASIO_SVC_TARG, Time, \
TimeTraits ASIO_SVC_TARG1>::streambuf_) \
Protocol ASIO_SVC_TARG, Clock, \
WaitTraits ASIO_SVC_TARG1>::streambuf_) \
{ \
this->setf(std::ios_base::unitbuf); \
if (rdbuf()->connect(ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \
@@ -83,59 +86,102 @@ namespace detail {
// A separate base class is used to ensure that the streambuf is initialised
// prior to the basic_socket_iostream's basic_iostream base class.
template <typename Protocol ASIO_SVC_TPARAM,
typename Time, typename TimeTraits ASIO_SVC_TPARAM1>
typename Clock, typename WaitTraits ASIO_SVC_TPARAM1>
class socket_iostream_base
{
protected:
socket_iostream_base()
{
}
#if defined(ASIO_HAS_MOVE)
socket_iostream_base(socket_iostream_base&& other)
: streambuf_(std::move(other.streambuf_))
{
}
socket_iostream_base(basic_stream_socket<Protocol> s)
: streambuf_(std::move(s))
{
}
socket_iostream_base& operator=(socket_iostream_base&& other)
{
streambuf_ = std::move(other.streambuf_);
return *this;
}
#endif // defined(ASIO_HAS_MOVE)
basic_socket_streambuf<Protocol ASIO_SVC_TARG,
Time, TimeTraits ASIO_SVC_TARG1> streambuf_;
Clock, WaitTraits ASIO_SVC_TARG1> streambuf_;
};
} // namespace detail
/// Iostream interface for a socket.
#if !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)
#define ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL
// Forward declaration with defaulted arguments.
template <typename Protocol
ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
#if defined(ASIO_HAS_BOOST_DATE_TIME) \
|| defined(GENERATING_DOCUMENTATION)
typename Time = boost::posix_time::ptime,
typename TimeTraits = asio::time_traits<Time>
ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Time, TimeTraits>)>
#if defined(ASIO_HAS_BOOST_DATE_TIME)
typename Clock = boost::posix_time::ptime,
typename WaitTraits = time_traits<Clock>
ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
#else
typename Time = steady_timer::clock_type,
typename TimeTraits = steady_timer::traits_type
typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock>
ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
#endif
class basic_socket_iostream;
#endif // !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)
/// Iostream interface for a socket.
#if defined(GENERATING_DOCUMENTATION)
template <typename Protocol,
typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock> >
#else // defined(GENERATING_DOCUMENTATION)
template <typename Protocol ASIO_SVC_TPARAM,
typename Clock, typename WaitTraits ASIO_SVC_TPARAM1>
#endif // defined(GENERATING_DOCUMENTATION)
class basic_socket_iostream
: private detail::socket_iostream_base<Protocol
ASIO_SVC_TARG, Time, TimeTraits ASIO_SVC_TARG1>,
ASIO_SVC_TARG, Clock, WaitTraits ASIO_SVC_TARG1>,
public std::basic_iostream<char>
{
private:
// These typedefs are intended keep this class's implementation independent
// of whether it's using Boost.DateTime, Boost.Chrono or std::chrono.
// of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.
#if defined(ASIO_HAS_BOOST_DATE_TIME)
typedef TimeTraits traits_helper;
typedef WaitTraits traits_helper;
#else
typedef detail::chrono_time_traits<Time, TimeTraits> traits_helper;
typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;
#endif
public:
/// The protocol type.
typedef Protocol protocol_type;
/// The endpoint type.
typedef typename Protocol::endpoint endpoint_type;
/// The clock type.
typedef Clock clock_type;
#if defined(GENERATING_DOCUMENTATION)
/// (Deprecated: Use time_point.) The time type.
typedef typename TimeTraits::time_type time_type;
typedef typename WaitTraits::time_type time_type;
/// The time type.
typedef typename TimeTraits::time_point time_point;
typedef typename WaitTraits::time_point time_point;
/// (Deprecated: Use duration.) The duration type.
typedef typename TimeTraits::duration_type duration_type;
typedef typename WaitTraits::duration_type duration_type;
/// The duration type.
typedef typename TimeTraits::duration duration;
typedef typename WaitTraits::duration duration;
#else
# if !defined(ASIO_NO_DEPRECATED)
typedef typename traits_helper::time_type time_type;
@@ -149,12 +195,49 @@ public:
basic_socket_iostream()
: std::basic_iostream<char>(
&this->detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Time,
TimeTraits ASIO_SVC_TARG1>::streambuf_)
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>::streambuf_)
{
this->setf(std::ios_base::unitbuf);
}
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Construct a basic_socket_iostream from the supplied socket.
explicit basic_socket_iostream(basic_stream_socket<protocol_type> s)
: detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>(std::move(s)),
std::basic_iostream<char>(
&this->detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>::streambuf_)
{
this->setf(std::ios_base::unitbuf);
}
/// Move-construct a basic_socket_iostream from another.
basic_socket_iostream(basic_socket_iostream&& other)
: detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>(std::move(other)),
std::basic_iostream<char>(std::move(other))
{
this->set_rdbuf(&this->detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>::streambuf_);
}
/// Move-assign a basic_socket_iostream from another.
basic_socket_iostream& operator=(basic_socket_iostream&& other)
{
std::basic_iostream<char>::operator=(std::move(other));
detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>::operator=(std::move(other));
return *this;
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
#if defined(GENERATING_DOCUMENTATION)
/// Establish a connection to an endpoint corresponding to a resolver query.
/**
@@ -169,8 +252,8 @@ public:
explicit basic_socket_iostream(T... x)
: std::basic_iostream<char>(
&this->detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Time,
TimeTraits ASIO_SVC_TARG1>::streambuf_)
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>::streambuf_)
{
this->setf(std::ios_base::unitbuf);
if (rdbuf()->connect(x...) == 0)
@@ -209,13 +292,19 @@ public:
/// Return a pointer to the underlying streambuf.
basic_socket_streambuf<Protocol ASIO_SVC_TARG,
Time, TimeTraits ASIO_SVC_TARG1>* rdbuf() const
Clock, WaitTraits ASIO_SVC_TARG1>* rdbuf() const
{
return const_cast<basic_socket_streambuf<Protocol ASIO_SVC_TARG,
Time, TimeTraits ASIO_SVC_TARG1>*>(
Clock, WaitTraits ASIO_SVC_TARG1>*>(
&this->detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Time,
TimeTraits ASIO_SVC_TARG1>::streambuf_);
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>::streambuf_);
}
/// Get a reference to the underlying socket.
basic_socket<Protocol ASIO_SVC_TARG>& socket()
{
return rdbuf()->socket();
}
/// Get the last error associated with the stream.
@@ -232,7 +321,7 @@ public:
*/
const asio::error_code& error() const
{
return rdbuf()->puberror();
return rdbuf()->error();
}
#if !defined(ASIO_NO_DEPRECATED)
@@ -309,6 +398,12 @@ public:
rdbuf()->expires_from_now(expiry_time);
}
#endif // !defined(ASIO_NO_DEPRECATED)
private:
// Disallow copying and assignment.
basic_socket_iostream(const basic_socket_iostream&) ASIO_DELETED;
basic_socket_iostream& operator=(
const basic_socket_iostream&) ASIO_DELETED;
};
} // namespace asio
@@ -0,0 +1,695 @@
//
// basic_socket_streambuf.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2016 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 ASIO_BASIC_SOCKET_STREAMBUF_HPP
#define ASIO_BASIC_SOCKET_STREAMBUF_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#if !defined(ASIO_NO_IOSTREAM)
#include <streambuf>
#include <vector>
#include "asio/basic_socket.hpp"
#include "asio/basic_stream_socket.hpp"
#include "asio/detail/buffer_sequence_adapter.hpp"
#include "asio/detail/memory.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/io_context.hpp"
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/stream_socket_service.hpp"
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#if defined(ASIO_HAS_BOOST_DATE_TIME)
# if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/deadline_timer_service.hpp"
# else // defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/detail/deadline_timer_service.hpp"
# endif // defined(ASIO_ENABLE_OLD_SERVICES)
#else
# include "asio/steady_timer.hpp"
#endif
#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)
# include "asio/detail/variadic_templates.hpp"
// A macro that should expand to:
// template <typename T1, ..., typename Tn>
// basic_socket_streambuf* connect(T1 x1, ..., Tn xn)
// {
// init_buffers();
// typedef typename Protocol::resolver resolver_type;
// resolver_type resolver(socket().get_executor().context());
// connect_to_endpoints(
// resolver.resolve(x1, ..., xn, ec_));
// return !ec_ ? this : 0;
// }
// This macro should only persist within this file.
# define ASIO_PRIVATE_CONNECT_DEF(n) \
template <ASIO_VARIADIC_TPARAMS(n)> \
basic_socket_streambuf* connect(ASIO_VARIADIC_BYVAL_PARAMS(n)) \
{ \
init_buffers(); \
typedef typename Protocol::resolver resolver_type; \
resolver_type resolver(socket().get_executor().context()); \
connect_to_endpoints( \
resolver.resolve(ASIO_VARIADIC_BYVAL_ARGS(n), ec_)); \
return !ec_ ? this : 0; \
} \
/**/
#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)
#if !defined(ASIO_ENABLE_OLD_SERVICES)
# define ASIO_SVC_T1 detail::deadline_timer_service<traits_helper>
#endif // !defined(ASIO_ENABLE_OLD_SERVICES)
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
// A separate base class is used to ensure that the io_context member is
// initialised prior to the basic_socket_streambuf's basic_socket base class.
class socket_streambuf_io_context
{
protected:
socket_streambuf_io_context(io_context* ctx)
: default_io_context_(ctx)
{
}
shared_ptr<io_context> default_io_context_;
};
// A separate base class is used to ensure that the dynamically allocated
// buffers are constructed prior to the basic_socket_streambuf's basic_socket
// base class. This makes moving the socket is the last potentially throwing
// step in the streambuf's move constructor, giving the constructor a strong
// exception safety guarantee.
class socket_streambuf_buffers
{
protected:
socket_streambuf_buffers()
: get_buffer_(buffer_size),
put_buffer_(buffer_size)
{
}
enum { buffer_size = 512 };
std::vector<char> get_buffer_;
std::vector<char> put_buffer_;
};
} // namespace detail
#if !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)
#define ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL
// Forward declaration with defaulted arguments.
template <typename Protocol
ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
#if defined(ASIO_HAS_BOOST_DATE_TIME)
typename Clock = boost::posix_time::ptime,
typename WaitTraits = time_traits<Clock>
ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
#else
typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock>
ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
#endif
class basic_socket_streambuf;
#endif // !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)
/// Iostream streambuf for a socket.
#if defined(GENERATING_DOCUMENTATION)
template <typename Protocol,
typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock> >
#else // defined(GENERATING_DOCUMENTATION)
template <typename Protocol ASIO_SVC_TPARAM,
typename Clock, typename WaitTraits ASIO_SVC_TPARAM1>
#endif // defined(GENERATING_DOCUMENTATION)
class basic_socket_streambuf
: public std::streambuf,
private detail::socket_streambuf_io_context,
private detail::socket_streambuf_buffers,
#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
private basic_socket<Protocol ASIO_SVC_TARG>
#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
public basic_socket<Protocol ASIO_SVC_TARG>
#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
{
private:
// These typedefs are intended keep this class's implementation independent
// of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.
#if defined(ASIO_HAS_BOOST_DATE_TIME)
typedef WaitTraits traits_helper;
#else
typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;
#endif
public:
/// The protocol type.
typedef Protocol protocol_type;
/// The endpoint type.
typedef typename Protocol::endpoint endpoint_type;
/// The clock type.
typedef Clock clock_type;
#if defined(GENERATING_DOCUMENTATION)
/// (Deprecated: Use time_point.) The time type.
typedef typename WaitTraits::time_type time_type;
/// The time type.
typedef typename WaitTraits::time_point time_point;
/// (Deprecated: Use duration.) The duration type.
typedef typename WaitTraits::duration_type duration_type;
/// The duration type.
typedef typename WaitTraits::duration duration;
#else
# if !defined(ASIO_NO_DEPRECATED)
typedef typename traits_helper::time_type time_type;
typedef typename traits_helper::duration_type duration_type;
# endif // !defined(ASIO_NO_DEPRECATED)
typedef typename traits_helper::time_type time_point;
typedef typename traits_helper::duration_type duration;
#endif
/// Construct a basic_socket_streambuf without establishing a connection.
basic_socket_streambuf()
: detail::socket_streambuf_io_context(new io_context),
basic_socket<Protocol ASIO_SVC_TARG>(*default_io_context_),
expiry_time_(max_expiry_time())
{
init_buffers();
}
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Construct a basic_socket_streambuf from the supplied socket.
explicit basic_socket_streambuf(basic_stream_socket<protocol_type> s)
: detail::socket_streambuf_io_context(0),
basic_socket<Protocol ASIO_SVC_TARG>(std::move(s)),
expiry_time_(max_expiry_time())
{
init_buffers();
}
/// Move-construct a basic_socket_streambuf from another.
basic_socket_streambuf(basic_socket_streambuf&& other)
: detail::socket_streambuf_io_context(other),
basic_socket<Protocol ASIO_SVC_TARG>(std::move(other.socket())),
ec_(other.ec_),
expiry_time_(other.expiry_time_)
{
get_buffer_.swap(other.get_buffer_);
put_buffer_.swap(other.put_buffer_);
setg(other.eback(), other.gptr(), other.egptr());
setp(other.pptr(), other.epptr());
other.ec_ = asio::error_code();
other.expiry_time_ = max_expiry_time();
other.init_buffers();
}
/// Move-assign a basic_socket_streambuf from another.
basic_socket_streambuf& operator=(basic_socket_streambuf&& other)
{
this->close();
socket() = std::move(other.socket());
detail::socket_streambuf_io_context::operator=(other);
ec_ = other.ec_;
expiry_time_ = other.expiry_time_;
get_buffer_.swap(other.get_buffer_);
put_buffer_.swap(other.put_buffer_);
setg(other.eback(), other.gptr(), other.egptr());
setp(other.pptr(), other.epptr());
other.ec_ = asio::error_code();
other.expiry_time_ = max_expiry_time();
other.put_buffer_.resize(buffer_size);
other.init_buffers();
return *this;
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Destructor flushes buffered data.
virtual ~basic_socket_streambuf()
{
if (pptr() != pbase())
overflow(traits_type::eof());
}
/// Establish a connection.
/**
* This function establishes a connection to the specified endpoint.
*
* @return \c this if a connection was successfully established, a null
* pointer otherwise.
*/
basic_socket_streambuf* connect(const endpoint_type& endpoint)
{
init_buffers();
ec_ = asio::error_code();
this->connect_to_endpoints(&endpoint, &endpoint + 1);
return !ec_ ? this : 0;
}
#if defined(GENERATING_DOCUMENTATION)
/// Establish a connection.
/**
* This function automatically establishes a connection based on the supplied
* resolver query parameters. The arguments are used to construct a resolver
* query object.
*
* @return \c this if a connection was successfully established, a null
* pointer otherwise.
*/
template <typename T1, ..., typename TN>
basic_socket_streambuf* connect(T1 t1, ..., TN tn);
#elif defined(ASIO_HAS_VARIADIC_TEMPLATES)
template <typename... T>
basic_socket_streambuf* connect(T... x)
{
init_buffers();
typedef typename Protocol::resolver resolver_type;
resolver_type resolver(socket().get_executor().context());
connect_to_endpoints(resolver.resolve(x..., ec_));
return !ec_ ? this : 0;
}
#else
ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_CONNECT_DEF)
#endif
/// Close the connection.
/**
* @return \c this if a connection was successfully established, a null
* pointer otherwise.
*/
basic_socket_streambuf* close()
{
sync();
socket().close(ec_);
if (!ec_)
init_buffers();
return !ec_ ? this : 0;
}
/// Get a reference to the underlying socket.
basic_socket<Protocol ASIO_SVC_TARG>& socket()
{
return *this;
}
/// Get the last error associated with the stream buffer.
/**
* @return An \c error_code corresponding to the last error from the stream
* buffer.
*/
const asio::error_code& error() const
{
return ec_;
}
#if !defined(ASIO_NO_DEPRECATED)
/// (Deprecated: Use error().) Get the last error associated with the stream
/// buffer.
/**
* @return An \c error_code corresponding to the last error from the stream
* buffer.
*/
const asio::error_code& puberror() const
{
return error();
}
/// (Deprecated: Use expiry().) Get the stream buffer's expiry time as an
/// absolute time.
/**
* @return An absolute time value representing the stream buffer's expiry
* time.
*/
time_point expires_at() const
{
return expiry_time_;
}
#endif // !defined(ASIO_NO_DEPRECATED)
/// Get the stream buffer's expiry time as an absolute time.
/**
* @return An absolute time value representing the stream buffer's expiry
* time.
*/
time_point expiry() const
{
return expiry_time_;
}
/// Set the stream buffer's expiry time as an absolute time.
/**
* This function sets the expiry time associated with the stream. Stream
* operations performed after this time (where the operations cannot be
* completed using the internal buffers) will fail with the error
* asio::error::operation_aborted.
*
* @param expiry_time The expiry time to be used for the stream.
*/
void expires_at(const time_point& expiry_time)
{
expiry_time_ = expiry_time;
}
/// Set the stream buffer's expiry time relative to now.
/**
* This function sets the expiry time associated with the stream. Stream
* operations performed after this time (where the operations cannot be
* completed using the internal buffers) will fail with the error
* asio::error::operation_aborted.
*
* @param expiry_time The expiry time to be used for the timer.
*/
void expires_after(const duration& expiry_time)
{
expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time);
}
#if !defined(ASIO_NO_DEPRECATED)
/// (Deprecated: Use expiry().) Get the stream buffer's expiry time relative
/// to now.
/**
* @return A relative time value representing the stream buffer's expiry time.
*/
duration expires_from_now() const
{
return traits_helper::subtract(expires_at(), traits_helper::now());
}
/// (Deprecated: Use expires_after().) Set the stream buffer's expiry time
/// relative to now.
/**
* This function sets the expiry time associated with the stream. Stream
* operations performed after this time (where the operations cannot be
* completed using the internal buffers) will fail with the error
* asio::error::operation_aborted.
*
* @param expiry_time The expiry time to be used for the timer.
*/
void expires_from_now(const duration& expiry_time)
{
expiry_time_ = traits_helper::add(traits_helper::now(), expiry_time);
}
#endif // !defined(ASIO_NO_DEPRECATED)
protected:
int_type underflow()
{
#if defined(ASIO_WINDOWS_RUNTIME)
ec_ = asio::error::operation_not_supported;
return traits_type::eof();
#else // defined(ASIO_WINDOWS_RUNTIME)
if (gptr() != egptr())
return traits_type::eof();
for (;;)
{
// Check if we are past the expiry time.
if (traits_helper::less_than(expiry_time_, traits_helper::now()))
{
ec_ = asio::error::timed_out;
return traits_type::eof();
}
// Try to complete the operation without blocking.
if (!socket().native_non_blocking())
socket().native_non_blocking(true, ec_);
detail::buffer_sequence_adapter<mutable_buffer, mutable_buffer>
bufs(asio::buffer(get_buffer_) + putback_max);
detail::signed_size_type bytes = detail::socket_ops::recv(
socket().native_handle(), bufs.buffers(), bufs.count(), 0, ec_);
// Check if operation succeeded.
if (bytes > 0)
{
setg(&get_buffer_[0], &get_buffer_[0] + putback_max,
&get_buffer_[0] + putback_max + bytes);
return traits_type::to_int_type(*gptr());
}
// Check for EOF.
if (bytes == 0)
{
ec_ = asio::error::eof;
return traits_type::eof();
}
// Operation failed.
if (ec_ != asio::error::would_block
&& ec_ != asio::error::try_again)
return traits_type::eof();
// Wait for socket to become ready.
if (detail::socket_ops::poll_read(
socket().native_handle(), 0, timeout(), ec_) < 0)
return traits_type::eof();
}
#endif // defined(ASIO_WINDOWS_RUNTIME)
}
int_type overflow(int_type c)
{
#if defined(ASIO_WINDOWS_RUNTIME)
ec_ = asio::error::operation_not_supported;
return traits_type::eof();
#else // defined(ASIO_WINDOWS_RUNTIME)
char_type ch = traits_type::to_char_type(c);
// Determine what needs to be sent.
const_buffer output_buffer;
if (put_buffer_.empty())
{
if (traits_type::eq_int_type(c, traits_type::eof()))
return traits_type::not_eof(c); // Nothing to do.
output_buffer = asio::buffer(&ch, sizeof(char_type));
}
else
{
output_buffer = asio::buffer(pbase(),
(pptr() - pbase()) * sizeof(char_type));
}
while (output_buffer.size() > 0)
{
// Check if we are past the expiry time.
if (traits_helper::less_than(expiry_time_, traits_helper::now()))
{
ec_ = asio::error::timed_out;
return traits_type::eof();
}
// Try to complete the operation without blocking.
if (!socket().native_non_blocking())
socket().native_non_blocking(true, ec_);
detail::buffer_sequence_adapter<
const_buffer, const_buffer> bufs(output_buffer);
detail::signed_size_type bytes = detail::socket_ops::send(
socket().native_handle(), bufs.buffers(), bufs.count(), 0, ec_);
// Check if operation succeeded.
if (bytes > 0)
{
output_buffer += static_cast<std::size_t>(bytes);
continue;
}
// Operation failed.
if (ec_ != asio::error::would_block
&& ec_ != asio::error::try_again)
return traits_type::eof();
// Wait for socket to become ready.
if (detail::socket_ops::poll_write(
socket().native_handle(), 0, timeout(), ec_) < 0)
return traits_type::eof();
}
if (!put_buffer_.empty())
{
setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());
// If the new character is eof then our work here is done.
if (traits_type::eq_int_type(c, traits_type::eof()))
return traits_type::not_eof(c);
// Add the new character to the output buffer.
*pptr() = ch;
pbump(1);
}
return c;
#endif // defined(ASIO_WINDOWS_RUNTIME)
}
int sync()
{
return overflow(traits_type::eof());
}
std::streambuf* setbuf(char_type* s, std::streamsize n)
{
if (pptr() == pbase() && s == 0 && n == 0)
{
put_buffer_.clear();
setp(0, 0);
sync();
return this;
}
return 0;
}
private:
// Disallow copying and assignment.
basic_socket_streambuf(const basic_socket_streambuf&) ASIO_DELETED;
basic_socket_streambuf& operator=(
const basic_socket_streambuf&) ASIO_DELETED;
void init_buffers()
{
setg(&get_buffer_[0],
&get_buffer_[0] + putback_max,
&get_buffer_[0] + putback_max);
if (put_buffer_.empty())
setp(0, 0);
else
setp(&put_buffer_[0], &put_buffer_[0] + put_buffer_.size());
}
int timeout() const
{
int64_t msec = traits_helper::to_posix_duration(
traits_helper::subtract(expiry_time_,
traits_helper::now())).total_milliseconds();
if (msec > (std::numeric_limits<int>::max)())
msec = (std::numeric_limits<int>::max)();
else if (msec < 0)
msec = 0;
return static_cast<int>(msec);
}
template <typename EndpointSequence>
void connect_to_endpoints(const EndpointSequence& endpoints)
{
this->connect_to_endpoints(endpoints.begin(), endpoints.end());
}
template <typename EndpointIterator>
void connect_to_endpoints(EndpointIterator begin, EndpointIterator end)
{
#if defined(ASIO_WINDOWS_RUNTIME)
ec_ = asio::error::operation_not_supported;
#else // defined(ASIO_WINDOWS_RUNTIME)
if (ec_)
return;
ec_ = asio::error::not_found;
for (EndpointIterator i = begin; i != end; ++i)
{
// Check if we are past the expiry time.
if (traits_helper::less_than(expiry_time_, traits_helper::now()))
{
ec_ = asio::error::timed_out;
return;
}
// Close and reopen the socket.
typename Protocol::endpoint ep(*i);
socket().close(ec_);
socket().open(ep.protocol(), ec_);
if (ec_)
continue;
// Try to complete the operation without blocking.
if (!socket().native_non_blocking())
socket().native_non_blocking(true, ec_);
detail::socket_ops::connect(socket().native_handle(),
ep.data(), ep.size(), ec_);
// Check if operation succeeded.
if (!ec_)
return;
// Operation failed.
if (ec_ != asio::error::in_progress
&& ec_ != asio::error::would_block)
continue;
// Wait for socket to become ready.
if (detail::socket_ops::poll_connect(
socket().native_handle(), timeout(), ec_) < 0)
continue;
// Get the error code from the connect operation.
int connect_error = 0;
size_t connect_error_len = sizeof(connect_error);
if (detail::socket_ops::getsockopt(socket().native_handle(), 0,
SOL_SOCKET, SO_ERROR, &connect_error, &connect_error_len, ec_)
== detail::socket_error_retval)
return;
// Check the result of the connect operation.
ec_ = asio::error_code(connect_error,
asio::error::get_system_category());
if (!ec_)
return;
}
#endif // defined(ASIO_WINDOWS_RUNTIME)
}
// Helper function to get the maximum expiry time.
static time_point max_expiry_time()
{
#if defined(ASIO_HAS_BOOST_DATE_TIME)
return boost::posix_time::pos_infin;
#else // defined(ASIO_HAS_BOOST_DATE_TIME)
return (time_point::max)();
#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
}
enum { putback_max = 8 };
asio::error_code ec_;
time_point expiry_time_;
};
} // namespace asio
#include "asio/detail/pop_options.hpp"
#if !defined(ASIO_ENABLE_OLD_SERVICES)
# undef ASIO_SVC_T1
#endif // !defined(ASIO_ENABLE_OLD_SERVICES)
#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)
# undef ASIO_PRIVATE_CONNECT_DEF
#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)
#endif // !defined(ASIO_NO_IOSTREAM)
#endif // ASIO_BASIC_SOCKET_STREAMBUF_HPP
@@ -2,7 +2,7 @@
// basic_stream_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -22,7 +22,10 @@
#include "asio/detail/handler_type_requirements.hpp"
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/stream_socket_service.hpp"
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/stream_socket_service.hpp"
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#include "asio/detail/push_options.hpp"
@@ -368,7 +371,7 @@ public:
this->get_service().async_send(
this->get_implementation(), buffers, 0,
init.handler);
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -432,7 +435,7 @@ public:
this->get_service().async_send(
this->get_implementation(), buffers, flags,
init.handler);
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -598,7 +601,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, 0, init.handler);
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -662,7 +665,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, flags, init.handler);
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -781,7 +784,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, 0, init.handler);
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -904,7 +907,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, 0, init.handler);
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -2,7 +2,7 @@
// basic_streambuf.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -119,8 +119,8 @@ public:
/// The type used to represent the output sequence as a list of buffers.
typedef implementation_defined mutable_buffers_type;
#else
typedef asio::const_buffers_1 const_buffers_type;
typedef asio::mutable_buffers_1 mutable_buffers_type;
typedef ASIO_CONST_BUFFER const_buffers_type;
typedef ASIO_MUTABLE_BUFFER mutable_buffers_type;
#endif
/// Construct a basic_streambuf object.
@@ -2,7 +2,7 @@
// basic_streambuf_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// basic_waitable_timer.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -22,24 +22,36 @@
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#include "asio/wait_traits.hpp"
#include "asio/waitable_timer_service.hpp"
#if defined(ASIO_HAS_MOVE)
# include <utility>
#endif // defined(ASIO_HAS_MOVE)
#if !defined(ASIO_ENABLE_OLD_SERVICES)
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/waitable_timer_service.hpp"
#else // defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/detail/chrono_time_traits.hpp"
# include "asio/detail/deadline_timer_service.hpp"
# define ASIO_SVC_T \
detail::deadline_timer_service< \
detail::chrono_time_traits<Clock, WaitTraits> >
#endif // !defined(ASIO_ENABLE_OLD_SERVICES)
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#include "asio/detail/push_options.hpp"
namespace asio {
#if !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
#define ASIO_BASIC_WAITABLE_TIMER_FWD_DECL
// Forward declaration with defaulted arguments.
template <typename Clock,
typename WaitTraits = asio::wait_traits<Clock>
ASIO_SVC_TPARAM_DEF2(= waitable_timer_service<Clock, WaitTraits>)>
class basic_waitable_timer;
#endif // !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
/// Provides waitable timer functionality.
/**
* The basic_waitable_timer class template provides the ability to perform a
@@ -132,9 +144,7 @@ namespace asio {
* @li If a wait handler is cancelled, the asio::error_code passed to
* it contains the value asio::error::operation_aborted.
*/
template <typename Clock,
typename WaitTraits = asio::wait_traits<Clock>
ASIO_SVC_TPARAM_DEF2(= waitable_timer_service<Clock, WaitTraits>)>
template <typename Clock, typename WaitTraits ASIO_SVC_TPARAM>
class basic_waitable_timer
: ASIO_SVC_ACCESS basic_io_object<ASIO_SVC_T>
{
@@ -670,7 +680,8 @@ public:
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
this->get_service().async_wait(this->get_implementation(), init.handler);
this->get_service().async_wait(this->get_implementation(),
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
@@ -2,7 +2,7 @@
// bind_executor.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -18,9 +18,11 @@
#include "asio/detail/config.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/detail/variadic_templates.hpp"
#include "asio/associated_executor.hpp"
#include "asio/associated_allocator.hpp"
#include "asio/async_result.hpp"
#include "asio/handler_type.hpp"
#include "asio/execution_context.hpp"
#include "asio/is_executor.hpp"
#include "asio/uses_executor.hpp"
#include "asio/detail/push_options.hpp"
@@ -166,27 +168,27 @@ class executor_binder_base<T, Executor, true>
protected:
template <typename E, typename U>
executor_binder_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u)
: Executor(ASIO_MOVE_CAST(E)(e)),
target_(executor_arg_t(), static_cast<const Executor&>(*this),
ASIO_MOVE_CAST(U)(u))
: executor_(ASIO_MOVE_CAST(E)(e)),
target_(executor_arg_t(), executor_, ASIO_MOVE_CAST(U)(u))
{
}
Executor executor_;
T target_;
};
template <typename T, typename Executor>
class executor_binder_base<T, Executor, false>
: protected Executor
{
protected:
template <typename E, typename U>
executor_binder_base(ASIO_MOVE_ARG(E) e, ASIO_MOVE_ARG(U) u)
: Executor(ASIO_MOVE_CAST(E)(e)),
: executor_(ASIO_MOVE_CAST(E)(e)),
target_(ASIO_MOVE_CAST(U)(u))
{
}
Executor executor_;
T target_;
};
@@ -393,7 +395,7 @@ public:
/// Obtain the associated executor.
executor_type get_executor() const ASIO_NOEXCEPT
{
return static_cast<const Executor&>(*this);
return this->executor_;
}
#if defined(GENERATING_DOCUMENTATION)
@@ -518,6 +520,35 @@ template <typename T, typename Executor>
struct uses_executor<executor_binder<T, Executor>, Executor>
: true_type {};
template <typename T, typename Executor, typename Signature>
class async_result<executor_binder<T, Executor>, Signature>
{
public:
typedef executor_binder<
typename async_result<T, Signature>::completion_handler_type, Executor>
completion_handler_type;
typedef typename async_result<T, Signature>::return_type return_type;
explicit async_result(executor_binder<T, Executor>& b)
: target_(b.get())
{
}
return_type get()
{
return target_.get();
}
private:
async_result(const async_result&) ASIO_DELETED;
async_result& operator=(const async_result&) ASIO_DELETED;
async_result<T, Signature> target_;
};
#if !defined(ASIO_NO_DEPRECATED)
template <typename T, typename Executor, typename Signature>
struct handler_type<executor_binder<T, Executor>, Signature>
{
@@ -545,6 +576,8 @@ private:
async_result<T> target_;
};
#endif // !defined(ASIO_NO_DEPRECATED)
template <typename T, typename Executor, typename Allocator>
struct associated_allocator<executor_binder<T, Executor>, Allocator>
{
@@ -2,7 +2,7 @@
// buffered_read_stream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -128,9 +128,10 @@ public:
}
/// Close the stream.
asio::error_code close(asio::error_code& ec)
ASIO_SYNC_OP_VOID close(asio::error_code& ec)
{
return next_layer_.close(ec);
next_layer_.close(ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Write the given data to the stream. Returns the number of bytes written.
@@ -158,14 +159,8 @@ public:
async_write_some(const ConstBufferSequence& buffers,
ASIO_MOVE_ARG(WriteHandler) handler)
{
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
next_layer_.async_write_some(buffers,
ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(WriteHandler,
void (asio::error_code, std::size_t)))(init.handler));
return init.result.get();
return next_layer_.async_write_some(buffers,
ASIO_MOVE_CAST(WriteHandler)(handler));
}
/// Fill the buffer with some data. Returns the number of bytes placed in the
@@ -2,7 +2,7 @@
// buffered_read_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// buffered_stream.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -119,9 +119,10 @@ public:
}
/// Close the stream.
asio::error_code close(asio::error_code& ec)
ASIO_SYNC_OP_VOID close(asio::error_code& ec)
{
return stream_impl_.close(ec);
stream_impl_.close(ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Flush all data from the buffer to the next layer. Returns the number of
@@ -2,7 +2,7 @@
// buffered_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// buffered_write_stream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -128,9 +128,10 @@ public:
}
/// Close the stream.
asio::error_code close(asio::error_code& ec)
ASIO_SYNC_OP_VOID close(asio::error_code& ec)
{
return next_layer_.close(ec);
next_layer_.close(ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Flush all data from the buffer to the next layer. Returns the number of
@@ -193,14 +194,8 @@ public:
async_read_some(const MutableBufferSequence& buffers,
ASIO_MOVE_ARG(ReadHandler) handler)
{
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
next_layer_.async_read_some(buffers,
ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(ReadHandler,
void (asio::error_code, std::size_t)))(init.handler));
return init.result.get();
return next_layer_.async_read_some(buffers,
ASIO_MOVE_CAST(ReadHandler)(handler));
}
/// Peek at the incoming data on the stream. Returns the number of bytes read.
@@ -2,7 +2,7 @@
// buffered_write_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// buffers_iterator.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -65,7 +65,44 @@ namespace detail
typedef buffers_iterator_types_helper<is_mutable> helper;
typedef typename helper::buffer_type buffer_type;
typedef typename helper::template byte_type<ByteType>::type byte_type;
typedef typename BufferSequence::const_iterator const_iterator;
};
template <typename ByteType>
struct buffers_iterator_types<mutable_buffer, ByteType>
{
typedef mutable_buffer buffer_type;
typedef ByteType byte_type;
typedef const mutable_buffer* const_iterator;
};
template <typename ByteType>
struct buffers_iterator_types<const_buffer, ByteType>
{
typedef const_buffer buffer_type;
typedef typename add_const<ByteType>::type byte_type;
typedef const const_buffer* const_iterator;
};
#if !defined(ASIO_NO_DEPRECATED)
template <typename ByteType>
struct buffers_iterator_types<mutable_buffers_1, ByteType>
{
typedef mutable_buffer buffer_type;
typedef ByteType byte_type;
typedef const mutable_buffer* const_iterator;
};
template <typename ByteType>
struct buffers_iterator_types<const_buffers_1, ByteType>
{
typedef const_buffer buffer_type;
typedef typename add_const<ByteType>::type byte_type;
typedef const const_buffer* const_iterator;
};
#endif // !defined(ASIO_NO_DEPRECATED)
}
/// A random access iterator over the bytes in a buffer sequence.
@@ -76,6 +113,9 @@ private:
typedef typename detail::buffers_iterator_types<
BufferSequence, ByteType>::buffer_type buffer_type;
typedef typename detail::buffers_iterator_types<BufferSequence,
ByteType>::const_iterator buffer_sequence_iterator_type;
public:
/// The type used for the distance between two iterators.
typedef std::ptrdiff_t difference_type;
@@ -130,9 +170,9 @@ public:
#endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
{
buffers_iterator new_iter;
new_iter.begin_ = buffers.begin();
new_iter.current_ = buffers.begin();
new_iter.end_ = buffers.end();
new_iter.begin_ = asio::buffer_sequence_begin(buffers);
new_iter.current_ = asio::buffer_sequence_begin(buffers);
new_iter.end_ = asio::buffer_sequence_end(buffers);
while (new_iter.current_ != new_iter.end_)
{
new_iter.current_buffer_ = *new_iter.current_;
@@ -150,9 +190,9 @@ public:
#endif // defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
{
buffers_iterator new_iter;
new_iter.begin_ = buffers.begin();
new_iter.current_ = buffers.begin();
new_iter.end_ = buffers.end();
new_iter.begin_ = asio::buffer_sequence_begin(buffers);
new_iter.current_ = asio::buffer_sequence_begin(buffers);
new_iter.end_ = asio::buffer_sequence_end(buffers);
while (new_iter.current_ != new_iter.end_)
{
buffer_type buffer = *new_iter.current_;
@@ -347,7 +387,7 @@ private:
}
// Find the previous non-empty buffer.
typename BufferSequence::const_iterator iter = current_;
buffer_sequence_iterator_type iter = current_;
while (iter != begin_)
{
--iter;
@@ -426,7 +466,7 @@ private:
}
// Find the previous non-empty buffer.
typename BufferSequence::const_iterator iter = current_;
buffer_sequence_iterator_type iter = current_;
while (iter != begin_)
{
--iter;
@@ -452,9 +492,9 @@ private:
buffer_type current_buffer_;
std::size_t current_buffer_position_;
typename BufferSequence::const_iterator begin_;
typename BufferSequence::const_iterator current_;
typename BufferSequence::const_iterator end_;
buffer_sequence_iterator_type begin_;
buffer_sequence_iterator_type current_;
buffer_sequence_iterator_type end_;
std::size_t position_;
};
@@ -2,7 +2,7 @@
// completion_condition.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// connect.hpp
// ~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// coroutine.hpp
// ~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// datagram_socket_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -113,17 +113,21 @@ public:
service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
}
// All socket services have access to each other's implementations.
template <typename Protocol1> friend class datagram_socket_service;
/// Move-construct a new datagram socket implementation from another protocol
/// type.
template <typename Protocol1>
void converting_move_construct(implementation_type& impl,
datagram_socket_service<Protocol1>& other_service,
typename datagram_socket_service<
Protocol1>::implementation_type& other_impl,
typename enable_if<is_convertible<
Protocol1, Protocol>::value>::type* = 0)
{
service_impl_.template converting_move_construct<Protocol1>(
impl, other_impl);
impl, other_service.service_impl_, other_impl);
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -134,22 +138,23 @@ public:
}
// Open a new datagram socket implementation.
asio::error_code open(implementation_type& impl,
ASIO_SYNC_OP_VOID open(implementation_type& impl,
const protocol_type& protocol, asio::error_code& ec)
{
if (protocol.type() == ASIO_OS_DEF(SOCK_DGRAM))
service_impl_.open(impl, protocol, ec);
else
ec = asio::error::invalid_argument;
return ec;
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Assign an existing native socket to a datagram socket.
asio::error_code assign(implementation_type& impl,
ASIO_SYNC_OP_VOID assign(implementation_type& impl,
const protocol_type& protocol, const native_handle_type& native_socket,
asio::error_code& ec)
{
return service_impl_.assign(impl, protocol, native_socket, ec);
service_impl_.assign(impl, protocol, native_socket, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the socket is open.
@@ -159,10 +164,18 @@ public:
}
/// Close a datagram socket implementation.
asio::error_code close(implementation_type& impl,
ASIO_SYNC_OP_VOID close(implementation_type& impl,
asio::error_code& ec)
{
return service_impl_.close(impl, ec);
service_impl_.close(impl, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Release ownership of the underlying socket.
native_handle_type release(implementation_type& impl,
asio::error_code& ec)
{
return service_impl_.release(impl, ec);
}
/// Get the native socket implementation.
@@ -172,10 +185,11 @@ public:
}
/// Cancel all asynchronous operations associated with the socket.
asio::error_code cancel(implementation_type& impl,
ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
asio::error_code& ec)
{
return service_impl_.cancel(impl, ec);
service_impl_.cancel(impl, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the socket is at the out-of-band data mark.
@@ -193,17 +207,19 @@ public:
}
// Bind the datagram socket to the specified local endpoint.
asio::error_code bind(implementation_type& impl,
ASIO_SYNC_OP_VOID bind(implementation_type& impl,
const endpoint_type& endpoint, asio::error_code& ec)
{
return service_impl_.bind(impl, endpoint, ec);
service_impl_.bind(impl, endpoint, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Connect the datagram socket to the specified endpoint.
asio::error_code connect(implementation_type& impl,
ASIO_SYNC_OP_VOID connect(implementation_type& impl,
const endpoint_type& peer_endpoint, asio::error_code& ec)
{
return service_impl_.connect(impl, peer_endpoint, ec);
service_impl_.connect(impl, peer_endpoint, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Start an asynchronous connect.
@@ -217,33 +233,36 @@ public:
async_completion<ConnectHandler,
void (asio::error_code)> init(handler);
service_impl_.async_connect(impl, peer_endpoint, init.handler);
service_impl_.async_connect(impl, peer_endpoint, init.completion_handler);
return init.result.get();
}
/// Set a socket option.
template <typename SettableSocketOption>
asio::error_code set_option(implementation_type& impl,
ASIO_SYNC_OP_VOID set_option(implementation_type& impl,
const SettableSocketOption& option, asio::error_code& ec)
{
return service_impl_.set_option(impl, option, ec);
service_impl_.set_option(impl, option, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get a socket option.
template <typename GettableSocketOption>
asio::error_code get_option(const implementation_type& impl,
ASIO_SYNC_OP_VOID get_option(const implementation_type& impl,
GettableSocketOption& option, asio::error_code& ec) const
{
return service_impl_.get_option(impl, option, ec);
service_impl_.get_option(impl, option, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Perform an IO control command on the socket.
template <typename IoControlCommand>
asio::error_code io_control(implementation_type& impl,
ASIO_SYNC_OP_VOID io_control(implementation_type& impl,
IoControlCommand& command, asio::error_code& ec)
{
return service_impl_.io_control(impl, command, ec);
service_impl_.io_control(impl, command, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the socket.
@@ -253,10 +272,11 @@ public:
}
/// Sets the non-blocking mode of the socket.
asio::error_code non_blocking(implementation_type& impl,
ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl,
bool mode, asio::error_code& ec)
{
return service_impl_.non_blocking(impl, mode, ec);
service_impl_.non_blocking(impl, mode, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the native socket implementation.
@@ -266,10 +286,11 @@ public:
}
/// Sets the non-blocking mode of the native socket implementation.
asio::error_code native_non_blocking(implementation_type& impl,
ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl,
bool mode, asio::error_code& ec)
{
return service_impl_.native_non_blocking(impl, mode, ec);
service_impl_.native_non_blocking(impl, mode, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get the local endpoint.
@@ -287,18 +308,20 @@ public:
}
/// Disable sends or receives on the socket.
asio::error_code shutdown(implementation_type& impl,
ASIO_SYNC_OP_VOID shutdown(implementation_type& impl,
socket_base::shutdown_type what, asio::error_code& ec)
{
return service_impl_.shutdown(impl, what, ec);
service_impl_.shutdown(impl, what, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Wait for the socket to become ready to read, ready to write, or to have
/// pending error conditions.
asio::error_code wait(implementation_type& impl,
ASIO_SYNC_OP_VOID wait(implementation_type& impl,
socket_base::wait_type w, asio::error_code& ec)
{
return service_impl_.wait(impl, w, ec);
service_impl_.wait(impl, w, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Asynchronously wait for the socket to become ready to read, ready to
@@ -312,7 +335,7 @@ public:
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
service_impl_.async_wait(impl, w, init.handler);
service_impl_.async_wait(impl, w, init.completion_handler);
return init.result.get();
}
@@ -337,7 +360,7 @@ public:
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
service_impl_.async_send(impl, buffers, flags, init.handler);
service_impl_.async_send(impl, buffers, flags, init.completion_handler);
return init.result.get();
}
@@ -364,7 +387,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
service_impl_.async_send_to(impl, buffers,
destination, flags, init.handler);
destination, flags, init.completion_handler);
return init.result.get();
}
@@ -390,7 +413,7 @@ public:
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
service_impl_.async_receive(impl, buffers, flags, init.handler);
service_impl_.async_receive(impl, buffers, flags, init.completion_handler);
return init.result.get();
}
@@ -418,7 +441,7 @@ public:
void (asio::error_code, std::size_t)> init(handler);
service_impl_.async_receive_from(impl, buffers,
sender_endpoint, flags, init.handler);
sender_endpoint, flags, init.completion_handler);
return init.result.get();
}
@@ -2,7 +2,7 @@
// deadline_timer.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// deadline_timer_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -145,7 +145,7 @@ public:
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
service_impl_.async_wait(impl, init.handler);
service_impl_.async_wait(impl, init.completion_handler);
return init.result.get();
}
@@ -2,7 +2,7 @@
// defer.hpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/array.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/array_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/assert.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/atomic_count.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/base_from_completion_cond.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/bind_handler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/buffer_resize_guard.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/buffer_sequence_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -27,11 +27,12 @@ namespace detail {
class buffer_sequence_adapter_base
{
protected:
#if defined(ASIO_WINDOWS_RUNTIME)
public:
// The maximum number of buffers to support in a single operation.
enum { max_buffers = 1 };
protected:
typedef Windows::Storage::Streams::IBuffer^ native_buffer_type;
ASIO_DECL static void init_native_buffer(
@@ -42,9 +43,11 @@ protected:
native_buffer_type& buf,
const asio::const_buffer& buffer);
#elif defined(ASIO_WINDOWS) || defined(__CYGWIN__)
public:
// The maximum number of buffers to support in a single operation.
enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
protected:
typedef WSABUF native_buffer_type;
static void init_native_buffer(WSABUF& buf,
@@ -61,9 +64,11 @@ protected:
buf.len = static_cast<ULONG>(buffer.size());
}
#else // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
public:
// The maximum number of buffers to support in a single operation.
enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
protected:
typedef iovec native_buffer_type;
static void init_iov_base(void*& base, void* addr)
@@ -102,14 +107,9 @@ public:
explicit buffer_sequence_adapter(const Buffers& buffer_sequence)
: count_(0), total_buffer_size_(0)
{
typename Buffers::const_iterator iter = buffer_sequence.begin();
typename Buffers::const_iterator end = buffer_sequence.end();
for (; iter != end && count_ < max_buffers; ++iter, ++count_)
{
Buffer buffer(*iter);
init_native_buffer(buffers_[count_], buffer);
total_buffer_size_ += buffer.size();
}
buffer_sequence_adapter::init(
asio::buffer_sequence_begin(buffer_sequence),
asio::buffer_sequence_end(buffer_sequence));
}
native_buffer_type* buffers()
@@ -122,6 +122,11 @@ public:
return count_;
}
std::size_t total_size() const
{
return total_buffer_size_;
}
bool all_empty() const
{
return total_buffer_size_ == 0;
@@ -129,8 +134,42 @@ public:
static bool all_empty(const Buffers& buffer_sequence)
{
typename Buffers::const_iterator iter = buffer_sequence.begin();
typename Buffers::const_iterator end = buffer_sequence.end();
return buffer_sequence_adapter::all_empty(
asio::buffer_sequence_begin(buffer_sequence),
asio::buffer_sequence_end(buffer_sequence));
}
static void validate(const Buffers& buffer_sequence)
{
buffer_sequence_adapter::validate(
asio::buffer_sequence_begin(buffer_sequence),
asio::buffer_sequence_end(buffer_sequence));
}
static Buffer first(const Buffers& buffer_sequence)
{
return buffer_sequence_adapter::first(
asio::buffer_sequence_begin(buffer_sequence),
asio::buffer_sequence_end(buffer_sequence));
}
private:
template <typename Iterator>
void init(Iterator begin, Iterator end)
{
Iterator iter = begin;
for (; iter != end && count_ < max_buffers; ++iter, ++count_)
{
Buffer buffer(*iter);
init_native_buffer(buffers_[count_], buffer);
total_buffer_size_ += buffer.size();
}
}
template <typename Iterator>
static bool all_empty(Iterator begin, Iterator end)
{
Iterator iter = begin;
std::size_t i = 0;
for (; iter != end && i < max_buffers; ++iter, ++i)
if (Buffer(*iter).size() > 0)
@@ -138,10 +177,10 @@ public:
return true;
}
static void validate(const Buffers& buffer_sequence)
template <typename Iterator>
static void validate(Iterator begin, Iterator end)
{
typename Buffers::const_iterator iter = buffer_sequence.begin();
typename Buffers::const_iterator end = buffer_sequence.end();
Iterator iter = begin;
for (; iter != end; ++iter)
{
Buffer buffer(*iter);
@@ -149,10 +188,10 @@ public:
}
}
static Buffer first(const Buffers& buffer_sequence)
template <typename Iterator>
static Buffer first(Iterator begin, Iterator end)
{
typename Buffers::const_iterator iter = buffer_sequence.begin();
typename Buffers::const_iterator end = buffer_sequence.end();
Iterator iter = begin;
for (; iter != end; ++iter)
{
Buffer buffer(*iter);
@@ -162,12 +201,117 @@ public:
return Buffer();
}
private:
native_buffer_type buffers_[max_buffers];
std::size_t count_;
std::size_t total_buffer_size_;
};
template <typename Buffer>
class buffer_sequence_adapter<Buffer, asio::mutable_buffer>
: buffer_sequence_adapter_base
{
public:
explicit buffer_sequence_adapter(
const asio::mutable_buffer& buffer_sequence)
{
init_native_buffer(buffer_, Buffer(buffer_sequence));
total_buffer_size_ = buffer_sequence.size();
}
native_buffer_type* buffers()
{
return &buffer_;
}
std::size_t count() const
{
return 1;
}
std::size_t total_size() const
{
return total_buffer_size_;
}
bool all_empty() const
{
return total_buffer_size_ == 0;
}
static bool all_empty(const asio::mutable_buffer& buffer_sequence)
{
return buffer_sequence.size() == 0;
}
static void validate(const asio::mutable_buffer& buffer_sequence)
{
buffer_sequence.data();
}
static Buffer first(const asio::mutable_buffer& buffer_sequence)
{
return Buffer(buffer_sequence);
}
private:
native_buffer_type buffer_;
std::size_t total_buffer_size_;
};
template <typename Buffer>
class buffer_sequence_adapter<Buffer, asio::const_buffer>
: buffer_sequence_adapter_base
{
public:
explicit buffer_sequence_adapter(
const asio::const_buffer& buffer_sequence)
{
init_native_buffer(buffer_, Buffer(buffer_sequence));
total_buffer_size_ = buffer_sequence.size();
}
native_buffer_type* buffers()
{
return &buffer_;
}
std::size_t count() const
{
return 1;
}
std::size_t total_size() const
{
return total_buffer_size_;
}
bool all_empty() const
{
return total_buffer_size_ == 0;
}
static bool all_empty(const asio::const_buffer& buffer_sequence)
{
return buffer_sequence.size() == 0;
}
static void validate(const asio::const_buffer& buffer_sequence)
{
buffer_sequence.data();
}
static Buffer first(const asio::const_buffer& buffer_sequence)
{
return Buffer(buffer_sequence);
}
private:
native_buffer_type buffer_;
std::size_t total_buffer_size_;
};
#if !defined(ASIO_NO_DEPRECATED)
template <typename Buffer>
class buffer_sequence_adapter<Buffer, asio::mutable_buffers_1>
: buffer_sequence_adapter_base
@@ -190,6 +334,11 @@ public:
return 1;
}
std::size_t total_size() const
{
return total_buffer_size_;
}
bool all_empty() const
{
return total_buffer_size_ == 0;
@@ -237,6 +386,11 @@ public:
return 1;
}
std::size_t total_size() const
{
return total_buffer_size_;
}
bool all_empty() const
{
return total_buffer_size_ == 0;
@@ -262,6 +416,8 @@ private:
std::size_t total_buffer_size_;
};
#endif // !defined(ASIO_NO_DEPRECATED)
template <typename Buffer, typename Elem>
class buffer_sequence_adapter<Buffer, boost::array<Elem, 2> >
: buffer_sequence_adapter_base
@@ -285,6 +441,11 @@ public:
return 2;
}
std::size_t total_size() const
{
return total_buffer_size_;
}
bool all_empty() const
{
return total_buffer_size_ == 0;
@@ -337,6 +498,11 @@ public:
return 2;
}
std::size_t total_size() const
{
return total_buffer_size_;
}
bool all_empty() const
{
return total_buffer_size_ == 0;
@@ -2,7 +2,7 @@
// detail/buffered_stream_storage.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/call_stack.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/chrono.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -38,11 +38,11 @@ using std::chrono::minutes;
using std::chrono::hours;
using std::chrono::time_point_cast;
#if defined(ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK)
typedef std::chrono::monotonic_clock system_clock;
typedef std::chrono::monotonic_clock steady_clock;
#else // defined(ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK)
using std::chrono::system_clock;
#endif // defined(ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK)
using std::chrono::steady_clock;
#endif // defined(ASIO_HAS_STD_CHRONO_MONOTONIC_CLOCK)
using std::chrono::system_clock;
using std::chrono::high_resolution_clock;
#elif defined(ASIO_HAS_BOOST_CHRONO)
using boost::chrono::duration;
@@ -2,7 +2,7 @@
// detail/chrono_time_traits.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/completion_handler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -0,0 +1,94 @@
//
// detail/concurrency_hint.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2016 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 ASIO_DETAIL_CONCURRENCY_HINT_HPP
#define ASIO_DETAIL_CONCURRENCY_HINT_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include "asio/detail/noncopyable.hpp"
// The concurrency hint ID and mask are used to identify when a "well-known"
// concurrency hint value has been passed to the io_context.
#define ASIO_CONCURRENCY_HINT_ID 0xA5100000u
#define ASIO_CONCURRENCY_HINT_ID_MASK 0xFFFF0000u
// If set, this bit indicates that the scheduler should perform locking.
#define ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER 0x1u
// If set, this bit indicates that the reactor should perform locking when
// managing descriptor registrations.
#define ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION 0x2u
// If set, this bit indicates that the reactor should perform locking for I/O.
#define ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_IO 0x4u
// Helper macro to determine if we have a special concurrency hint.
#define ASIO_CONCURRENCY_HINT_IS_SPECIAL(hint) \
((static_cast<unsigned>(hint) \
& ASIO_CONCURRENCY_HINT_ID_MASK) \
== ASIO_CONCURRENCY_HINT_ID)
// Helper macro to determine if locking is enabled for a given facility.
#define ASIO_CONCURRENCY_HINT_IS_LOCKING(facility, hint) \
(((static_cast<unsigned>(hint) \
& (ASIO_CONCURRENCY_HINT_ID_MASK \
| ASIO_CONCURRENCY_HINT_LOCKING_ ## facility)) \
^ ASIO_CONCURRENCY_HINT_ID) != 0)
// This special concurrency hint disables locking in both the scheduler and
// reactor I/O. This hint has the following restrictions:
//
// - Care must be taken to ensure that all operations on the io_context and any
// of its associated I/O objects (such as sockets and timers) occur in only
// one thread at a time.
//
// - Asynchronous resolve operations fail with operation_not_supported.
//
// - If a signal_set is used with the io_context, signal_set objects cannot be
// used with any other io_context in the program.
#define ASIO_CONCURRENCY_HINT_UNSAFE \
static_cast<int>(ASIO_CONCURRENCY_HINT_ID)
// This special concurrency hint disables locking in the reactor I/O. This hint
// has the following restrictions:
//
// - Care must be taken to ensure that run functions on the io_context, and all
// operations on the io_context's associated I/O objects (such as sockets and
// timers), occur in only one thread at a time.
#define ASIO_CONCURRENCY_HINT_UNSAFE_IO \
static_cast<int>(ASIO_CONCURRENCY_HINT_ID \
| ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER \
| ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION)
// The special concurrency hint provides full thread safety.
#define ASIO_CONCURRENCY_HINT_SAFE \
static_cast<int>(ASIO_CONCURRENCY_HINT_ID \
| ASIO_CONCURRENCY_HINT_LOCKING_SCHEDULER \
| ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_REGISTRATION \
| ASIO_CONCURRENCY_HINT_LOCKING_REACTOR_IO)
// This #define may be overridden at compile time to specify a program-wide
// default concurrency hint, used by the zero-argument io_context constructor.
#if !defined(ASIO_CONCURRENCY_HINT_DEFAULT)
# define ASIO_CONCURRENCY_HINT_DEFAULT -1
#endif // !defined(ASIO_CONCURRENCY_HINT_DEFAULT)
// This #define may be overridden at compile time to specify a program-wide
// concurrency hint, used by the one-argument io_context constructor when
// passed a value of 1.
#if !defined(ASIO_CONCURRENCY_HINT_1)
# define ASIO_CONCURRENCY_HINT_1 1
#endif // !defined(ASIO_CONCURRENCY_HINT_DEFAULT)
#endif // ASIO_DETAIL_CONCURRENCY_HINT_HPP
@@ -0,0 +1,112 @@
//
// detail/conditionally_enabled_event.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2016 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 ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP
#define ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include "asio/detail/conditionally_enabled_mutex.hpp"
#include "asio/detail/event.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/null_event.hpp"
#include "asio/detail/scoped_lock.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
// Mutex adapter used to conditionally enable or disable locking.
class conditionally_enabled_event
: private noncopyable
{
public:
// Constructor.
conditionally_enabled_event()
{
}
// Destructor.
~conditionally_enabled_event()
{
}
// Signal the event. (Retained for backward compatibility.)
void signal(conditionally_enabled_mutex::scoped_lock& lock)
{
if (lock.mutex_.enabled_)
event_.signal(lock);
}
// Signal all waiters.
void signal_all(conditionally_enabled_mutex::scoped_lock& lock)
{
if (lock.mutex_.enabled_)
event_.signal_all(lock);
}
// Unlock the mutex and signal one waiter.
void unlock_and_signal_one(
conditionally_enabled_mutex::scoped_lock& lock)
{
if (lock.mutex_.enabled_)
event_.unlock_and_signal_one(lock);
}
// If there's a waiter, unlock the mutex and signal it.
bool maybe_unlock_and_signal_one(
conditionally_enabled_mutex::scoped_lock& lock)
{
if (lock.mutex_.enabled_)
return event_.maybe_unlock_and_signal_one(lock);
else
return false;
}
// Reset the event.
void clear(conditionally_enabled_mutex::scoped_lock& lock)
{
if (lock.mutex_.enabled_)
event_.clear(lock);
}
// Wait for the event to become signalled.
void wait(conditionally_enabled_mutex::scoped_lock& lock)
{
if (lock.mutex_.enabled_)
event_.wait(lock);
else
null_event().wait(lock);
}
// Timed wait for the event to become signalled.
bool wait_for_usec(
conditionally_enabled_mutex::scoped_lock& lock, long usec)
{
if (lock.mutex_.enabled_)
return event_.wait_for_usec(lock, usec);
else
return null_event().wait_for_usec(lock, usec);
}
private:
asio::detail::event event_;
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_CONDITIONALLY_ENABLED_EVENT_HPP
@@ -0,0 +1,149 @@
//
// detail/conditionally_enabled_mutex.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2016 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 ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
#define ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include "asio/detail/mutex.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/scoped_lock.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
// Mutex adapter used to conditionally enable or disable locking.
class conditionally_enabled_mutex
: private noncopyable
{
public:
// Helper class to lock and unlock a mutex automatically.
class scoped_lock
: private noncopyable
{
public:
// Tag type used to distinguish constructors.
enum adopt_lock_t { adopt_lock };
// Constructor adopts a lock that is already held.
scoped_lock(conditionally_enabled_mutex& m, adopt_lock_t)
: mutex_(m),
locked_(m.enabled_)
{
}
// Constructor acquires the lock.
explicit scoped_lock(conditionally_enabled_mutex& m)
: mutex_(m)
{
if (m.enabled_)
{
mutex_.mutex_.lock();
locked_ = true;
}
else
locked_ = false;
}
// Destructor releases the lock.
~scoped_lock()
{
if (locked_)
mutex_.mutex_.unlock();
}
// Explicitly acquire the lock.
void lock()
{
if (mutex_.enabled_ && !locked_)
{
mutex_.mutex_.lock();
locked_ = true;
}
}
// Explicitly release the lock.
void unlock()
{
if (locked_)
{
mutex_.unlock();
locked_ = false;
}
}
// Test whether the lock is held.
bool locked() const
{
return locked_;
}
// Get the underlying mutex.
asio::detail::mutex& mutex()
{
return mutex_.mutex_;
}
private:
friend class conditionally_enabled_event;
conditionally_enabled_mutex& mutex_;
bool locked_;
};
// Constructor.
explicit conditionally_enabled_mutex(bool enabled)
: enabled_(enabled)
{
}
// Destructor.
~conditionally_enabled_mutex()
{
}
// Determine whether locking is enabled.
bool enabled() const
{
return enabled_;
}
// Lock the mutex.
void lock()
{
if (enabled_)
mutex_.lock();
}
// Unlock the mutex.
void unlock()
{
if (enabled_)
mutex_.unlock();
}
private:
friend class scoped_lock;
friend class conditionally_enabled_event;
asio::detail::mutex mutex_;
const bool enabled_;
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_CONDITIONALLY_ENABLED_MUTEX_HPP
@@ -2,7 +2,7 @@
// detail/config.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -65,7 +65,8 @@
#if !defined(ASIO_MSVC)
# if defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)
# define ASIO_MSVC BOOST_MSVC
# elif defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__EDG_VERSION__)
# elif defined(_MSC_VER) && (defined(__INTELLISENSE__) \
|| (!defined(__MWERKS__) && !defined(__EDG_VERSION__)))
# define ASIO_MSVC _MSC_VER
# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)
#endif // defined(ASIO_MSVC)
@@ -82,6 +83,11 @@
# endif // (__cplusplus >= 201103)
#endif // defined(__clang__)
// Android platform detection.
#if defined(__ANDROID__)
# include <android/api-level.h>
#endif // defined(__ANDROID__)
// Support move construction and assignment on compilers known to allow it.
#if !defined(ASIO_HAS_MOVE)
# if !defined(ASIO_DISABLE_MOVE)
@@ -569,6 +575,30 @@
# endif // !defined(ASIO_DISABLE_NULLPTR)
#endif // !defined(ASIO_HAS_NULLPTR)
// Standard library support for the C++11 allocator additions.
#if !defined(ASIO_HAS_CXX11_ALLOCATORS)
# if !defined(ASIO_DISABLE_CXX11_ALLOCATORS)
# if defined(__clang__)
# if defined(ASIO_HAS_CLANG_LIBCXX)
# define ASIO_HAS_CXX11_ALLOCATORS 1
# elif (__cplusplus >= 201103)
# define ASIO_HAS_CXX11_ALLOCATORS 1
# endif // (__cplusplus >= 201103)
# elif defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
# define ASIO_HAS_CXX11_ALLOCATORS 1
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
# if defined(ASIO_MSVC)
# if (_MSC_VER >= 1700)
# define ASIO_HAS_CXX11_ALLOCATORS 1
# endif // (_MSC_VER >= 1700)
# endif // defined(ASIO_MSVC)
# endif // !defined(ASIO_DISABLE_CXX11_ALLOCATORS)
#endif // !defined(ASIO_HAS_CXX11_ALLOCATORS)
// Standard library support for the cstdint header.
#if !defined(ASIO_HAS_CSTDINT)
# if !defined(ASIO_DISABLE_CSTDINT)
@@ -675,6 +705,55 @@
# endif // !defined(ASIO_DISABLE_STD_CALL_ONCE)
#endif // !defined(ASIO_HAS_STD_CALL_ONCE)
// Standard library support for futures.
#if !defined(ASIO_HAS_STD_FUTURE)
# if !defined(ASIO_DISABLE_STD_FUTURE)
# if defined(__clang__)
# if defined(ASIO_HAS_CLANG_LIBCXX)
# define ASIO_HAS_STD_FUTURE 1
# elif (__cplusplus >= 201103)
# if __has_include(<future>)
# define ASIO_HAS_STD_FUTURE 1
# endif // __has_include(<mutex>)
# endif // (__cplusplus >= 201103)
# endif // defined(__clang__)
# if defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
# define ASIO_HAS_STD_FUTURE 1
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
# if defined(ASIO_MSVC)
# if (_MSC_VER >= 1700)
# define ASIO_HAS_STD_FUTURE 1
# endif // (_MSC_VER >= 1700)
# endif // defined(ASIO_MSVC)
# endif // !defined(ASIO_DISABLE_STD_FUTURE)
#endif // !defined(ASIO_HAS_STD_FUTURE)
// Standard library support for experimental::string_view.
#if !defined(ASIO_HAS_STD_STRING_VIEW)
# if !defined(ASIO_DISABLE_STD_STRING_VIEW)
# if defined(__clang__)
# if (__cplusplus >= 201103)
# if __has_include(<experimental/string_view>)
# define ASIO_HAS_STD_STRING_VIEW 1
# define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
# endif // __has_include(<experimental/string_view>)
# endif // (__cplusplus >= 201103)
# endif // defined(__clang__)
# if defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)
# if (__cplusplus >= 201300)
# define ASIO_HAS_STD_STRING_VIEW 1
# define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
# endif // (__cplusplus >= 201300)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
# endif // !defined(ASIO_DISABLE_STD_STRING_VIEW)
#endif // !defined(ASIO_HAS_STD_STRING_VIEW)
// Windows App target. Windows but with a limited API.
#if !defined(ASIO_WINDOWS_APP)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603)
@@ -963,15 +1042,25 @@
// Can use getaddrinfo() and getnameinfo().
#if !defined(ASIO_HAS_GETADDRINFO)
# if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
# if !defined(ASIO_DISABLE_GETADDRINFO)
# if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
# define ASIO_HAS_GETADDRINFO 1
# elif defined(UNDER_CE)
# define ASIO_HAS_GETADDRINFO 1
# endif // defined(UNDER_CE)
# elif defined(__MACH__) && defined(__APPLE__)
# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
# if (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
# define ASIO_HAS_GETADDRINFO 1
# endif // (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
# else // defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
# define ASIO_HAS_GETADDRINFO 1
# endif // defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
# else // defined(__MACH__) && defined(__APPLE__)
# define ASIO_HAS_GETADDRINFO 1
# elif defined(UNDER_CE)
# define ASIO_HAS_GETADDRINFO 1
# endif // defined(UNDER_CE)
# elif !(defined(__MACH__) && defined(__APPLE__))
# define ASIO_HAS_GETADDRINFO 1
# endif // !(defined(__MACH__) && defined(__APPLE__))
# endif // defined(__MACH__) && defined(__APPLE__)
# endif // !defined(ASIO_DISABLE_GETADDRINFO)
#endif // !defined(ASIO_HAS_GETADDRINFO)
// Whether standard iostreams are disabled.
@@ -1180,4 +1269,35 @@
# define ASIO_SVC_ACCESS protected
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
// Helper macros to manage transition away from error_code return values.
#if defined(ASIO_NO_DEPRECATED)
# define ASIO_SYNC_OP_VOID void
# define ASIO_SYNC_OP_VOID_RETURN(e) return
#else // defined(ASIO_NO_DEPRECATED)
# define ASIO_SYNC_OP_VOID asio::error_code
# define ASIO_SYNC_OP_VOID_RETURN(e) return e
#endif // defined(ASIO_NO_DEPRECATED)
// Newer gcc, clang need special treatment to suppress unused typedef warnings.
#if defined(__clang__) && (__clang_major__ >= 7)
# define ASIO_UNUSED_TYPEDEF __attribute__((__unused__))
#elif defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)
# define ASIO_UNUSED_TYPEDEF __attribute__((__unused__))
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4)
#endif // defined(__GNUC__)
#if !defined(ASIO_UNUSED_TYPEDEF)
# define ASIO_UNUSED_TYPEDEF
#endif // !defined(ASIO_UNUSED_TYPEDEF)
// Some versions of gcc generate spurious warnings about unused variables.
#if defined(__GNUC__)
# if (__GNUC__ >= 4)
# define ASIO_UNUSED_VARIABLE __attribute__((__unused__))
# endif // (__GNUC__ >= 4)
#endif // defined(__GNUC__)
#if !defined(ASIO_UNUSED_VARIABLE)
# define ASIO_UNUSED_VARIABLE
#endif // !defined(ASIO_UNUSED_VARIABLE)
#endif // ASIO_DETAIL_CONFIG_HPP
@@ -0,0 +1,392 @@
//
// detail/consuming_buffers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2016 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 ASIO_DETAIL_CONSUMING_BUFFERS_HPP
#define ASIO_DETAIL_CONSUMING_BUFFERS_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include <cstddef>
#include "asio/buffer.hpp"
#include "asio/detail/buffer_sequence_adapter.hpp"
#include "asio/detail/limits.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
// A buffer sequence used to represent a subsequence of the buffers.
template <typename Buffer>
struct prepared_buffers
{
typedef Buffer value_type;
typedef const Buffer* const_iterator;
enum
{
max_buffers = buffer_sequence_adapter_base::max_buffers < 8
? buffer_sequence_adapter_base::max_buffers : 8
};
prepared_buffers() : count(0) {}
const_iterator begin() const { return elems; }
const_iterator end() const { return elems + count; }
Buffer elems[max_buffers];
std::size_t count;
};
// A proxy for a sub-range in a list of buffers.
template <typename Buffer, typename Buffers, typename Buffer_Iterator>
class consuming_buffers
{
public:
// Construct to represent the entire list of buffers.
explicit consuming_buffers(const Buffers& buffers)
: buffers_(buffers),
total_size_(asio::buffer_size(buffers)),
total_consumed_(0),
next_elem_(0),
next_elem_offset_(0)
{
}
// Determine if we are at the end of the buffers.
bool empty() const
{
return total_consumed_ >= total_size_;
}
// Get the buffer for a single transfer, with a size.
prepared_buffers<Buffer> prepare(std::size_t max_size)
{
prepared_buffers<Buffer> result;
Buffer_Iterator next = asio::buffer_sequence_begin(buffers_);
Buffer_Iterator end = asio::buffer_sequence_end(buffers_);
std::advance(next, next_elem_);
std::size_t elem_offset = next_elem_offset_;
while (next != end && max_size > 0 && result.count < result.max_buffers)
{
Buffer next_buf = Buffer(*next) + elem_offset;
result.elems[result.count] = asio::buffer(next_buf, max_size);
max_size -= result.elems[result.count].size();
elem_offset = 0;
if (result.elems[result.count].size() > 0)
++result.count;
++next;
}
return result;
}
// Consume the specified number of bytes from the buffers.
void consume(std::size_t size)
{
total_consumed_ += size;
Buffer_Iterator next = asio::buffer_sequence_begin(buffers_);
Buffer_Iterator end = asio::buffer_sequence_end(buffers_);
std::advance(next, next_elem_);
while (next != end && size > 0)
{
Buffer next_buf = Buffer(*next) + next_elem_offset_;
if (size < next_buf.size())
{
next_elem_offset_ += size;
size = 0;
}
else
{
size -= next_buf.size();
next_elem_offset_ = 0;
++next_elem_;
++next;
}
}
}
// Get the total number of bytes consumed from the buffers.
std::size_t total_consumed() const
{
return total_consumed_;
}
private:
Buffers buffers_;
std::size_t total_size_;
std::size_t total_consumed_;
std::size_t next_elem_;
std::size_t next_elem_offset_;
};
// Base class of all consuming_buffers specialisations for single buffers.
template <typename Buffer>
class consuming_single_buffer
{
public:
// Construct to represent the entire list of buffers.
template <typename Buffer1>
explicit consuming_single_buffer(const Buffer1& buffer)
: buffer_(buffer),
total_consumed_(0)
{
}
// Determine if we are at the end of the buffers.
bool empty() const
{
return total_consumed_ >= buffer_.size();
}
// Get the buffer for a single transfer, with a size.
Buffer prepare(std::size_t max_size)
{
return asio::buffer(buffer_ + total_consumed_, max_size);
}
// Consume the specified number of bytes from the buffers.
void consume(std::size_t size)
{
total_consumed_ += size;
}
// Get the total number of bytes consumed from the buffers.
std::size_t total_consumed() const
{
return total_consumed_;
}
private:
Buffer buffer_;
std::size_t total_consumed_;
};
template <>
class consuming_buffers<mutable_buffer, mutable_buffer, const mutable_buffer*>
: public consuming_single_buffer<ASIO_MUTABLE_BUFFER>
{
public:
explicit consuming_buffers(const mutable_buffer& buffer)
: consuming_single_buffer<ASIO_MUTABLE_BUFFER>(buffer)
{
}
};
template <>
class consuming_buffers<const_buffer, mutable_buffer, const mutable_buffer*>
: public consuming_single_buffer<ASIO_CONST_BUFFER>
{
public:
explicit consuming_buffers(const mutable_buffer& buffer)
: consuming_single_buffer<ASIO_CONST_BUFFER>(buffer)
{
}
};
template <>
class consuming_buffers<const_buffer, const_buffer, const const_buffer*>
: public consuming_single_buffer<ASIO_CONST_BUFFER>
{
public:
explicit consuming_buffers(const const_buffer& buffer)
: consuming_single_buffer<ASIO_CONST_BUFFER>(buffer)
{
}
};
#if !defined(ASIO_NO_DEPRECATED)
template <>
class consuming_buffers<mutable_buffer,
mutable_buffers_1, const mutable_buffer*>
: public consuming_single_buffer<ASIO_MUTABLE_BUFFER>
{
public:
explicit consuming_buffers(const mutable_buffers_1& buffer)
: consuming_single_buffer<ASIO_MUTABLE_BUFFER>(buffer)
{
}
};
template <>
class consuming_buffers<const_buffer, mutable_buffers_1, const mutable_buffer*>
: public consuming_single_buffer<ASIO_CONST_BUFFER>
{
public:
explicit consuming_buffers(const mutable_buffers_1& buffer)
: consuming_single_buffer<ASIO_CONST_BUFFER>(buffer)
{
}
};
template <>
class consuming_buffers<const_buffer, const_buffers_1, const const_buffer*>
: public consuming_single_buffer<ASIO_CONST_BUFFER>
{
public:
explicit consuming_buffers(const const_buffers_1& buffer)
: consuming_single_buffer<ASIO_CONST_BUFFER>(buffer)
{
}
};
#endif // !defined(ASIO_NO_DEPRECATED)
template <typename Buffer, typename Elem>
class consuming_buffers<Buffer, boost::array<Elem, 2>,
typename boost::array<Elem, 2>::const_iterator>
{
public:
// Construct to represent the entire list of buffers.
explicit consuming_buffers(const boost::array<Elem, 2>& buffers)
: buffers_(buffers),
total_consumed_(0)
{
}
// Determine if we are at the end of the buffers.
bool empty() const
{
return total_consumed_ >=
Buffer(buffers_[0]).size() + Buffer(buffers_[1]).size();
}
// Get the buffer for a single transfer, with a size.
boost::array<Buffer, 2> prepare(std::size_t max_size)
{
boost::array<Buffer, 2> result = {{
Buffer(buffers_[0]), Buffer(buffers_[1]) }};
std::size_t buffer0_size = result[0].size();
result[0] = asio::buffer(result[0] + total_consumed_, max_size);
result[1] = asio::buffer(
result[1] + (total_consumed_ < buffer0_size
? 0 : total_consumed_ - buffer0_size),
max_size - result[0].size());
return result;
}
// Consume the specified number of bytes from the buffers.
void consume(std::size_t size)
{
total_consumed_ += size;
}
// Get the total number of bytes consumed from the buffers.
std::size_t total_consumed() const
{
return total_consumed_;
}
private:
boost::array<Elem, 2> buffers_;
std::size_t total_consumed_;
};
#if defined(ASIO_HAS_STD_ARRAY)
template <typename Buffer, typename Elem>
class consuming_buffers<Buffer, std::array<Elem, 2>,
typename std::array<Elem, 2>::const_iterator>
{
public:
// Construct to represent the entire list of buffers.
explicit consuming_buffers(const std::array<Elem, 2>& buffers)
: buffers_(buffers),
total_consumed_(0)
{
}
// Determine if we are at the end of the buffers.
bool empty() const
{
return total_consumed_ >=
Buffer(buffers_[0]).size() + Buffer(buffers_[1]).size();
}
// Get the buffer for a single transfer, with a size.
std::array<Buffer, 2> prepare(std::size_t max_size)
{
std::array<Buffer, 2> result = {{
Buffer(buffers_[0]), Buffer(buffers_[1]) }};
std::size_t buffer0_size = result[0].size();
result[0] = asio::buffer(result[0] + total_consumed_, max_size);
result[1] = asio::buffer(
result[1] + (total_consumed_ < buffer0_size
? 0 : total_consumed_ - buffer0_size),
max_size - result[0].size());
return result;
}
// Consume the specified number of bytes from the buffers.
void consume(std::size_t size)
{
total_consumed_ += size;
}
// Get the total number of bytes consumed from the buffers.
std::size_t total_consumed() const
{
return total_consumed_;
}
private:
std::array<Elem, 2> buffers_;
std::size_t total_consumed_;
};
#endif // defined(ASIO_HAS_STD_ARRAY)
// Specialisation for null_buffers to ensure that the null_buffers type is
// always passed through to the underlying read or write operation.
template <typename Buffer>
class consuming_buffers<Buffer, null_buffers, const mutable_buffer*>
: public asio::null_buffers
{
public:
consuming_buffers(const null_buffers&)
{
// No-op.
}
bool empty()
{
return false;
}
null_buffers prepare(std::size_t)
{
return null_buffers();
}
void consume(std::size_t)
{
// No-op.
}
std::size_t total_consume() const
{
return 0;
}
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_CONSUMING_BUFFERS_HPP
@@ -2,7 +2,7 @@
// detail/cstddef.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/cstdint.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/date_time_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/deadline_timer_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/dependent_type.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/descriptor_ops.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/descriptor_read_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -44,15 +44,16 @@ public:
{
}
static bool do_perform(reactor_op* base)
static status do_perform(reactor_op* base)
{
descriptor_read_op_base* o(static_cast<descriptor_read_op_base*>(base));
buffer_sequence_adapter<asio::mutable_buffer,
MutableBufferSequence> bufs(o->buffers_);
bool result = descriptor_ops::non_blocking_read(o->descriptor_,
bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_);
status result = descriptor_ops::non_blocking_read(o->descriptor_,
bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_)
? done : not_done;
ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_read",
o->ec_, o->bytes_transferred_));
@@ -2,7 +2,7 @@
// detail/descriptor_write_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -44,15 +44,16 @@ public:
{
}
static bool do_perform(reactor_op* base)
static status do_perform(reactor_op* base)
{
descriptor_write_op_base* o(static_cast<descriptor_write_op_base*>(base));
buffer_sequence_adapter<asio::const_buffer,
ConstBufferSequence> bufs(o->buffers_);
bool result = descriptor_ops::non_blocking_write(o->descriptor_,
bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_);
status result = descriptor_ops::non_blocking_write(o->descriptor_,
bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_)
? done : not_done;
ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_write",
o->ec_, o->bytes_transferred_));
@@ -2,7 +2,7 @@
// detail/dev_poll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -158,7 +158,7 @@ private:
// Get the timeout value for the /dev/poll DP_POLL operation. The timeout
// value is returned as a number of milliseconds. A return value of -1
// indicates that the poll should block indefinitely.
ASIO_DECL int get_timeout();
ASIO_DECL int get_timeout(int msec);
// Cancel all operations associated with the given descriptor. The do_cancel
// function of the handler objects will be invoked. This function does not
@@ -2,7 +2,7 @@
// detail/epoll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -20,8 +20,8 @@
#if defined(ASIO_HAS_EPOLL)
#include "asio/detail/atomic_count.hpp"
#include "asio/detail/conditionally_enabled_mutex.hpp"
#include "asio/detail/limits.hpp"
#include "asio/detail/mutex.hpp"
#include "asio/detail/object_pool.hpp"
#include "asio/detail/op_queue.hpp"
#include "asio/detail/reactor_op.hpp"
@@ -40,6 +40,10 @@ namespace detail {
class epoll_reactor
: public execution_context_service_base<epoll_reactor>
{
private:
// The mutex type used by this reactor.
typedef conditionally_enabled_mutex mutex;
public:
enum op_types { read_op = 0, write_op = 1,
connect_op = 1, except_op = 2, max_ops = 3 };
@@ -58,9 +62,10 @@ public:
int descriptor_;
uint32_t registered_events_;
op_queue<reactor_op> op_queue_[max_ops];
bool try_speculative_[max_ops];
bool shutdown_;
ASIO_DECL descriptor_state();
ASIO_DECL descriptor_state(bool locking);
void set_ready_events(uint32_t events) { task_result_ = events; }
ASIO_DECL operation* perform_io(uint32_t events);
ASIO_DECL static void do_complete(
@@ -159,7 +164,7 @@ public:
typename timer_queue<Time_Traits>::per_timer_data& source);
// Run epoll once until interrupted or events are ready to be dispatched.
ASIO_DECL void run(bool block, op_queue<operation>& ops);
ASIO_DECL void run(long usec, op_queue<operation>& ops);
// Interrupt the select loop.
ASIO_DECL void interrupt();
@@ -193,7 +198,7 @@ private:
// Get the timeout value for the epoll_wait call. The timeout value is
// returned as a number of milliseconds. A return value of -1 indicates
// that epoll_wait should block indefinitely.
ASIO_DECL int get_timeout();
ASIO_DECL int get_timeout(int msec);
#if defined(ASIO_HAS_TIMERFD)
// Get the timeout value for the timer descriptor. The return value is the
@@ -2,7 +2,7 @@
// detail/event.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/eventfd_select_interrupter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -2,7 +2,7 @@
// detail/executor_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/fd_set_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -20,6 +20,8 @@
#if !defined(ASIO_HAS_THREADS) \
|| defined(ASIO_DISABLE_FENCED_BLOCK)
# include "asio/detail/null_fenced_block.hpp"
#elif defined(ASIO_HAS_STD_ATOMIC)
# include "asio/detail/std_fenced_block.hpp"
#elif defined(__MACH__) && defined(__APPLE__)
# include "asio/detail/macos_fenced_block.hpp"
#elif defined(__sun)
@@ -48,6 +50,8 @@ namespace detail {
#if !defined(ASIO_HAS_THREADS) \
|| defined(ASIO_DISABLE_FENCED_BLOCK)
typedef null_fenced_block fenced_block;
#elif defined(ASIO_HAS_STD_ATOMIC)
typedef std_fenced_block fenced_block;
#elif defined(__MACH__) && defined(__APPLE__)
typedef macos_fenced_block fenced_block;
#elif defined(__sun)
@@ -2,7 +2,7 @@
// detail/functional.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/gcc_arm_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/gcc_hppa_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/gcc_sync_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/gcc_x86_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/global.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -2,7 +2,7 @@
// detail/handler_alloc_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)
@@ -59,6 +59,8 @@ template <typename Handler, typename T>
class hook_allocator
{
public:
typedef T value_type;
template <typename U>
struct rebind
{
@@ -95,6 +97,8 @@ template <typename Handler>
class hook_allocator<Handler, void>
{
public:
typedef void value_type;
template <typename U>
struct rebind
{
@@ -124,7 +128,9 @@ public:
{ \
typedef typename ::asio::associated_allocator<Handler, \
::asio::detail::hook_allocator<Handler, \
void> >::type::template rebind<op>::other allocator_type; \
void> >::type associated_allocator_type; \
typedef ASIO_REBIND_ALLOC( \
associated_allocator_type, op) allocator_type; \
Handler* h; \
op* v; \
op* p; \
@@ -161,7 +167,7 @@ public:
#define ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(op, alloc) \
struct ptr \
{ \
typename alloc::template rebind<op>::other a; \
ASIO_REBIND_ALLOC(alloc, op) a; \
void* v; \
op* p; \
~ptr() \
@@ -2,7 +2,7 @@
// detail/handler_cont_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2016 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)

Some files were not shown because too many files have changed in this diff Show More