diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt index 000516e1be..8092c72cad 100644 --- a/Release/CMakeLists.txt +++ b/Release/CMakeLists.txt @@ -13,6 +13,29 @@ set(CPPREST_VERSION_MAJOR 2) set(CPPREST_VERSION_MINOR 10) set(CPPREST_VERSION_REVISION 14) +# Note: when bumping CMake version to 3.3 or higher if(... IN_LIST ...) may be used +list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_std_17 COMPILER_HAS_CXX_STD_17) +set(CPPREST_USE_STRING_VIEWS_DEFAULT_PER_CXX_STANDARD OFF) +if(COMPILER_HAS_CXX_STD_17 EQUAL "-1") + if(CPPREST_USE_STRING_VIEWS) + if(CMAKE_VERSION VERSION_LESS 3.8) + message(FATAL_ERROR "CPPREST_USE_STRING_VIEWS cannot be enabled. CMake 3.8 or higher required to support C++17.") + else() + message(FATAL_ERROR "CPPREST_USE_STRING_VIEWS cannot be enabled. Compiler (${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}) does not support C++17.") + endif() + endif() +elseif(CMAKE_CXX_STANDARD LESS 17) + if(CPPREST_USE_STRING_VIEWS) + message(FATAL_ERROR "CPPREST_USE_STRING_VIEWS cannot be enabled when C++ standard is less than 17") + endif() +elseif((NOT CMAKE_CXX_STANDARD GREATER 16.99) AND (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR IOS OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")) + if(CPPREST_USE_STRING_VIEWS) + message(FATAL_ERROR "CPPREST_USE_STRING_VIEWS cannot be enabled without setting C++ standard to 17 or greater for current configuration") # see compiler specific settings below + endif() +else() + set(CPPREST_USE_STRING_VIEWS_DEFAULT_PER_CXX_STANDARD ON) +endif() + enable_testing() set(WERROR ON CACHE BOOL "Treat Warnings as Errors.") @@ -20,6 +43,7 @@ set(CPPREST_EXCLUDE_WEBSOCKETS OFF CACHE BOOL "Exclude websockets functionality. set(CPPREST_EXCLUDE_COMPRESSION OFF CACHE BOOL "Exclude compression functionality.") set(CPPREST_EXCLUDE_BROTLI ON CACHE BOOL "Exclude Brotli compression functionality.") set(CPPREST_EXPORT_DIR cpprestsdk CACHE STRING "Directory to install CMake config files.") +option(CPPREST_USE_STRING_VIEWS "Use string_view types" ${CPPREST_USE_STRING_VIEWS_DEFAULT_PER_CXX_STANDARD}) set(CPPREST_INSTALL_HEADERS ON CACHE BOOL "Install header files.") set(CPPREST_INSTALL ON CACHE BOOL "Add install commands.") @@ -116,6 +140,11 @@ endif() set(WARNINGS) set(ANDROID_LIBS) +# Generic build settings +if(CPPREST_USE_STRING_VIEWS) + add_definitions(-DCPPREST_USE_STRING_VIEWS) +endif() + # Platform (not compiler) specific settings if(ANDROID) # These are used in the shared library case @@ -140,6 +169,15 @@ else() endif() # Compiler (not platform) specific settings +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR IOS OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") + if(NOT CMAKE_CXX_STANDARD GREATER 0) + if(CPPREST_USE_STRING_VIEWS) + message(FATAL_ERROR "internal cpprestsdk cmake error: CPPREST_USE_STRING_VIEWS ON while C++ standard not set") + endif() + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + endif() +endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR IOS) message("-- Setting clang options") @@ -157,10 +195,10 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR IOS) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -Wno-return-type-c-linkage -Wno-unneeded-internal-declaration") set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++${CMAKE_CXX_STANDARD}") endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-strict-aliasing") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") message("-- Setting gcc options") @@ -168,7 +206,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(WARNINGS -Wall -Wextra -Wunused-parameter -Wcast-align -Wcast-qual -Wconversion -Wformat=2 -Winit-self -Winvalid-pch -Wmissing-format-attribute -Wmissing-include-dirs -Wpacked -Wredundant-decls -Wunreachable-code) set(LD_FLAGS "${LD_FLAGS} -Wl,-z,defs") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-strict-aliasing") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -D_GLIBCXX_USE_SCHED_YIELD -D_GLIBCXX_USE_NANOSLEEP") endif() @@ -193,6 +231,13 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") add_compile_options(/permissive-) endif() endif() + + # Suppress C++17 deprecation warning in aiso per https://github.com/chriskohlhoff/asio/issues/290#issuecomment-371867040 + # MSVC has addressed issue in 16.0 per https://devblogs.microsoft.com/cppblog/cpp17-20-features-and-fixes-in-vs-2019/ + if(MSVC_VERSION GREATER 1912 AND MSVC_VERSION LESS 1920) + add_definitions(-D_SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING) + endif() + else() message("-- Unknown compiler, success is doubtful.") message("CMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}") diff --git a/Release/include/cpprest/base64_utils.h b/Release/include/cpprest/base64_utils.h index d986b5973d..a5c0823664 100644 --- a/Release/include/cpprest/base64_utils.h +++ b/Release/include/cpprest/base64_utils.h @@ -36,7 +36,7 @@ _ASYNCRTIMP utility::string_t __cdecl to_base64(uint64_t data); /// /// Decode the given base64 string to a byte array /// -_ASYNCRTIMP std::vector __cdecl from_base64(const utility::string_t& str); +_ASYNCRTIMP std::vector __cdecl from_base64(utility::string_view_t str); } // namespace conversions diff --git a/Release/include/cpprest/details/basic_types.h b/Release/include/cpprest/details/basic_types.h index 5630d61cb1..9a546665ea 100644 --- a/Release/include/cpprest/details/basic_types.h +++ b/Release/include/cpprest/details/basic_types.h @@ -18,6 +18,9 @@ #include #include #include +#if defined(CPPREST_USE_STRING_VIEWS) +#include +#endif #ifndef _WIN32 #ifndef __STDC_LIMIT_MACROS @@ -44,11 +47,22 @@ typedef uint64_t size64_t; typedef uint32_t HRESULT; // Needed for PPLX #endif +#if defined(CPPREST_USE_STRING_VIEWS) +typedef std::string_view nstring_view_t; +typedef std::wstring_view wstring_view_t; +template using string_view = std::basic_string_view; +#else +typedef const std::string & nstring_view_t; +typedef const std::wstring & wstring_view_t; +template using string_view = const std::basic_string &; +#endif + #ifdef _UTF16_STRINGS // // On Windows, all strings are wide // typedef wchar_t char_t; +typedef wstring_view_t string_view_t; typedef std::wstring string_t; #define _XPLATSTR(x) L##x typedef std::wostringstream ostringstream_t; @@ -66,6 +80,7 @@ typedef std::wstringstream stringstream_t; // On POSIX platforms, all strings are narrow // typedef char char_t; +typedef nstring_view_t string_view_t; typedef std::string string_t; #define _XPLATSTR(x) x typedef std::ostringstream ostringstream_t; @@ -90,6 +105,7 @@ typedef std::stringstream stringstream_t; } // namespace utility typedef char utf8char; +typedef utility::nstring_view_t utf8string_view; typedef std::string utf8string; typedef std::stringstream utf8stringstream; typedef std::ostringstream utf8ostringstream; @@ -99,6 +115,7 @@ typedef std::istringstream utf8istringstream; #if defined(_UTF16_STRINGS) || defined(_WIN32) typedef wchar_t utf16char; +typedef utility::wstring_view_t utf16string_view; typedef std::wstring utf16string; typedef std::wstringstream utf16stringstream; typedef std::wostringstream utf16ostringstream; @@ -107,6 +124,11 @@ typedef std::wistream utf16istream; typedef std::wistringstream utf16istringstream; #else typedef char16_t utf16char; +#if defined(CPPREST_USE_STRING_VIEWS) +typedef std::u16string_view utf16string_view; +#else +typedef const std::u16string & utf16string_view; +#endif typedef std::u16string utf16string; typedef std::basic_stringstream utf16stringstream; typedef std::basic_ostringstream utf16ostringstream; diff --git a/Release/include/cpprest/details/web_utilities.h b/Release/include/cpprest/details/web_utilities.h index d7c7fdb36b..441775cf62 100644 --- a/Release/include/cpprest/details/web_utilities.h +++ b/Release/include/cpprest/details/web_utilities.h @@ -32,7 +32,7 @@ class winrt_encryption { public: winrt_encryption() = default; - _ASYNCRTIMP winrt_encryption(const ::utility::string_t& data); + _ASYNCRTIMP winrt_encryption(utility::string_view_t data); _ASYNCRTIMP plaintext_string decrypt() const; private: @@ -43,7 +43,7 @@ class win32_encryption { public: win32_encryption() = default; - _ASYNCRTIMP win32_encryption(const ::utility::string_t& data); + _ASYNCRTIMP win32_encryption(::utility::string_view_t data); _ASYNCRTIMP ~win32_encryption(); _ASYNCRTIMP plaintext_string decrypt() const; @@ -73,7 +73,7 @@ class credentials /// /// User name as a string. /// Password as a string. - credentials(utility::string_t username, const utility::string_t& password) + credentials(utility::string_t username, utility::string_view_t password) : m_username(std::move(username)), m_password(password) { } diff --git a/Release/include/cpprest/filestream.h b/Release/include/cpprest/filestream.h index a9e6351caa..d71f9c20a7 100644 --- a/Release/include/cpprest/filestream.h +++ b/Release/include/cpprest/filestream.h @@ -713,7 +713,7 @@ class basic_file_buffer : public details::streambuf_state_manager<_CharType> #if !defined(__cplusplus_winrt) static pplx::task>> open( - const utility::string_t& _Filename, + utility::string_view_t _Filename, std::ios_base::openmode _Mode = std::ios_base::out, #ifdef _WIN32 int _Prot = (int)std::ios_base::_Openprot @@ -724,7 +724,7 @@ class basic_file_buffer : public details::streambuf_state_manager<_CharType> { auto result_tce = pplx::task_completion_event>>(); auto callback = new _filestream_callback_open(result_tce); - _open_fsb_str(callback, _Filename.c_str(), _Mode, _Prot); + _open_fsb_str(callback, _Filename.data(), _Mode, _Prot); return pplx::create_task(result_tce); } @@ -955,7 +955,7 @@ class file_buffer /// The opening mode of the file /// The file protection mode /// A task that returns an opened stream buffer on completion. - static pplx::task> open(const utility::string_t& file_name, + static pplx::task> open(utility::string_view_t file_name, std::ios_base::openmode mode = std::ios_base::out, #ifdef _WIN32 int prot = _SH_DENYRD @@ -1010,7 +1010,7 @@ class file_stream /// The opening mode of the file /// The file protection mode /// A task that returns an opened input stream on completion. - static pplx::task> open_istream(const utility::string_t& file_name, + static pplx::task> open_istream(utility::string_view_t file_name, std::ios_base::openmode mode = std::ios_base::in, #ifdef _WIN32 int prot = (int)std::ios_base::_Openprot @@ -1035,7 +1035,7 @@ class file_stream /// The opening mode of the file /// The file protection mode /// A task that returns an opened output stream on completion. - static pplx::task> open_ostream(const utility::string_t& file_name, + static pplx::task> open_ostream(utility::string_view_t file_name, std::ios_base::openmode mode = std::ios_base::out, #ifdef _WIN32 int prot = (int)std::ios_base::_Openprot diff --git a/Release/include/cpprest/json.h b/Release/include/cpprest/json.h index 1f180bac9e..174da35212 100644 --- a/Release/include/cpprest/json.h +++ b/Release/include/cpprest/json.h @@ -281,7 +281,7 @@ class value #if defined(_UTF16_STRINGS) private: // Only used internally by JSON parser. - static _ASYNCRTIMP value __cdecl string(const std::string& value); + static _ASYNCRTIMP value __cdecl string(utility::nstring_view_t value); public: #endif @@ -394,7 +394,7 @@ class value /// Parses a string and construct a JSON value. /// /// The C++ value to create a JSON value from, a C++ STL double-byte string - _ASYNCRTIMP static value __cdecl parse(const utility::string_t& value); + _ASYNCRTIMP static value __cdecl parse(utility::string_view_t value); /// /// Attempts to parse a string and construct a JSON value. @@ -402,7 +402,7 @@ class value /// The C++ value to create a JSON value from, a C++ STL double-byte string /// If parsing fails, the error code is greater than 0 /// The parsed object. Returns web::json::value::null if failed - _ASYNCRTIMP static value __cdecl parse(const utility::string_t& value, std::error_code& errorCode); + _ASYNCRTIMP static value __cdecl parse(utility::string_view_t value, std::error_code& errorCode); /// /// Serializes the current JSON value to a C++ string. @@ -539,56 +539,56 @@ class value /// /// The name of the field /// True if the field exists, false otherwise. - bool has_field(const utility::string_t& key) const; + bool has_field(utility::string_view_t key) const; /// /// Tests for the presence of a number field /// /// The name of the field /// True if the field exists, false otherwise. - _ASYNCRTIMP bool has_number_field(const utility::string_t& key) const; + _ASYNCRTIMP bool has_number_field(utility::string_view_t key) const; /// /// Tests for the presence of an integer field /// /// The name of the field /// True if the field exists, false otherwise. - _ASYNCRTIMP bool has_integer_field(const utility::string_t& key) const; + _ASYNCRTIMP bool has_integer_field(utility::string_view_t key) const; /// /// Tests for the presence of a double field /// /// The name of the field /// True if the field exists, false otherwise. - _ASYNCRTIMP bool has_double_field(const utility::string_t& key) const; + _ASYNCRTIMP bool has_double_field(utility::string_view_t key) const; /// /// Tests for the presence of a boolean field /// /// The name of the field /// True if the field exists, false otherwise. - _ASYNCRTIMP bool has_boolean_field(const utility::string_t& key) const; + _ASYNCRTIMP bool has_boolean_field(utility::string_view_t key) const; /// /// Tests for the presence of a string field /// /// The name of the field /// True if the field exists, false otherwise. - _ASYNCRTIMP bool has_string_field(const utility::string_t& key) const; + _ASYNCRTIMP bool has_string_field(utility::string_view_t key) const; /// /// Tests for the presence of an array field /// /// The name of the field /// True if the field exists, false otherwise. - _ASYNCRTIMP bool has_array_field(const utility::string_t& key) const; + _ASYNCRTIMP bool has_array_field(utility::string_view_t key) const; /// /// Tests for the presence of an object field /// /// The name of the field /// True if the field exists, false otherwise. - _ASYNCRTIMP bool has_object_field(const utility::string_t& key) const; + _ASYNCRTIMP bool has_object_field(utility::string_view_t key) const; /// /// Accesses a field of a JSON object. @@ -609,7 +609,7 @@ class value /// Erases an element of a JSON object. Throws if the key doesn't exist. /// /// The key of the element to erase in the JSON object. - _ASYNCRTIMP void erase(const utility::string_t& key); + _ASYNCRTIMP void erase(utility::string_view_t key); /// /// Accesses an element of a JSON array. Throws when index out of bounds. @@ -630,26 +630,26 @@ class value /// /// The key of an element in the JSON object. /// If the key exists, a reference to the value. - _ASYNCRTIMP json::value& at(const utility::string_t& key); + _ASYNCRTIMP json::value& at(utility::string_view_t key); /// /// Accesses an element of a JSON object. If the key doesn't exist, this method throws. /// /// The key of an element in the JSON object. /// If the key exists, a reference to the value. - _ASYNCRTIMP const json::value& at(const utility::string_t& key) const; + _ASYNCRTIMP const json::value& at(utility::string_view_t key) const; /// /// Accesses a field of a JSON object. /// /// The name of the field /// A reference to the value kept in the field. - _ASYNCRTIMP value& operator[](const utility::string_t& key); + _ASYNCRTIMP value& operator[](utility::string_view_t key); #if defined(_UTF16_STRINGS) private: // Only used internally by JSON parser - _ASYNCRTIMP value& operator[](const std::string& key) + _ASYNCRTIMP value& operator[](utility::nstring_view_t key) { // JSON object stores its field map as a unordered_map of string_t, so this conversion is hard to avoid return operator[](utility::conversions::to_string_t(key)); @@ -1050,7 +1050,7 @@ class object /// Deletes an element of the JSON object. If the key doesn't exist, this method throws. /// /// The key of an element in the JSON object. - void erase(const utility::string_t& key) + void erase(utility::string_view_t key) { auto iter = find_by_key(key); if (iter == m_elements.end()) @@ -1066,7 +1066,7 @@ class object /// /// The key of an element in the JSON object. /// If the key exists, a reference to the value kept in the field. - json::value& at(const utility::string_t& key) + json::value& at(utility::string_view_t key) { auto iter = find_by_key(key); if (iter == m_elements.end()) @@ -1082,7 +1082,7 @@ class object /// /// The key of an element in the JSON object. /// If the key exists, a reference to the value kept in the field. - const json::value& at(const utility::string_t& key) const + const json::value& at(utility::string_view_t key) const { auto iter = find_by_key(key); if (iter == m_elements.end()) @@ -1099,7 +1099,7 @@ class object /// The key of an element in the JSON object. /// If the key exists, a reference to the value kept in the field, otherwise a newly created null value /// that will be stored for the given key. - json::value& operator[](const utility::string_t& key) + json::value& operator[](utility::string_view_t key) { auto iter = find_insert_location(key); @@ -1116,7 +1116,7 @@ class object /// /// The key of an element in the JSON object. /// A const iterator to the value kept in the field. - const_iterator find(const utility::string_t& key) const { return find_by_key(key); } + const_iterator find(utility::string_view_t key) const { return find_by_key(key); } /// /// Gets the number of elements of the object. @@ -1136,12 +1136,12 @@ class object { return p1.first < p2.first; } - static bool compare_with_key(const std::pair& p1, const utility::string_t& key) + static bool compare_with_key(const std::pair& p1, utility::string_view_t key) { return p1.first < key; } - storage_type::iterator find_insert_location(const utility::string_t& key) + storage_type::iterator find_insert_location(utility::string_view_t key) { if (m_keep_order) { @@ -1155,7 +1155,7 @@ class object } } - storage_type::const_iterator find_by_key(const utility::string_t& key) const + storage_type::const_iterator find_by_key(utility::string_view_t key) const { if (m_keep_order) { @@ -1174,7 +1174,7 @@ class object } } - storage_type::iterator find_by_key(const utility::string_t& key) + storage_type::iterator find_by_key(utility::string_view_t key) { auto iter = find_insert_location(key); if (iter != m_elements.end() && key != iter->first) @@ -1357,14 +1357,14 @@ class _Value public: virtual std::unique_ptr<_Value> _copy_value() = 0; - virtual bool has_field(const utility::string_t&) const { return false; } - virtual value get_field(const utility::string_t&) const { throw json_exception("not an object"); } + virtual bool has_field(utility::string_view_t) const { return false; } + virtual value get_field(utility::string_view_t) const { throw json_exception("not an object"); } virtual value get_element(array::size_type) const { throw json_exception("not an array"); } - virtual value& index(const utility::string_t&) { throw json_exception("not an object"); } + virtual value& index(utility::string_view_t) { throw json_exception("not an object"); } virtual value& index(array::size_type) { throw json_exception("not an array"); } - virtual const value& cnst_index(const utility::string_t&) const { throw json_exception("not an object"); } + virtual const value& cnst_index(utility::string_view_t) const { throw json_exception("not an object"); } virtual const value& cnst_index(array::size_type) const { throw json_exception("not an array"); } // Common function used for serialization to strings and streams. @@ -1537,12 +1537,12 @@ class _String : public _Value }; template -_ASYNCRTIMP void append_escape_string(std::basic_string& str, const std::basic_string& escaped); +_ASYNCRTIMP void append_escape_string(std::basic_string& str, utility::string_view escaped); -void format_string(const utility::string_t& key, utility::string_t& str); +void format_string(utility::string_view_t key, utility::string_t& str); #if defined(_UTF16_STRINGS) -void format_string(const utility::string_t& key, std::string& str); +void format_string(utility::string_view_t key, std::string& str); #endif class _Object : public _Value @@ -1559,9 +1559,9 @@ class _Object : public _Value virtual json::value::value_type type() const { return json::value::Object; } - virtual bool has_field(const utility::string_t&) const; + virtual bool has_field(utility::string_view_t) const; - virtual json::value& index(const utility::string_t& key); + virtual json::value& index(utility::string_view_t key); bool is_equal(const _Object* other) const { @@ -1752,7 +1752,7 @@ inline size_t json::value::size() const { return m_value->size(); } /// /// The name of the field /// True if the field exists, false otherwise. -inline bool json::value::has_field(const utility::string_t& key) const { return m_value->has_field(key); } +inline bool json::value::has_field(utility::string_view_t key) const { return m_value->has_field(key); } /// /// Access a field of a JSON object. diff --git a/Release/include/cpprest/string_utils.h b/Release/include/cpprest/string_utils.h index 0daaca8705..7929f9e66b 100644 --- a/Release/include/cpprest/string_utils.h +++ b/Release/include/cpprest/string_utils.h @@ -42,35 +42,35 @@ namespace conversions /// /// A two byte character UTF-16 string. /// A single byte character UTF-8 string. -_ASYNCRTIMP std::string __cdecl utf16_to_utf8(const utf16string& w); +_ASYNCRTIMP std::string __cdecl utf16_to_utf8(utf16string_view w); /// /// Converts a UTF-8 string to a UTF-16 /// /// A single byte character UTF-8 string. /// A two byte character UTF-16 string. -_ASYNCRTIMP utf16string __cdecl utf8_to_utf16(const std::string& s); +_ASYNCRTIMP utf16string __cdecl utf8_to_utf16(utility::nstring_view_t s); /// /// Converts a ASCII (us-ascii) string to a UTF-16 string. /// /// A single byte character us-ascii string. /// A two byte character UTF-16 string. -_ASYNCRTIMP utf16string __cdecl usascii_to_utf16(const std::string& s); +_ASYNCRTIMP utf16string __cdecl usascii_to_utf16(utility::nstring_view_t s); /// /// Converts a Latin1 (iso-8859-1) string to a UTF-16 string. /// /// A single byte character UTF-8 string. /// A two byte character UTF-16 string. -_ASYNCRTIMP utf16string __cdecl latin1_to_utf16(const std::string& s); +_ASYNCRTIMP utf16string __cdecl latin1_to_utf16(utility::nstring_view_t s); /// /// Converts a Latin1 (iso-8859-1) string to a UTF-8 string. /// /// A single byte character UTF-8 string. /// A single byte character UTF-8 string. -_ASYNCRTIMP utf8string __cdecl latin1_to_utf8(const std::string& s); +_ASYNCRTIMP utf8string __cdecl latin1_to_utf8(utility::nstring_view_t s); /// /// Converts to a platform dependent Unicode string type. @@ -99,9 +99,18 @@ _ASYNCRTIMP utility::string_t __cdecl to_string_t(utf16string&& s); /// A single byte character UTF-8 string. /// A platform dependent string type. #ifdef _UTF16_STRINGS -_ASYNCRTIMP utility::string_t __cdecl to_string_t(const std::string& s); +_ASYNCRTIMP utility::string_t __cdecl to_string_t(utility::nstring_view_t s); #else inline const utility::string_t& to_string_t(const std::string& s) { return s; } +#if CPPREST_USE_STRING_VIEWS +inline utility::string_view_t to_string_t(utility::nstring_view_t s) { return s; } +#endif +#endif + +#if CPPREST_USE_STRING_VIEWS +// Provide precise overload for string literals to resolve ambiguity of other overloads. +template +inline auto to_string_t(const CharType * s) { return to_string_t(std::basic_string_view(s)); } #endif /// @@ -111,8 +120,11 @@ inline const utility::string_t& to_string_t(const std::string& s) { return s; } /// A platform dependent string type. #ifdef _UTF16_STRINGS inline const utility::string_t& to_string_t(const utf16string& s) { return s; } +#if CPPREST_USE_STRING_VIEWS +inline utf16string_view to_string_t(utf16string_view s) { return s; } +#endif #else -_ASYNCRTIMP utility::string_t __cdecl to_string_t(const utf16string& s); +_ASYNCRTIMP utility::string_t __cdecl to_string_t(utf16string_view s); #endif /// @@ -120,7 +132,7 @@ _ASYNCRTIMP utility::string_t __cdecl to_string_t(const utf16string& s); /// /// A single byte character UTF-8 string. /// A two byte character UTF-16 string. -_ASYNCRTIMP utf16string __cdecl to_utf16string(const std::string& value); +_ASYNCRTIMP utf16string __cdecl to_utf16string(utility::nstring_view_t value); /// /// Converts to a UTF-16 from string. @@ -128,6 +140,9 @@ _ASYNCRTIMP utf16string __cdecl to_utf16string(const std::string& value); /// A two byte character UTF-16 string. /// A two byte character UTF-16 string. inline const utf16string& to_utf16string(const utf16string& value) { return value; } +#if CPPREST_USE_STRING_VIEWS +inline utf16string_view to_utf16string(utf16string_view value) { return value; } +#endif /// /// Converts to a UTF-16 from string. /// @@ -135,6 +150,12 @@ inline const utf16string& to_utf16string(const utf16string& value) { return valu /// A two byte character UTF-16 string. inline utf16string&& to_utf16string(utf16string&& value) { return std::move(value); } +#if CPPREST_USE_STRING_VIEWS +// Provide precise overload for string literals to resolve ambiguity of other overloads. +template +inline auto to_utf16string(const CharType * s) { return to_utf16string(std::basic_string_view(s)); } +#endif + /// /// Converts to a UTF-8 string. /// @@ -148,13 +169,22 @@ inline std::string&& to_utf8string(std::string&& value) { return std::move(value /// A single byte character UTF-8 string. /// A single byte character UTF-8 string. inline const std::string& to_utf8string(const std::string& value) { return value; } +#if CPPREST_USE_STRING_VIEWS +inline utility::nstring_view_t to_utf8string(utility::nstring_view_t value) { return value; } +#endif /// /// Converts to a UTF-8 string. /// /// A two byte character UTF-16 string. /// A single byte character UTF-8 string. -_ASYNCRTIMP std::string __cdecl to_utf8string(const utf16string& value); +_ASYNCRTIMP std::string __cdecl to_utf8string(utf16string_view value); + +#if CPPREST_USE_STRING_VIEWS +// Provide precise overload for string literals to resolve ambiguity of other overloads. +template +inline auto to_utf8string(const CharType * s) { return to_utf8string(std::basic_string_view(s)); } +#endif template CASABLANCA_DEPRECATED("All locale-sensitive APIs will be removed in a future update. Use stringstreams directly if " @@ -216,6 +246,9 @@ utility::string_t print_string(const Source& val) } inline const utility::string_t& print_string(const utility::string_t& val) { return val; } +#if CPPREST_USE_STRING_VIEWS +inline utility::string_view_t print_string(utility::string_view_t val) { return val; } +#endif template utf8string print_utf8string(const Source& val) @@ -363,7 +396,7 @@ inline bool __cdecl is_space(Elem ch) CPPREST_NOEXCEPT /// First string to compare. /// Second strong to compare. /// true if the strings are equivalent, false otherwise -_ASYNCRTIMP bool __cdecl str_iequal(const std::string& left, const std::string& right) CPPREST_NOEXCEPT; +_ASYNCRTIMP bool __cdecl str_iequal(utility::nstring_view_t left, utility::nstring_view_t right) CPPREST_NOEXCEPT; /// /// Cross platform utility function for performing case insensitive string equality comparison. @@ -371,7 +404,7 @@ _ASYNCRTIMP bool __cdecl str_iequal(const std::string& left, const std::string& /// First string to compare. /// Second strong to compare. /// true if the strings are equivalent, false otherwise -_ASYNCRTIMP bool __cdecl str_iequal(const std::wstring& left, const std::wstring& right) CPPREST_NOEXCEPT; +_ASYNCRTIMP bool __cdecl str_iequal(utility::wstring_view_t left, utility::wstring_view_t right) CPPREST_NOEXCEPT; /// /// Cross platform utility function for performing case insensitive string less-than comparison. @@ -380,7 +413,7 @@ _ASYNCRTIMP bool __cdecl str_iequal(const std::wstring& left, const std::wstring /// Second strong to compare. /// true if a lowercase view of left is lexicographically less than a lowercase view of right; otherwise, /// false. -_ASYNCRTIMP bool __cdecl str_iless(const std::string& left, const std::string& right) CPPREST_NOEXCEPT; +_ASYNCRTIMP bool __cdecl str_iless(utility::nstring_view_t left, utility::nstring_view_t right) CPPREST_NOEXCEPT; /// /// Cross platform utility function for performing case insensitive string less-than comparison. @@ -389,7 +422,7 @@ _ASYNCRTIMP bool __cdecl str_iless(const std::string& left, const std::string& r /// Second strong to compare. /// true if a lowercase view of left is lexicographically less than a lowercase view of right; otherwise, /// false. -_ASYNCRTIMP bool __cdecl str_iless(const std::wstring& left, const std::wstring& right) CPPREST_NOEXCEPT; +_ASYNCRTIMP bool __cdecl str_iless(utility::wstring_view_t left, utility::wstring_view_t right) CPPREST_NOEXCEPT; /// /// Convert a string to lowercase in place. diff --git a/Release/samples/SearchFile/searchfile.cpp b/Release/samples/SearchFile/searchfile.cpp index 7200f05dc8..480fe96752 100644 --- a/Release/samples/SearchFile/searchfile.cpp +++ b/Release/samples/SearchFile/searchfile.cpp @@ -86,8 +86,8 @@ class type_parser /// Function to create in data from a file and search for a given string writing all lines containing the string to /// memory_buffer. /// -static pplx::task find_matches_in_file(const string_t& fileName, - const std::string& searchString, +static pplx::task find_matches_in_file(utility::string_view_t fileName, + utility::nstring_view_t searchString, basic_ostream results) { return file_stream::open_istream(fileName).then([=](basic_istream inFile) { @@ -130,7 +130,7 @@ static pplx::task find_matches_in_file(const string_t& fileName, /// /// Function to write out results from matched_lines type to file /// -static pplx::task write_matches_to_file(const string_t& fileName, matched_lines results) +static pplx::task write_matches_to_file(utility::string_view_t fileName, matched_lines results) { // Create a shared pointer to the matched_lines structure to copying repeatedly. auto sharedResults = std::make_shared(std::move(results)); @@ -162,9 +162,9 @@ int main(int argc, char* args[]) printf("Usage: SearchFile.exe input_file search_string output_file\n"); return -1; } - const string_t inFileName = utility::conversions::to_string_t(args[1]); - const std::string searchString = utility::conversions::to_utf8string(args[2]); - const string_t outFileName = utility::conversions::to_string_t(args[3]); + const auto inFileName = utility::conversions::to_string_t(args[1]); + const auto searchString = utility::conversions::to_utf8string(args[2]); + const auto outFileName = utility::conversions::to_string_t(args[3]); producer_consumer_buffer lineResultsBuffer; // Find all matches in file. diff --git a/Release/src/CMakeLists.txt b/Release/src/CMakeLists.txt index 9d0fadde62..af31a9f2c4 100644 --- a/Release/src/CMakeLists.txt +++ b/Release/src/CMakeLists.txt @@ -48,6 +48,10 @@ target_include_directories(cpprest pch ) +if(CPPREST_USE_STRING_VIEWS) + target_compile_features(cpprest PUBLIC cxx_std_17) +endif() + ## Sub-components # Websockets component if(CPPREST_WEBSOCKETS_IMPL STREQUAL "none") diff --git a/Release/src/json/json.cpp b/Release/src/json/json.cpp index eee8db7cd6..70e227f197 100644 --- a/Release/src/json/json.cpp +++ b/Release/src/json/json.cpp @@ -196,7 +196,7 @@ web::json::value web::json::value::string(utility::string_t value, bool has_esca } #if defined(_UTF16_STRINGS) -web::json::value web::json::value::string(const std::string& value) +web::json::value web::json::value::string(utility::nstring_view_t value) { std::unique_ptr ptr = utility::details::make_unique(utility::conversions::to_utf16string(value)); @@ -355,44 +355,44 @@ bool json::value::is_double() const return m_value->is_double(); } -json::value& web::json::details::_Object::index(const utility::string_t& key) { return m_object[key]; } +json::value& web::json::details::_Object::index(utility::string_view_t key) { return m_object[key]; } -bool web::json::details::_Object::has_field(const utility::string_t& key) const +bool web::json::details::_Object::has_field(utility::string_view_t key) const { return m_object.find(key) != m_object.end(); } -bool web::json::value::has_number_field(const utility::string_t& key) const +bool web::json::value::has_number_field(utility::string_view_t key) const { return has_field(key) && at(key).is_number(); } -bool web::json::value::has_integer_field(const utility::string_t& key) const +bool web::json::value::has_integer_field(utility::string_view_t key) const { return has_field(key) && at(key).is_integer(); } -bool web::json::value::has_double_field(const utility::string_t& key) const +bool web::json::value::has_double_field(utility::string_view_t key) const { return has_field(key) && at(key).is_double(); } -bool web::json::value::has_boolean_field(const utility::string_t& key) const +bool web::json::value::has_boolean_field(utility::string_view_t key) const { return has_field(key) && at(key).is_boolean(); } -bool web::json::value::has_string_field(const utility::string_t& key) const +bool web::json::value::has_string_field(utility::string_view_t key) const { return has_field(key) && at(key).is_string(); } -bool web::json::value::has_array_field(const utility::string_t& key) const +bool web::json::value::has_array_field(utility::string_view_t key) const { return has_field(key) && at(key).is_array(); } -bool web::json::value::has_object_field(const utility::string_t& key) const +bool web::json::value::has_object_field(utility::string_view_t key) const { return has_field(key) && at(key).is_object(); } @@ -428,18 +428,18 @@ bool json::value::operator==(const json::value& other) const void web::json::value::erase(size_t index) { return this->as_array().erase(index); } -void web::json::value::erase(const utility::string_t& key) { return this->as_object().erase(key); } +void web::json::value::erase(utility::string_view_t key) { return this->as_object().erase(key); } // at() overloads web::json::value& web::json::value::at(size_t index) { return this->as_array().at(index); } const web::json::value& web::json::value::at(size_t index) const { return this->as_array().at(index); } -web::json::value& web::json::value::at(const utility::string_t& key) { return this->as_object().at(key); } +web::json::value& web::json::value::at(utility::string_view_t key) { return this->as_object().at(key); } -const web::json::value& web::json::value::at(const utility::string_t& key) const { return this->as_object().at(key); } +const web::json::value& web::json::value::at(utility::string_view_t key) const { return this->as_object().at(key); } -web::json::value& web::json::value::operator[](const utility::string_t& key) +web::json::value& web::json::value::operator[](utility::string_view_t key) { if (this->is_null()) { diff --git a/Release/src/json/json_parsing.cpp b/Release/src/json/json_parsing.cpp index 2e0d71e6d3..e5719d3494 100644 --- a/Release/src/json/json_parsing.cpp +++ b/Release/src/json/json_parsing.cpp @@ -46,7 +46,7 @@ __declspec(noreturn) #else __attribute__((noreturn)) #endif - void CreateException(const Token& tk, const utility::string_t& message) + void CreateException(const Token& tk, utility::string_view_t message) { std::string str("* Line "); str += std::to_string(tk.start.m_line); @@ -211,7 +211,7 @@ template class JSON_StringParser : public JSON_Parser { public: - JSON_StringParser(const std::basic_string& string) : m_position(&string[0]) + JSON_StringParser(utility::string_view string) : m_position(string.data()) { m_startpos = m_position; m_endpos = m_position + string.size(); @@ -1223,7 +1223,7 @@ static web::json::value _parse_narrow_stream(std::istream& stream, std::error_co } #endif -web::json::value web::json::value::parse(const utility::string_t& str) +web::json::value web::json::value::parse(utility::string_view_t str) { web::json::details::JSON_StringParser parser(str); web::json::details::JSON_Parser::Token tkn; @@ -1247,7 +1247,7 @@ web::json::value web::json::value::parse(const utility::string_t& str) return value; } -web::json::value web::json::value::parse(const utility::string_t& str, std::error_code& error) +web::json::value web::json::value::parse(utility::string_view_t str, std::error_code& error) { web::json::details::JSON_StringParser parser(str); web::json::details::JSON_Parser::Token tkn; diff --git a/Release/src/json/json_serialization.cpp b/Release/src/json/json_serialization.cpp index 83c1086e1f..9652bc23db 100644 --- a/Release/src/json/json_serialization.cpp +++ b/Release/src/json/json_serialization.cpp @@ -56,7 +56,7 @@ void web::json::value::format(std::basic_string& string) const { m_value-> template void web::json::details::append_escape_string(std::basic_string& str, - const std::basic_string& escaped) + utility::string_view escaped) { for (const auto& ch : escaped) { @@ -112,18 +112,18 @@ void web::json::details::append_escape_string(std::basic_string& str, } } -void web::json::details::format_string(const utility::string_t& key, utility::string_t& str) +void web::json::details::format_string(utility::string_view_t key, utility::string_t& str) { str.push_back('"'); - append_escape_string(str, key); + append_escape_string(str, key); str.push_back('"'); } #if defined(_UTF16_STRINGS) -void web::json::details::format_string(const utility::string_t& key, std::string& str) +void web::json::details::format_string(utility::string_view_t key, std::string& str) { str.push_back('"'); - append_escape_string(str, utility::conversions::to_utf8string(key)); + append_escape_string(str, utility::conversions::to_utf8string(key)); str.push_back('"'); } #endif @@ -134,7 +134,7 @@ void web::json::details::_String::format(std::basic_string& str) const if (m_has_escape_char) { - append_escape_string(str, utility::conversions::to_utf8string(m_string)); + append_escape_string(str, utility::conversions::to_utf8string(m_string)); } else { @@ -198,7 +198,7 @@ void web::json::details::_String::format(std::basic_string& str) const if (m_has_escape_char) { - append_escape_string(str, m_string); + append_escape_string(str, m_string); } else { diff --git a/Release/src/streams/fileio_win32.cpp b/Release/src/streams/fileio_win32.cpp index 129fd991de..82657d61bd 100644 --- a/Release/src/streams/fileio_win32.cpp +++ b/Release/src/streams/fileio_win32.cpp @@ -228,7 +228,11 @@ bool __cdecl _open_fsb_str(_In_ _filestream_callback* callback, _ASSERTE(callback != nullptr); _ASSERTE(filename != nullptr); - std::wstring name = conversions::to_utf16string(filename); + std::wstring name( +#if defined(CPPREST_FORCE_NARROW_STRINGS) + conversions::to_utf16string +#endif + (filename)); pplx::create_task([=]() { DWORD dwDesiredAccess, dwCreationDisposition, dwShareMode; diff --git a/Release/src/utilities/base64.cpp b/Release/src/utilities/base64.cpp index 89ccf43674..db419d5ec9 100644 --- a/Release/src/utilities/base64.cpp +++ b/Release/src/utilities/base64.cpp @@ -16,10 +16,10 @@ using namespace utility; -std::vector _from_base64(const utility::string_t& str); +std::vector _from_base64(utility::string_view_t str); utility::string_t _to_base64(const unsigned char* ptr, size_t size); -std::vector __cdecl conversions::from_base64(const utility::string_t& str) { return _from_base64(str); } +std::vector __cdecl conversions::from_base64(utility::string_view_t str) { return _from_base64(str); } utility::string_t __cdecl conversions::to_base64(const std::vector& input) { @@ -29,7 +29,7 @@ utility::string_t __cdecl conversions::to_base64(const std::vector _from_base64(const utility::string_t& input) +std::vector _from_base64(utility::string_view_t input) { std::vector result; @@ -127,7 +127,7 @@ std::vector _from_base64(const utility::string_t& input) } auto size = input.size(); - const char_t* ptr = &input[0]; + const char_t* ptr = input.data(); auto outsz = (size / 4) * 3; outsz -= padding; diff --git a/Release/src/utilities/string_utils.cpp b/Release/src/utilities/string_utils.cpp index 51751f224d..03f94f5e32 100644 --- a/Release/src/utilities/string_utils.cpp +++ b/Release/src/utilities/string_utils.cpp @@ -68,22 +68,22 @@ namespace utility { namespace details { -_ASYNCRTIMP bool __cdecl str_iequal(const std::string& left, const std::string& right) CPPREST_NOEXCEPT +_ASYNCRTIMP bool __cdecl str_iequal(utility::nstring_view_t left, utility::nstring_view_t right) CPPREST_NOEXCEPT { return left.size() == right.size() && std::equal(left.cbegin(), left.cend(), right.cbegin(), eq_lower_ch); } -_ASYNCRTIMP bool __cdecl str_iequal(const std::wstring& left, const std::wstring& right) CPPREST_NOEXCEPT +_ASYNCRTIMP bool __cdecl str_iequal(utility::wstring_view_t left, utility::wstring_view_t right) CPPREST_NOEXCEPT { return left.size() == right.size() && std::equal(left.cbegin(), left.cend(), right.cbegin(), eq_lower_ch); } -_ASYNCRTIMP bool __cdecl str_iless(const std::string& left, const std::string& right) CPPREST_NOEXCEPT +_ASYNCRTIMP bool __cdecl str_iless(utility::nstring_view_t left, utility::nstring_view_t right) CPPREST_NOEXCEPT { return std::lexicographical_compare(left.cbegin(), left.cend(), right.cbegin(), right.cend(), lt_lower_ch); } -_ASYNCRTIMP bool __cdecl str_iless(const std::wstring& left, const std::wstring& right) CPPREST_NOEXCEPT +_ASYNCRTIMP bool __cdecl str_iless(utility::wstring_view_t left, utility::wstring_view_t right) CPPREST_NOEXCEPT { return std::lexicographical_compare(left.cbegin(), left.cend(), right.cbegin(), right.cend(), lt_lower_ch); } @@ -228,7 +228,7 @@ scoped_c_thread_locale::~scoped_c_thread_locale() // or unsigned. using UtilCharInternal_t = signed char; -inline size_t count_utf8_to_utf16(const std::string& s) +inline size_t count_utf8_to_utf16(utility::nstring_view_t s) { const size_t sSize = s.size(); auto const sData = reinterpret_cast(s.data()); @@ -313,7 +313,7 @@ inline size_t count_utf8_to_utf16(const std::string& s) return result; } -utf16string __cdecl conversions::utf8_to_utf16(const std::string& s) +utf16string __cdecl conversions::utf8_to_utf16(utility::nstring_view_t s) { // Save repeated heap allocations, use the length of resulting sequence. const size_t srcSize = s.size(); @@ -384,9 +384,9 @@ utf16string __cdecl conversions::utf8_to_utf16(const std::string& s) return dest; } -inline size_t count_utf16_to_utf8(const utf16string& w) +inline size_t count_utf16_to_utf8(utf16string_view w) { - const utf16string::value_type* const srcData = &w[0]; + const utf16string::value_type* const srcData = w.data(); const size_t srcSize = w.size(); size_t destSize(srcSize); for (size_t index = 0; index < srcSize; ++index) @@ -425,10 +425,10 @@ inline size_t count_utf16_to_utf8(const utf16string& w) return destSize; } -std::string __cdecl conversions::utf16_to_utf8(const utf16string& w) +std::string __cdecl conversions::utf16_to_utf8(utf16string_view w) { const size_t srcSize = w.size(); - const utf16string::value_type* const srcData = &w[0]; + const utf16string::value_type* const srcData = w.data(); std::string dest(count_utf16_to_utf8(w), '\0'); std::string::value_type* const destData = &dest[0]; size_t destIndex(0); @@ -481,13 +481,13 @@ std::string __cdecl conversions::utf16_to_utf8(const utf16string& w) return dest; } -utf16string __cdecl conversions::usascii_to_utf16(const std::string& s) +utf16string __cdecl conversions::usascii_to_utf16(utility::nstring_view_t s) { // Ascii is a subset of UTF-8 so just convert to UTF-16 return utf8_to_utf16(s); } -utf16string __cdecl conversions::latin1_to_utf16(const std::string& s) +utf16string __cdecl conversions::latin1_to_utf16(utility::nstring_view_t s) { // Latin1 is the first 256 code points in Unicode. // In UTF-16 encoding each of these is represented as exactly the numeric code point. @@ -502,7 +502,7 @@ utf16string __cdecl conversions::latin1_to_utf16(const std::string& s) return dest; } -utf8string __cdecl conversions::latin1_to_utf8(const std::string& s) { return utf16_to_utf8(latin1_to_utf16(s)); } +utf8string __cdecl conversions::latin1_to_utf8(utility::nstring_view_t s) { return utf16_to_utf8(latin1_to_utf16(s)); } #ifndef _UTF16_STRINGS utility::string_t __cdecl conversions::to_string_t(utf16string&& s) { return utf16_to_utf8(std::move(s)); } @@ -513,15 +513,15 @@ utility::string_t __cdecl conversions::to_string_t(std::string&& s) { return utf #endif #ifndef _UTF16_STRINGS -utility::string_t __cdecl conversions::to_string_t(const utf16string& s) { return utf16_to_utf8(s); } +utility::string_t __cdecl conversions::to_string_t(utf16string_view s) { return utf16_to_utf8(s); } #endif #ifdef _UTF16_STRINGS -utility::string_t __cdecl conversions::to_string_t(const std::string& s) { return utf8_to_utf16(s); } +utility::string_t __cdecl conversions::to_string_t(utility::nstring_view_t s) { return utf8_to_utf16(s); } #endif -std::string __cdecl conversions::to_utf8string(const utf16string& value) { return utf16_to_utf8(value); } +std::string __cdecl conversions::to_utf8string(utf16string_view value) { return utf16_to_utf8(value); } -utf16string __cdecl conversions::to_utf16string(const std::string& value) { return utf8_to_utf16(value); } +utf16string __cdecl conversions::to_utf16string(utility::nstring_view_t value) { return utf8_to_utf16(value); } } // namespace utility diff --git a/Release/src/utilities/web_utilities.cpp b/Release/src/utilities/web_utilities.cpp index 67d15a343b..2096396e47 100644 --- a/Release/src/utilities/web_utilities.cpp +++ b/Release/src/utilities/web_utilities.cpp @@ -47,14 +47,14 @@ void winrt_secure_zero_buffer(Windows::Storage::Streams::IBuffer ^ buffer) } } -winrt_encryption::winrt_encryption(const ::utility::string_t& data) +winrt_encryption::winrt_encryption(utility::string_view_t data) { auto provider = ref new Windows::Security::Cryptography::DataProtection::DataProtectionProvider( ref new Platform::String(L"Local=user")); // Create buffer containing plain text password. Platform::ArrayReference arrayref( - reinterpret_cast(const_cast<::utility::string_t::value_type*>(data.c_str())), + reinterpret_cast(const_cast<::utility::string_t::value_type*>(data.data())), static_cast(data.size()) * sizeof(::utility::string_t::value_type)); Windows::Storage::Streams::IBuffer ^ plaintext = Windows::Security::Cryptography::CryptographicBuffer::CreateFromByteArray(arrayref); @@ -91,7 +91,7 @@ plaintext_string winrt_encryption::decrypt() const #else // ^^^ __cplusplus_winrt ^^^ // vvv !__cplusplus_winrt vvv -win32_encryption::win32_encryption(const ::utility::string_t& data) : m_numCharacters(data.size()) +win32_encryption::win32_encryption(::utility::string_view_t data) : m_numCharacters(data.size()) { // Early return because CryptProtectMemory crashes with empty string if (m_numCharacters == 0) @@ -113,7 +113,7 @@ win32_encryption::win32_encryption(const ::utility::string_t& data) : m_numChara assert((dataNumBytes % CRYPTPROTECTMEMORY_BLOCK_SIZE) == 0); assert(dataNumBytes >= dataSizeDword); m_buffer.resize(dataNumBytes); - memcpy_s(m_buffer.data(), m_buffer.size(), data.c_str(), dataNumBytes); + memcpy_s(m_buffer.data(), m_buffer.size(), data.data(), dataNumBytes); if (!CryptProtectMemory(m_buffer.data(), dataNumBytes, CRYPTPROTECTMEMORY_SAME_PROCESS)) { throw ::utility::details::create_system_error(GetLastError()); diff --git a/Release/tests/functional/utils/win32_encryption_tests.cpp b/Release/tests/functional/utils/win32_encryption_tests.cpp index a2be7cde5a..8b77d18988 100644 --- a/Release/tests/functional/utils/win32_encryption_tests.cpp +++ b/Release/tests/functional/utils/win32_encryption_tests.cpp @@ -26,7 +26,7 @@ SUITE(win32_encryption) { TEST(win32_encryption_random_string) { - utility::string_t rndStr = utility::conversions::to_string_t("random string"); + const auto rndStr = utility::conversions::to_string_t("random string"); web::details::win32_encryption enc(rndStr); VERIFY_ARE_EQUAL(*enc.decrypt(), rndStr); @@ -34,7 +34,7 @@ SUITE(win32_encryption) TEST(win32_encryption_empty_string) { - utility::string_t emptyStr = utility::conversions::to_string_t(""); + const auto emptyStr = utility::conversions::to_string_t(""); web::details::win32_encryption enc(emptyStr); VERIFY_ARE_EQUAL(*enc.decrypt(), emptyStr); diff --git a/azure-devops/build-windows.yml b/azure-devops/build-windows.yml index 45ea392a82..bbfa5bb465 100644 --- a/azure-devops/build-windows.yml +++ b/azure-devops/build-windows.yml @@ -2,6 +2,7 @@ parameters: name: 'Windows_VS2019_x86' targetPlatform: 'x86' image: 'windows-latest' + useStringViews: 'ON' jobs: - job: ${{ parameters.name }} @@ -30,7 +31,7 @@ jobs: cmakeBuildType: 'Debug' useVcpkgToolchainFile: true buildDirectory: $(Build.ArtifactStagingDirectory)/${{ parameters.targetPlatform }}_Debug - cmakeAppendedArgs: '-DCPPREST_EXCLUDE_BROTLI=OFF' + cmakeAppendedArgs: '-DCPPREST_EXCLUDE_BROTLI=OFF -DCPPREST_USE_STRING_VIEWS=${{ parameters.useStringViews }}' - script: | cd $(Build.ArtifactStagingDirectory)\${{ parameters.targetPlatform }}_Debug\Release\Binaries .\test_runner.exe *testd.dll @@ -43,7 +44,7 @@ jobs: cmakeBuildType: 'Release' useVcpkgToolchainFile: true buildDirectory: $(Build.ArtifactStagingDirectory)/${{ parameters.targetPlatform }}_Release - cmakeAppendedArgs: '-DCPPREST_EXCLUDE_BROTLI=OFF' + cmakeAppendedArgs: '-DCPPREST_EXCLUDE_BROTLI=OFF -DCPPREST_USE_STRING_VIEWS=${{ parameters.useStringViews }}' - script: | cd $(Build.ArtifactStagingDirectory)\${{ parameters.targetPlatform }}_Release\Release\Binaries .\test_runner.exe *test.dll diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 55f7683b3a..1eb56eaa8b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -26,11 +26,13 @@ jobs: name: 'Windows_VS2015_x86' targetPlatform: x86 image: 'vs2015-win2012r2' + useStringViews: 'OFF' - template: azure-devops/build-windows.yml parameters: name: 'Windows_VS2015_x64' targetPlatform: x64 image: 'vs2015-win2012r2' + useStringViews: 'OFF' - job: Windows_VS2019_UWP pool: vmImage: 'windows-latest' @@ -44,7 +46,7 @@ jobs: - task: CMake@1 inputs: workingDirectory: 'build.common' - cmakeArgs: '-A x64 -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0 ..' + cmakeArgs: '-A x64 -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0 -DCPPREST_USE_STRING_VIEWS=ON ..' - task: MSBuild@1 inputs: solution: 'build.common/ALL_BUILD.vcxproj'