diff --git a/CMakeLists.txt b/CMakeLists.txt index 33ff734..7fc1730 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,9 @@ project (signalrclient) include(CTest) +set(WERROR true CACHE BOOL "Enable warnings as errors.") +set(WALL true CACHE BOOL "Enable all warnings.") + if(NOT WIN32) set(EXTRA_FLAGS "-std=c++11 -fPIC -DNO_SIGNALRCLIENT_EXPORTS") else() diff --git a/include/signalrclient/http_client.h b/include/signalrclient/http_client.h index f5d0108..ec01720 100644 --- a/include/signalrclient/http_client.h +++ b/include/signalrclient/http_client.h @@ -36,6 +36,15 @@ namespace signalr http_response() {} http_response(http_response&& rhs) noexcept : status_code(rhs.status_code), content(std::move(rhs.content)) {} http_response(int code, const std::string& content) : status_code(code), content(content) {} + http_response(const http_response& rhs) : status_code(rhs.status_code), content(rhs.content) {} + + http_response& operator=(const http_response& rhs) + { + status_code = rhs.status_code; + content = rhs.content; + + return *this; + } http_response& operator=(http_response&& rhs) noexcept { diff --git a/include/signalrclient/log_writer.h b/include/signalrclient/log_writer.h index 3562209..ffaae94 100644 --- a/include/signalrclient/log_writer.h +++ b/include/signalrclient/log_writer.h @@ -13,5 +13,7 @@ namespace signalr public: // NOTE: the caller does not enforce thread safety of this call SIGNALRCLIENT_API virtual void write(const std::string &entry) = 0; + + virtual ~log_writer() {} }; } diff --git a/include/signalrclient/signalr_client_config.h b/include/signalrclient/signalr_client_config.h index bdad493..5337bb9 100644 --- a/include/signalrclient/signalr_client_config.h +++ b/include/signalrclient/signalr_client_config.h @@ -5,8 +5,11 @@ #pragma once #ifdef USE_CPPRESTSDK -#include "cpprest/http_client.h" -#include "cpprest/ws_client.h" +#pragma warning (push) +#pragma warning (disable : 5204 4355 4625 4626 4868) +#include +#include +#pragma warning (pop) #endif #include "_exports.h" diff --git a/include/signalrclient/signalr_value.h b/include/signalrclient/signalr_value.h index 76fb9c7..d017e96 100644 --- a/include/signalrclient/signalr_value.h +++ b/include/signalrclient/signalr_value.h @@ -180,8 +180,22 @@ namespace signalr double number; std::map map; + // constructor of types in union are not implicitly called + // this is expected as we only construct a single type in the union once we know + // what that type is when constructing the signalr_value type. +#pragma warning (push) +#pragma warning (disable: 4582) storage() {} +#pragma warning (pop) + + storage(const storage&) = delete; + storage& operator=(const storage&) = delete; + + // destructor is not implicitly called +#pragma warning (push) +#pragma warning (disable: 4583) ~storage() {} +#pragma warning (pop) }; storage mStorage; diff --git a/src/signalrclient/CMakeLists.txt b/src/signalrclient/CMakeLists.txt index cad57f4..de8b7a5 100644 --- a/src/signalrclient/CMakeLists.txt +++ b/src/signalrclient/CMakeLists.txt @@ -31,6 +31,40 @@ include_directories( add_library (signalrclient SHARED ${SOURCES}) +if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + if(WERROR) + target_compile_options(signalrclient PRIVATE /WX) + endif() + if(WALL) + target_compile_options(signalrclient PRIVATE /Wall) + endif() + target_compile_options(signalrclient PRIVATE + /wd4820 # padding added after data member + /wd4514 # unreferenced inline function removed + /wd5045 # compiler will insert Spectre mitigation if /Qspectre switch is added + /wd4464 # relative include paths + /wd4711 # function 'x' selected for automatic inline expansion + /wd4710 # function not inlined + /experimental:external /external:anglebrackets /external:templates- /external:W0 + /GR- # disable run-time type information + /guard:cf # enable control-flow guard + /EHa # enable C++ EH (w/ SEH exceptions) + ) +else() + if(WERROR) + target_compile_options(signalrclient PRIVATE -Werror) + endif() + if(WALL) + target_compile_options(signalrclient PRIVATE -Wall) + endif() + + # GCC on OSX has a bug with exceptions and no-rtti that can cause crashes + if(NOT APPLE) + target_compile_options(signalrclient PRIVATE -fno-rtti) + endif() + target_compile_options(signalrclient PRIVATE -Wextra -Wpedantic -Wno-unknown-pragmas) +endif() + if(NOT USE_CPPRESTSDK) target_link_libraries(signalrclient) else() diff --git a/src/signalrclient/cancellation_token.h b/src/signalrclient/cancellation_token.h index 5de98f3..c738b63 100644 --- a/src/signalrclient/cancellation_token.h +++ b/src/signalrclient/cancellation_token.h @@ -24,6 +24,9 @@ namespace signalr { } + cancellation_token(const cancellation_token&) = delete; + cancellation_token& operator=(const cancellation_token&) = delete; + void cancel() { std::lock_guard lock(m_lock); diff --git a/src/signalrclient/case_insensitive_comparison_utils.h b/src/signalrclient/case_insensitive_comparison_utils.h index b127361..a6a271c 100644 --- a/src/signalrclient/case_insensitive_comparison_utils.h +++ b/src/signalrclient/case_insensitive_comparison_utils.h @@ -21,7 +21,7 @@ namespace signalr return false; } - for (int i = 0; i < s1.size(); ++i) + for (unsigned i = 0; i < s1.size(); ++i) { if (std::toupper(s1[i]) != std::toupper(s2[i])) { @@ -41,7 +41,7 @@ namespace signalr std::hash hasher; for (const auto& c : s) { - hash ^= hasher(std::toupper(c)) + (hash << 5) + (hash >> 2); + hash ^= hasher(static_cast(std::toupper(c))) + (hash << 5) + (hash >> 2); } return hash; diff --git a/src/signalrclient/completion_event.h b/src/signalrclient/completion_event.h index 8c9c776..a709963 100644 --- a/src/signalrclient/completion_event.h +++ b/src/signalrclient/completion_event.h @@ -4,13 +4,19 @@ #pragma once +#pragma warning (push) +#pragma warning (disable : 5204 4355) #include +#pragma warning (pop) namespace signalr { class completion_event_impl : public std::enable_shared_from_this { public: + completion_event_impl(const completion_event_impl&) = delete; + completion_event_impl& operator=(const completion_event_impl&) = delete; + static std::shared_ptr create() { return std::shared_ptr(new completion_event_impl()); diff --git a/src/signalrclient/connection_impl.cpp b/src/signalrclient/connection_impl.cpp index 271b62c..27b3fe7 100644 --- a/src/signalrclient/connection_impl.cpp +++ b/src/signalrclient/connection_impl.cpp @@ -13,7 +13,6 @@ #include "signalrclient/signalr_exception.h" #include "default_http_client.h" #include "case_insensitive_comparison_utils.h" -#include "make_unique.h" #include "completion_event.h" #include #include "signalrclient/websocket_client.h" @@ -21,13 +20,6 @@ namespace signalr { - // unnamed namespace makes it invisble outside this translation unit - namespace - { - // this is a workaround for a compiler bug where mutable lambdas won't sometimes compile - static void log(const logger& logger, trace_level level, const std::string& entry); - } - std::shared_ptr connection_impl::create(const std::string& url, trace_level trace_level, const std::shared_ptr& log_writer) { return connection_impl::create(url, trace_level, log_writer, nullptr, nullptr); @@ -259,8 +251,7 @@ namespace signalr } catch (const std::exception& e) { - auto canceled = dynamic_cast(&e); - if (canceled) + if (token->is_canceled()) { connection->m_logger.log(trace_level::info, "starting the connection has been canceled."); diff --git a/src/signalrclient/default_http_client.cpp b/src/signalrclient/default_http_client.cpp index 10fdc92..fc9e946 100644 --- a/src/signalrclient/default_http_client.cpp +++ b/src/signalrclient/default_http_client.cpp @@ -7,7 +7,10 @@ #ifdef USE_CPPRESTSDK #include "default_http_client.h" #include -#include "cpprest/http_client.h" +#pragma warning (push) +#pragma warning (disable : 5204 4355 4625 4626 4868) +#include +#pragma warning (pop) namespace signalr { diff --git a/src/signalrclient/default_websocket_client.cpp b/src/signalrclient/default_websocket_client.cpp index dd70b5c..f7c83dc 100644 --- a/src/signalrclient/default_websocket_client.cpp +++ b/src/signalrclient/default_websocket_client.cpp @@ -52,6 +52,7 @@ namespace signalr { try { + task.get(); callback(nullptr); } catch (...) diff --git a/src/signalrclient/default_websocket_client.h b/src/signalrclient/default_websocket_client.h index 3619d76..45e849b 100644 --- a/src/signalrclient/default_websocket_client.h +++ b/src/signalrclient/default_websocket_client.h @@ -6,7 +6,10 @@ #ifdef USE_CPPRESTSDK -#include "cpprest/ws_client.h" +#pragma warning (push) +#pragma warning (disable : 5204 4355 4625 4626 4868) +#include +#pragma warning (pop) #include "signalrclient/signalr_client_config.h" #include "signalrclient/websocket_client.h" diff --git a/src/signalrclient/hub_connection_impl.cpp b/src/signalrclient/hub_connection_impl.cpp index 0c6225d..fb11257 100644 --- a/src/signalrclient/hub_connection_impl.cpp +++ b/src/signalrclient/hub_connection_impl.cpp @@ -7,7 +7,6 @@ #include "signalrclient/hub_exception.h" #include "trace_log_writer.h" #include "signalrclient/signalr_exception.h" -#include "make_unique.h" #include "json_hub_protocol.h" #include "message_type.h" #include "handshake_protocol.h" @@ -40,7 +39,7 @@ namespace signalr : m_connection(connection_impl::create(url, trace_level, log_writer, http_client, websocket_factory)), m_logger(log_writer, trace_level), m_callback_manager(signalr::value(std::map { { std::string("error"), std::string("connection went out of scope before invocation result was received") } })), - m_disconnected([]() noexcept {}), m_handshakeReceived(false), m_protocol(std::make_shared()) + m_handshakeReceived(false), m_disconnected([]() noexcept {}), m_protocol(std::make_shared()) {} void hub_connection_impl::initialize() diff --git a/src/signalrclient/json_hub_protocol.cpp b/src/signalrclient/json_hub_protocol.cpp index 5f104a7..e3ee8de 100644 --- a/src/signalrclient/json_hub_protocol.cpp +++ b/src/signalrclient/json_hub_protocol.cpp @@ -7,7 +7,6 @@ #include "message_type.h" #include "json_helpers.h" #include "signalrclient/signalr_exception.h" -#include "json/json.h" namespace signalr { @@ -84,6 +83,6 @@ namespace signalr break; } - return std::move(value); + return value; } } \ No newline at end of file diff --git a/src/signalrclient/logger.cpp b/src/signalrclient/logger.cpp index 313cad7..4f959ac 100644 --- a/src/signalrclient/logger.cpp +++ b/src/signalrclient/logger.cpp @@ -71,6 +71,10 @@ namespace signalr return "error"; case signalr::trace_level::info: return "info"; + case signalr::trace_level::none: + return "none"; + case signalr::trace_level::all: + return "all"; default: assert(false); return "(unknown)"; diff --git a/src/signalrclient/make_unique.h b/src/signalrclient/make_unique.h deleted file mode 100644 index 7a27d20..0000000 --- a/src/signalrclient/make_unique.h +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#pragma once - -#if defined (__GNUC__) - -#include - -namespace std -{ - template - std::unique_ptr make_unique(Args&&... args) - { - return std::unique_ptr(new T(std::forward(args)...)); - } -} -#endif diff --git a/src/signalrclient/signalr_client_config.cpp b/src/signalrclient/signalr_client_config.cpp index dc25f2d..1e2c219 100644 --- a/src/signalrclient/signalr_client_config.cpp +++ b/src/signalrclient/signalr_client_config.cpp @@ -4,10 +4,6 @@ #include "stdafx.h" #include "signalrclient/signalr_client_config.h" -#ifdef USE_CPPRESTSDK -#include "cpprest/http_client.h" -#include "cpprest/ws_client.h" -#endif namespace signalr { diff --git a/src/signalrclient/signalr_value.cpp b/src/signalrclient/signalr_value.cpp index b6208f0..a01e9c3 100644 --- a/src/signalrclient/signalr_value.cpp +++ b/src/signalrclient/signalr_value.cpp @@ -51,6 +51,7 @@ namespace signalr case value_type::map: new (&mStorage.map) std::map(); break; + case value_type::null: default: break; } @@ -121,6 +122,7 @@ namespace signalr case value_type::map: new (&mStorage.map) std::map(rhs.mStorage.map); break; + case value_type::null: default: break; } @@ -146,6 +148,7 @@ namespace signalr case value_type::map: new (&mStorage.map) std::map(std::move(rhs.mStorage.map)); break; + case value_type::null: default: break; } @@ -169,6 +172,9 @@ namespace signalr case value_type::map: mStorage.map.~map(); break; + case value_type::null: + case value_type::float64: + case value_type::boolean: default: break; } @@ -196,6 +202,7 @@ namespace signalr case value_type::map: new (&mStorage.map) std::map(rhs.mStorage.map); break; + case value_type::null: default: break; } @@ -225,6 +232,7 @@ namespace signalr case value_type::map: new (&mStorage.map) std::map(std::move(rhs.mStorage.map)); break; + case value_type::null: default: break; } diff --git a/src/signalrclient/stdafx.h b/src/signalrclient/stdafx.h index 97deeae..466cc9d 100644 --- a/src/signalrclient/stdafx.h +++ b/src/signalrclient/stdafx.h @@ -8,11 +8,7 @@ // prevents from defining min/max macros that conflict with std::min()/std::max() functions #define NOMINMAX - -#include - #define WIN32_LEAN_AND_MEAN - #include #endif diff --git a/src/signalrclient/transport_factory.cpp b/src/signalrclient/transport_factory.cpp index 579dbe7..2c0619c 100644 --- a/src/signalrclient/transport_factory.cpp +++ b/src/signalrclient/transport_factory.cpp @@ -4,7 +4,6 @@ #include "stdafx.h" #include "transport_factory.h" -#include "default_websocket_client.h" #include "websocket_transport.h" #include "signalrclient/websocket_client.h" diff --git a/src/signalrclient/websocket_transport.cpp b/src/signalrclient/websocket_transport.cpp index 36609ec..e1d84d2 100644 --- a/src/signalrclient/websocket_transport.cpp +++ b/src/signalrclient/websocket_transport.cpp @@ -7,7 +7,11 @@ #include "logger.h" #include "signalrclient/signalr_exception.h" #include "base_uri.h" + +#pragma warning (push) +#pragma warning (disable : 5204 4355) #include +#pragma warning (pop) namespace signalr { @@ -20,9 +24,9 @@ namespace signalr websocket_transport::websocket_transport(const std::function(const signalr_client_config&)>& websocket_client_factory, const signalr_client_config& signalr_client_config, const logger& logger) - : transport(logger), m_websocket_client_factory(websocket_client_factory), m_close_callback([](std::exception_ptr) {}), - m_process_response_callback([](std::string, std::exception_ptr) {}), m_receive_loop_cts(std::make_shared()), - m_signalr_client_config(signalr_client_config) + : transport(logger), m_websocket_client_factory(websocket_client_factory), m_process_response_callback([](std::string, std::exception_ptr) {}), + m_close_callback([](std::exception_ptr) {}), m_signalr_client_config(signalr_client_config), + m_receive_loop_cts(std::make_shared()) { // we use this cts to check if the receive loop is running so it should be // initially canceled to indicate that the receive loop is not running diff --git a/test/signalrclienttests/connection_impl_tests.cpp b/test/signalrclienttests/connection_impl_tests.cpp index 519c931..6ae2ce0 100644 --- a/test/signalrclienttests/connection_impl_tests.cpp +++ b/test/signalrclienttests/connection_impl_tests.cpp @@ -107,10 +107,10 @@ TEST(connection_impl_start, connection_state_is_connected_when_connection_establ TEST(connection_impl_start, connection_state_is_disconnected_when_connection_cannot_be_established) { - auto http_client = std::make_unique([](const std::string&, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string&, http_request) { return http_response{ 404, "" }; - }); + })); auto connection = connection_impl::create(create_uri(), trace_level::none, std::make_shared(), @@ -234,10 +234,10 @@ TEST(connection_impl_start, start_logs_exceptions) { std::shared_ptr writer(std::make_shared()); - auto http_client = std::make_unique([](const std::string&, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string&, http_request) { return http_response{ 404, "" }; - }); + })); auto connection = connection_impl::create(create_uri(), trace_level::errors, writer, @@ -266,10 +266,10 @@ TEST(connection_impl_start, start_logs_exceptions) TEST(connection_impl_start, start_propagates_exceptions_from_negotiate) { - auto http_client = std::make_unique([](const std::string&, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string&, http_request) { return http_response{ 404, "" }; - }); + })); auto connection = connection_impl::create(create_uri(), trace_level::none, std::make_shared(), @@ -374,10 +374,10 @@ TEST(connection_impl_start, start_fails_if_negotiate_request_fails) { std::shared_ptr writer(std::make_shared()); - auto http_client = std::make_unique([](const std::string&, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string&, http_request) { return http_response{ 400, "" }; - }); + })); auto websocket_client = std::make_shared(); @@ -406,7 +406,7 @@ TEST(connection_impl_start, start_fails_if_negotiate_response_has_error) { std::shared_ptr writer(std::make_shared()); - auto http_client = std::make_unique([](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string& url, http_request) { auto response_body = url.find("/negotiate") != std::string::npos @@ -414,7 +414,7 @@ TEST(connection_impl_start, start_fails_if_negotiate_response_has_error) : ""; return http_response{ 200, response_body }; - }); + })); auto connect_mre = manual_reset_event(); auto websocket_client = std::make_shared(); @@ -451,7 +451,7 @@ TEST(connection_impl_start, start_fails_if_negotiate_response_does_not_have_webs { std::shared_ptr writer(std::make_shared()); - auto http_client = std::make_unique([](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string& url, http_request) { auto response_body = url.find("/negotiate") != std::string::npos @@ -459,7 +459,7 @@ TEST(connection_impl_start, start_fails_if_negotiate_response_does_not_have_webs : ""; return http_response{ 200, response_body }; - }); + })); auto websocket_client = std::make_shared(); @@ -488,7 +488,7 @@ TEST(connection_impl_start, start_fails_if_negotiate_response_does_not_have_tran { std::shared_ptr writer(std::make_shared()); - auto http_client = std::make_unique([](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string& url, http_request) { auto response_body = url.find("/negotiate") != std::string::npos @@ -496,7 +496,7 @@ TEST(connection_impl_start, start_fails_if_negotiate_response_does_not_have_tran : ""; return http_response{ 200, response_body }; - }); + })); auto websocket_client = std::make_shared(); @@ -525,7 +525,7 @@ TEST(connection_impl_start, start_fails_if_negotiate_response_is_invalid) { std::shared_ptr writer(std::make_shared()); - auto http_client = std::make_unique([](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string& url, http_request) { auto response_body = url.find("/negotiate") != std::string::npos @@ -533,7 +533,7 @@ TEST(connection_impl_start, start_fails_if_negotiate_response_is_invalid) : ""; return http_response{ 200, response_body }; - }); + })); auto websocket_client = std::make_shared(); @@ -559,7 +559,7 @@ TEST(connection_impl_start, negotiate_follows_redirect) { std::shared_ptr writer(std::make_shared()); - auto http_client = std::make_unique([](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string& url, http_request) { std::string response_body = ""; if (url.find("/negotiate") != std::string::npos) @@ -576,7 +576,7 @@ TEST(connection_impl_start, negotiate_follows_redirect) } return http_response{ 200, response_body }; - }); + })); auto websocket_client = std::make_shared(); @@ -607,7 +607,7 @@ TEST(connection_impl_start, negotiate_redirect_uses_accessToken) std::shared_ptr writer(std::make_shared()); std::string accessToken; - auto http_client = std::make_unique([&accessToken](const std::string& url, http_request request) + auto http_client = std::unique_ptr(new test_http_client([&accessToken](const std::string& url, http_request request) { std::string response_body = ""; if (url.find("/negotiate") != std::string::npos) @@ -625,7 +625,7 @@ TEST(connection_impl_start, negotiate_redirect_uses_accessToken) accessToken = request.headers["Authorization"]; return http_response{ 200, response_body }; - }); + })); auto websocket_client = std::make_shared(); @@ -656,7 +656,7 @@ TEST(connection_impl_start, negotiate_fails_after_too_many_redirects) { std::shared_ptr writer(std::make_shared()); - auto http_client = std::make_unique([](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string& url, http_request) { std::string response_body = ""; if (url.find("/negotiate") != std::string::npos) @@ -666,7 +666,7 @@ TEST(connection_impl_start, negotiate_fails_after_too_many_redirects) } return http_response{ 200, response_body }; - }); + })); auto websocket_client = std::make_shared(); @@ -695,7 +695,7 @@ TEST(connection_impl_start, negotiate_fails_if_ProtocolVersion_in_response) { std::shared_ptr writer(std::make_shared()); - auto http_client = std::make_unique([](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string& url, http_request) { std::string response_body = ""; if (url.find("/negotiate") != std::string::npos) @@ -704,7 +704,7 @@ TEST(connection_impl_start, negotiate_fails_if_ProtocolVersion_in_response) } return http_response{ 200, response_body }; - }); + })); auto websocket_client = std::make_shared(); @@ -733,7 +733,7 @@ TEST(connection_impl_start, negotiate_redirect_does_not_overwrite_url) std::shared_ptr writer(std::make_shared()); int redirectCount = 0; - auto http_client = std::make_unique([&redirectCount](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([&redirectCount](const std::string& url, http_request) { std::string response_body = ""; if (url.find("/negotiate") != std::string::npos) @@ -751,7 +751,7 @@ TEST(connection_impl_start, negotiate_redirect_does_not_overwrite_url) } return http_response{ 200, response_body }; - }); + })); auto websocket_client = std::make_shared(); @@ -794,7 +794,7 @@ TEST(connection_impl_start, negotiate_redirect_uses_own_query_string) callback(std::make_exception_ptr(std::runtime_error("connecting failed"))); }); - auto http_client = std::make_unique([](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string& url, http_request) { std::string response_body = ""; if (url.find("/negotiate") != std::string::npos) @@ -811,7 +811,7 @@ TEST(connection_impl_start, negotiate_redirect_uses_own_query_string) } return http_response{ 200, response_body }; - }); + })); auto connection = connection_impl::create(create_uri("a=b&c=d"), trace_level::errors, writer, std::move(http_client), [websocket_client](const signalr_client_config&) { return websocket_client; }); @@ -848,7 +848,7 @@ TEST(connection_impl_start, negotiate_with_negotiateVersion_uses_connectionToken callback(std::make_exception_ptr(std::runtime_error("connecting failed"))); }); - auto http_client = std::make_unique([](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string& url, http_request) { std::string response_body = ""; if (url.find("/negotiate") != std::string::npos) @@ -859,7 +859,7 @@ TEST(connection_impl_start, negotiate_with_negotiateVersion_uses_connectionToken } return http_response{ 200, response_body }; - }); + })); auto connection = connection_impl::create(create_uri(), trace_level::errors, writer, std::move(http_client), [websocket_client](const signalr_client_config&) { return websocket_client; }); @@ -889,12 +889,12 @@ TEST(connection_impl_start, correct_connection_id_returned_with_negotiateVersion auto websocket_client = create_test_websocket_client( /* send function */ [](const std::string&, std::function callback) { callback(std::make_exception_ptr(std::runtime_error("should not be invoked"))); }, - /* connect function */[](const std::string& url, std::function callback) + /* connect function */[](const std::string&, std::function callback) { callback(nullptr); }); - auto http_client = std::make_unique([](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string& url, http_request) { std::string response_body = ""; if (url.find("/negotiate") != std::string::npos) @@ -905,7 +905,7 @@ TEST(connection_impl_start, correct_connection_id_returned_with_negotiateVersion } return http_response{ 200, response_body }; - }); + })); auto connection = connection_impl::create(create_uri(), trace_level::errors, writer, std::move(http_client), [websocket_client](const signalr_client_config&) { return websocket_client; }); @@ -1448,7 +1448,7 @@ TEST(connection_impl_stop, stop_cancels_ongoing_start_request) { auto disconnect_completed_event = std::make_shared(); - auto http_client = std::make_unique([](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string& url, http_request) { auto response_body = url.find("/negotiate") != std::string::npos @@ -1457,9 +1457,10 @@ TEST(connection_impl_stop, stop_cancels_ongoing_start_request) : ""; return http_response{ 200, response_body }; - }); + })); auto wait_for_start_mre = manual_reset_event(); + auto close_complete = manual_reset_event(); auto websocket_client = create_test_websocket_client( [](const std::string&, std::function callback) { callback(std::make_exception_ptr(std::exception())); }, @@ -1467,6 +1468,9 @@ TEST(connection_impl_stop, stop_cancels_ongoing_start_request) wait_for_start_mre.set(); disconnect_completed_event->wait(); callback(nullptr); + }, [&close_complete](std::function callback) { + callback(nullptr); + close_complete.set(); }); auto writer = std::shared_ptr{ std::make_shared() }; @@ -1496,22 +1500,24 @@ TEST(connection_impl_stop, stop_cancels_ongoing_start_request) } ASSERT_EQ(connection_state::disconnected, connection->get_connection_state()); + close_complete.get(); auto log_entries = std::dynamic_pointer_cast(writer)->get_log_entries(); - ASSERT_EQ(6U, log_entries.size()) << dump_vector(log_entries); + ASSERT_EQ(7U, log_entries.size()) << dump_vector(log_entries); ASSERT_EQ("[state change] disconnected -> connecting\n", remove_date_from_log_entry(log_entries[0])); ASSERT_EQ("[info ] [websocket transport] connecting to: ws://stop_cancels_ongoing_start_request/?id=f7707523-307d-4cba-9abf-3eef701241e8\n", remove_date_from_log_entry(log_entries[1])); ASSERT_EQ("[info ] stopping connection\n", remove_date_from_log_entry(log_entries[2])); ASSERT_EQ("[info ] acquired lock in shutdown()\n", remove_date_from_log_entry(log_entries[3])); ASSERT_EQ("[info ] starting the connection has been canceled.\n", remove_date_from_log_entry(log_entries[4])); ASSERT_EQ("[state change] connecting -> disconnected\n", remove_date_from_log_entry(log_entries[5])); + ASSERT_EQ("[info ] Stopping was ignored because the connection is already in the disconnected state.\n", remove_date_from_log_entry(log_entries[6])); } // Test races with start and stop TEST(connection_impl_stop, DISABLED_ongoing_start_request_canceled_if_connection_stopped_before_init_message_received) { auto stop_mre = manual_reset_event(); - auto http_client = std::make_unique([&stop_mre](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([&stop_mre](const std::string& url, http_request) { stop_mre.get(); @@ -1522,7 +1528,7 @@ TEST(connection_impl_stop, DISABLED_ongoing_start_request_canceled_if_connection : ""; return http_response{ 200, response_body }; - }); + })); auto websocket_client = create_test_websocket_client(); @@ -1671,7 +1677,7 @@ TEST(connection_impl_config, custom_headers_set_in_requests) { auto writer = std::shared_ptr{ std::make_shared() }; - auto http_client = std::make_unique([](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([](const std::string& url, http_request) { auto response_body = url.find("/negotiate") != std::string::npos @@ -1688,7 +1694,7 @@ TEST(connection_impl_config, custom_headers_set_in_requests) };*/ return http_response{ 200, response_body }; - }); + })); auto websocket_client = create_test_websocket_client(); @@ -1844,7 +1850,7 @@ TEST(connection_id, connection_id_reset_when_starting_connection) auto websocket_client = create_test_websocket_client(); - auto http_client = std::make_unique([&fail_http_requests](const std::string& url, http_request) + auto http_client = std::unique_ptr(new test_http_client([&fail_http_requests](const std::string& url, http_request) { if (!fail_http_requests) { auto response_body = @@ -1857,7 +1863,7 @@ TEST(connection_id, connection_id_reset_when_starting_connection) } return http_response{ 500, "" }; - }); + })); auto connection = connection_impl::create(create_uri(), trace_level::none, std::make_shared(), diff --git a/test/signalrclienttests/hub_connection_tests.cpp b/test/signalrclienttests/hub_connection_tests.cpp index 5affa2c..175fabe 100644 --- a/test/signalrclienttests/hub_connection_tests.cpp +++ b/test/signalrclienttests/hub_connection_tests.cpp @@ -1315,7 +1315,6 @@ TEST(on, cannot_register_handler_if_connection_not_in_disconnected_state) { try { - int number = 0; auto websocket_client = create_test_websocket_client(); auto hub_connection = create_hub_connection(websocket_client); diff --git a/test/signalrclienttests/negotiate_tests.cpp b/test/signalrclienttests/negotiate_tests.cpp index 6e58dbc..2f5ed69 100644 --- a/test/signalrclienttests/negotiate_tests.cpp +++ b/test/signalrclienttests/negotiate_tests.cpp @@ -24,7 +24,7 @@ TEST(negotiate, request_created_with_correct_url) auto mre = manual_reset_event(); negotiate::negotiate(http_client, "http://fake/signalr", signalr_client_config(), - [&mre](signalr::negotiation_response&& response, std::exception_ptr exception) + [&mre](signalr::negotiation_response&&, std::exception_ptr exception) { mre.set(); }); diff --git a/test/signalrclienttests/stdafx.h b/test/signalrclienttests/stdafx.h index 3a9832c..555a831 100644 --- a/test/signalrclienttests/stdafx.h +++ b/test/signalrclienttests/stdafx.h @@ -11,5 +11,4 @@ #include "gtest/gtest.h" #include "../../src/signalrclient/cancellation_token.h" -#include "../../src/signalrclient/make_unique.h" #include \ No newline at end of file diff --git a/test/signalrclienttests/test_utils.cpp b/test/signalrclienttests/test_utils.cpp index 06b81c5..9182289 100644 --- a/test/signalrclienttests/test_utils.cpp +++ b/test/signalrclienttests/test_utils.cpp @@ -19,7 +19,7 @@ std::string remove_date_from_log_entry(const std::string &log_entry) std::unique_ptr create_test_http_client() { - return std::make_unique([](const std::string & url, http_request request) + return std::unique_ptr(new test_http_client([](const std::string & url, http_request request) { auto response_body = url.find_first_of("/negotiate") != 0 @@ -28,7 +28,7 @@ std::unique_ptr create_test_http_client() : ""; return http_response{ 200, response_body }; - }); + })); } std::string create_uri() diff --git a/third_party_code/cpprestsdk/uri.cpp b/third_party_code/cpprestsdk/uri.cpp index 688609c..278b73b 100644 --- a/third_party_code/cpprestsdk/uri.cpp +++ b/third_party_code/cpprestsdk/uri.cpp @@ -38,7 +38,7 @@ namespace signalr /// inline bool is_unreserved(int c) { - return utility::is_alnum((char)c) || c == '-' || c == '.' || c == '_' || c == '~'; + return utility::is_alnum((unsigned char)c) || c == '-' || c == '.' || c == '_' || c == '~'; } /// @@ -93,7 +93,7 @@ namespace signalr /// inline bool is_scheme_character(int c) { - return utility::is_alnum((char)c) || c == '+' || c == '-' || c == '.'; + return utility::is_alnum((unsigned char)c) || c == '+' || c == '-' || c == '.'; } /// @@ -732,13 +732,13 @@ namespace signalr } else if (equals_index == 0) { - std::string value(key_value_pair.begin() + equals_index + 1, key_value_pair.end()); + std::string value(key_value_pair.begin() + (int64_t)equals_index + 1, key_value_pair.end()); results[std::string{}] = value; } else { - std::string key(key_value_pair.begin(), key_value_pair.begin() + equals_index); - std::string value(key_value_pair.begin() + equals_index + 1, key_value_pair.end()); + std::string key(key_value_pair.begin(), key_value_pair.begin() + (int64_t)equals_index); + std::string value(key_value_pair.begin() + (int64_t)equals_index + 1, key_value_pair.end()); results[key] = value; } } diff --git a/third_party_code/jsoncpp/jsoncpp.cpp b/third_party_code/jsoncpp/jsoncpp.cpp index 507a1c6..93f68c7 100644 --- a/third_party_code/jsoncpp/jsoncpp.cpp +++ b/third_party_code/jsoncpp/jsoncpp.cpp @@ -6,28 +6,28 @@ // ////////////////////////////////////////////////////////////////////// /* -The JsonCpp library's source code, including accompanying documentation, +The JsonCpp library's source code, including accompanying documentation, tests and demonstration applications, are licensed under the following conditions... -Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all -jurisdictions which recognize such a disclaimer. In such jurisdictions, +Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all +jurisdictions which recognize such a disclaimer. In such jurisdictions, this software is released into the Public Domain. In jurisdictions which do not recognize Public Domain property (e.g. Germany as of 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and The JsonCpp Authors, and is released under the terms of the MIT License (see below). -In jurisdictions which recognize Public Domain property, the user of this -software may choose to accept it either as 1) Public Domain, 2) under the -conditions of the MIT License (see below), or 3) under the terms of dual +In jurisdictions which recognize Public Domain property, the user of this +software may choose to accept it either as 1) Public Domain, 2) under the +conditions of the MIT License (see below), or 3) under the terms of dual Public Domain/MIT License conditions described here, as they choose. The MIT License is about as close to Public Domain as a license can get, and is described in clear, concise terms at: http://en.wikipedia.org/wiki/MIT_License - + The full text of the MIT License follows: ======================================================================== @@ -69,7 +69,8 @@ license you like. // ////////////////////////////////////////////////////////////////////// - +#pragma warning( push, 0 ) +#pragma warning( disable: 4702 ) @@ -235,7 +236,7 @@ static inline void fixNumericLocaleInput(char* begin, char* end) { #include #if defined(_MSC_VER) -#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above +#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above #define snprintf sprintf_s #elif _MSC_VER >= 1900 // VC++ 14.0 and above #define snprintf std::snprintf @@ -379,7 +380,7 @@ bool Reader::parse(const char* beginDoc, bool Reader::readValue() { // readValue() may call itself only if it calls readObject() or ReadArray(). - // These methods execute nodes_.push() just before and nodes_.pop)() just after calling readValue(). + // These methods execute nodes_.push() just before and nodes_.pop)() just after calling readValue(). // parse() executes one nodes_.push(), so > instead of >=. if (nodes_.size() > stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue()."); @@ -4206,7 +4207,7 @@ Value& Path::make(Value& root) const { #endif #endif -#if defined(__BORLANDC__) +#if defined(__BORLANDC__) #include #define isfinite _finite #define snprintf _snprintf @@ -5290,7 +5291,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const JSONCPP_STRING cs_str = settings_["commentStyle"].asString(); bool eyc = settings_["enableYAMLCompatibility"].asBool(); bool dnp = settings_["dropNullPlaceholders"].asBool(); - bool usf = settings_["useSpecialFloats"].asBool(); + bool usf = settings_["useSpecialFloats"].asBool(); unsigned int pre = settings_["precision"].asUInt(); CommentStyle::Enum cs = CommentStyle::All; if (cs_str == "All") { @@ -5380,7 +5381,7 @@ JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM& sout, Value const& root) { // End of content of file: src/lib_json/json_writer.cpp // ////////////////////////////////////////////////////////////////////// - +#pragma warning ( pop )