Skip to content

Commit 6e9080e

Browse files
committed
Merge branch 'development' of https://git01.codeplex.com/casablanca into vs14rc_update
2 parents 4507bd3 + b462fe4 commit 6e9080e

File tree

10 files changed

+405
-45
lines changed

10 files changed

+405
-45
lines changed

Build/version.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<CppRestBaseFileName>cpprest</CppRestBaseFileName>
55
<CppRestSDKVersionMajor>2</CppRestSDKVersionMajor>
6-
<CppRestSDKVersionMinor>5</CppRestSDKVersionMinor>
6+
<CppRestSDKVersionMinor>6</CppRestSDKVersionMinor>
77
<CppRestSDKVersionRevision>0</CppRestSDKVersionRevision>
88
<CppRestSDKVersionFileSuffix>$(CppRestSDKVersionMajor)_$(CppRestSDKVersionMinor)</CppRestSDKVersionFileSuffix>
99
<CppRestSDKVersionString>$(CppRestSDKVersionMajor).$(CppRestSDKVersionMinor)</CppRestSDKVersionString>

CONTRIBUTORS.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ intercommiura
1717
halex2005
1818
simonlep
1919
jracle
20+
gandziej
2021

2122
AutoDesk Inc.
2223
Cyrille Fauvel (cyrillef)

Release/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ set(ANDROID_STL_FLAGS)
99

1010
# Platform (not compiler) specific settings
1111
if(IOS)
12-
set(IOS_SOURCE_DIR "${CMAKE_SOURCE_DIR}/../Build_iOS")
12+
set(IOS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../Build_iOS")
1313
set(Boost_FRAMEWORK "-F ${IOS_SOURCE_DIR} -framework boost")
1414
set(Boost_INCLUDE_DIR "${IOS_SOURCE_DIR}/boost.framework/Headers")
1515

@@ -36,7 +36,7 @@ elseif(ANDROID)
3636
set(BOOST_ROOT "${CMAKE_BINARY_DIR}/../Boost-for-Android-x86/build")
3737
set(BOOST_LIBRARYDIR "${CMAKE_BINARY_DIR}/../Boost-for-Android-x86/build/lib")
3838
endif()
39-
find_host_package(Boost 1.55 EXACT REQUIRED COMPONENTS random system thread locale filesystem chrono atomic)
39+
find_host_package(Boost 1.55 EXACT REQUIRED COMPONENTS random system thread filesystem chrono atomic)
4040

4141
set(OPENSSL_FOUND 1)
4242
if(ARM)
@@ -73,7 +73,7 @@ elseif(ANDROID)
7373
set(BUILD_SAMPLES OFF)
7474
option(BUILD_TESTS "Build tests." ON)
7575
elseif(UNIX) # This includes OSX
76-
find_package(Boost REQUIRED COMPONENTS random chrono system thread locale regex filesystem)
76+
find_package(Boost REQUIRED COMPONENTS random chrono system thread regex filesystem)
7777
find_package(Threads REQUIRED)
7878
if(APPLE AND NOT OPENSSL_ROOT_DIR)
7979
# Prefer a homebrew version of OpenSSL over the one in /usr/lib

Release/include/cpprest/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* ==--==
1717
*/
1818
#define CPPREST_VERSION_REVISION 0
19-
#define CPPREST_VERSION_MINOR 5
19+
#define CPPREST_VERSION_MINOR 6
2020
#define CPPREST_VERSION_MAJOR 2
2121

2222
#define CPPREST_VERSION (CPPREST_VERSION_MAJOR*100000+CPPREST_VERSION_MINOR*100+CPPREST_VERSION_REVISION)

Release/src/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ target_link_libraries(${Casablanca_LIBRARY}
8282
${Boost_THREAD_LIBRARY}
8383
${Boost_ATOMIC_LIBRARY}
8484
${Boost_CHRONO_LIBRARY}
85-
${Boost_LOCALE_LIBRARY}
8685
${Boost_RANDOM_LIBRARY}
8786
${EXTRALINKS}
8887
${Boost_FRAMEWORK}
@@ -93,7 +92,7 @@ target_link_libraries(${Casablanca_LIBRARY}
9392

9493
# Portions specific to cpprest binary versioning.
9594
set (CPPREST_VERSION_MAJOR 2)
96-
set (CPPREST_VERSION_MINOR 5)
95+
set (CPPREST_VERSION_MINOR 6)
9796
set (CPPREST_VERSION_REVISION 0)
9897

9998
if(WIN32)

Release/src/build/package_info.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<package>
22
<metadata>
33
<base_id>cpprestsdk</base_id>
4-
<version>2.5.0</version>
4+
<version>2.6.0</version>
55
<authors>casablancacore</authors>
66
<owners>Microsoft, Visual C++</owners>
77
<licenseUrl>http://www.apache.org/licenses/LICENSE-2.0</licenseUrl>
@@ -10,7 +10,7 @@
1010
<requireLicenseAcceptance>false</requireLicenseAcceptance>
1111
<summary>The C++ REST SDK is a cross-platform, modern, and asynchronous library that enables developers to access and author connected applications.</summary>
1212
<description>The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.</description>
13-
<releaseNotes>https://casablanca.codeplex.com/releases/view/574398</releaseNotes>
13+
<releaseNotes>https://casablanca.codeplex.com/releases/view/612765</releaseNotes>
1414
<copyright>Copyright 2015</copyright>
1515
<tags>cpprestsdk Casablanca REST JSON HTTP URI WebSockets</tags>
1616
</metadata>

Release/src/build/vs14.android/packages.config

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
<package id="boost_chrono-android" version="1.55.0.0" targetFramework="Native" />
66
<package id="boost_date_time-android" version="1.55.0.0" targetFramework="Native" />
77
<package id="boost_filesystem-android" version="1.55.0.0" targetFramework="Native" />
8-
<package id="boost_locale-android" version="1.55.0.0" targetFramework="Native" />
98
<package id="boost_system-android" version="1.55.0.0" targetFramework="Native" />
109
<package id="boost_thread-android" version="1.55.0.0" targetFramework="Native" />
11-
<package id="libiconv-android" version="1.13.1.0" targetFramework="Native" />
1210
<package id="openssl-android" version="1.0.1" targetFramework="Native" />
1311
</packages>

Release/src/http/listener/http_server_asio.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -853,21 +853,37 @@ pplx::task<void> http_linux_server::register_listener(details::http_listener_imp
853853
{
854854
pplx::extensibility::scoped_rw_lock_t lock(m_listeners_lock);
855855
if (m_registered_listeners.find(listener) != m_registered_listeners.end())
856+
{
856857
throw std::invalid_argument("listener already registered");
858+
}
857859

858-
m_registered_listeners[listener] = utility::details::make_unique<pplx::extensibility::reader_writer_lock_t>();
859-
860-
auto found_hostport_listener = m_listeners.find(hostport);
861-
if (found_hostport_listener == m_listeners.end())
860+
try
862861
{
863-
found_hostport_listener = m_listeners.insert(
864-
std::make_pair(hostport, utility::details::make_unique<details::hostport_listener>(this, hostport))).first;
862+
m_registered_listeners[listener] = utility::details::make_unique<pplx::extensibility::reader_writer_lock_t>();
865863

866-
if (m_started)
867-
found_hostport_listener->second->start();
868-
}
864+
auto found_hostport_listener = m_listeners.find(hostport);
865+
if (found_hostport_listener == m_listeners.end())
866+
{
867+
found_hostport_listener = m_listeners.insert(
868+
std::make_pair(hostport, utility::details::make_unique<details::hostport_listener>(this, hostport))).first;
869869

870-
found_hostport_listener->second->add_listener(path, listener);
870+
if (m_started)
871+
{
872+
found_hostport_listener->second->start();
873+
}
874+
}
875+
876+
found_hostport_listener->second->add_listener(path, listener);
877+
}
878+
catch (...)
879+
{
880+
// Future improvement - really this API should entirely be asychronously.
881+
// the hostport_listener::start() method should be made to return a task
882+
// throwing the exception.
883+
m_registered_listeners.erase(listener);
884+
m_listeners.erase(hostport);
885+
throw;
886+
}
871887
}
872888

873889
return pplx::task_from_result();

Release/src/utilities/asyncrt_utils.cpp

Lines changed: 155 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,9 @@
3030
#include <boost/date_time/posix_time/posix_time_io.hpp>
3131
#endif
3232

33-
#if defined(__GLIBCXX__)
34-
#include "boost/locale.hpp"
35-
#else
36-
// Not supported on libstdc++
33+
// Could use C++ standard library if not __GLIBCXX__,
34+
// For testing purposes we just the handwritten on all platforms.
35+
#if defined(CPPREST_STDLIB_UNICODE_CONVERSIONS)
3736
#include <codecvt>
3837
#endif
3938

@@ -253,24 +252,166 @@ const std::error_category & __cdecl linux_category()
253252

254253
}
255254

255+
#define LOW_3BITS 0x7
256+
#define LOW_4BITS 0xF
257+
#define LOW_5BITS 0x1F
258+
#define LOW_6BITS 0x3F
259+
#define BIT4 0x8
260+
#define BIT5 0x10
261+
#define BIT6 0x20
262+
#define BIT7 0x40
263+
#define BIT8 0x80
264+
#define L_SURROGATE_START 0xDC00
265+
#define L_SURROGATE_END 0xDFFF
266+
#define H_SURROGATE_START 0xD800
267+
#define H_SURROGATE_END 0xDBFF
268+
#define SURROGATE_PAIR_START 0x10000
269+
256270
utf16string __cdecl conversions::utf8_to_utf16(const std::string &s)
257271
{
258-
#if defined(__GLIBCXX__)
259-
return boost::locale::conv::utf_to_utf<utf16char>(s, boost::locale::conv::stop);
260-
#else
272+
#if defined(CPPREST_STDLIB_UNICODE_CONVERSIONS)
261273
std::wstring_convert<std::codecvt_utf8_utf16<utf16char>, utf16char> conversion;
262-
return conversion.from_bytes(s);
274+
return conversion.from_bytes(src);
275+
#else
276+
utf16string dest;
277+
// Save repeated heap allocations, use less than source string size assuming some
278+
// of the characters are not just ASCII and collapse.
279+
dest.reserve(static_cast<size_t>(static_cast<double>(s.size()) * .70));
280+
281+
for (auto src = s.begin(); src != s.end(); ++src)
282+
{
283+
if ((*src & BIT8) == 0) // single byte character, 0x0 to 0x7F
284+
{
285+
dest.push_back(utf16string::value_type(*src));
286+
}
287+
else
288+
{
289+
if ((*src & BIT8) != 0 && (*src & BIT7) == 0)
290+
{
291+
throw std::range_error("UTF-8 string character can never start with 10xxxxxx");
292+
}
293+
294+
unsigned char numContBytes = 0;
295+
uint32_t codePoint;
296+
if ((*src & BIT6) == 0) // 2 byte character, 0x80 to 0x7FF
297+
{
298+
codePoint = *src & LOW_5BITS;
299+
numContBytes = 1;
300+
}
301+
else if ((*src & BIT5) == 0) // 3 byte character, 0x800 to 0xFFFF
302+
{
303+
codePoint = *src & LOW_4BITS;
304+
numContBytes = 2;
305+
}
306+
else if ((*src & BIT4) == 0) // 4 byte character, 0x10000 to 0x10FFFF
307+
{
308+
codePoint = *src & LOW_3BITS;
309+
numContBytes = 3;
310+
}
311+
else
312+
{
313+
throw std::range_error("UTF-8 string has invalid Unicode code point");
314+
}
315+
316+
for (unsigned char i = 0; i < numContBytes; ++i)
317+
{
318+
if (++src == s.end())
319+
{
320+
throw std::range_error("UTF-8 string is missing bytes in character");
321+
}
322+
if ((*src & BIT8) == 0 || (*src & BIT7) != 0)
323+
{
324+
throw std::range_error("UTF-8 continuation byte is missing leading byte");
325+
}
326+
codePoint <<= 6;
327+
codePoint |= *src & LOW_6BITS;
328+
}
329+
330+
if (codePoint >= SURROGATE_PAIR_START)
331+
{
332+
// In UTF-16 U+10000 to U+10FFFF are represented as two 16-bit code units, surrogate pairs.
333+
// - 0x10000 is subtracted from the code point
334+
// - high surrogate is 0xD800 added to the top ten bits
335+
// - low surrogate is 0xDC00 added to the low ten bits
336+
codePoint -= SURROGATE_PAIR_START;
337+
dest.push_back(utf16string::value_type((codePoint >> 10) | H_SURROGATE_START));
338+
dest.push_back(utf16string::value_type((codePoint & 0x3FF) | L_SURROGATE_START));
339+
}
340+
else
341+
{
342+
// In UTF-16 U+0000 to U+D7FF and U+E000 to U+FFFF are represented exactly as the Unicode code point value.
343+
// U+D800 to U+DFFF are not valid characters, for simplicity we assume they are not present but will encode
344+
// them if encountered.
345+
dest.push_back(utf16string::value_type(codePoint));
346+
}
347+
}
348+
}
349+
return dest;
263350
#endif
264351
}
265352

266353
std::string __cdecl conversions::utf16_to_utf8(const utf16string &w)
267354
{
268-
#if defined(__GLIBCXX__)
269-
return boost::locale::conv::utf_to_utf<char>(w, boost::locale::conv::stop);
270-
#else
271-
std::wstring_convert<std::codecvt_utf8_utf16<utf16char>, utf16char> conversion;
272-
return conversion.to_bytes(w);
273-
#endif
355+
#if defined(CPPREST_STDLIB_UNICODE_CONVERSIONS)
356+
std::wstring_convert<std::codecvt_utf8_utf16<utf16char>, utf16char> conversion;
357+
return conversion.to_bytes(w);
358+
#else
359+
std::string dest;
360+
dest.reserve(w.size());
361+
for (auto src = w.begin(); src != w.end(); ++src)
362+
{
363+
// Check for high surrogate.
364+
if (*src >= H_SURROGATE_START && *src <= H_SURROGATE_END)
365+
{
366+
const auto highSurrogate = *src++;
367+
if (src == w.end())
368+
{
369+
throw std::range_error("UTF-16 string is missing low surrogate");
370+
}
371+
const auto lowSurrogate = *src;
372+
if (lowSurrogate < L_SURROGATE_START || lowSurrogate > L_SURROGATE_END)
373+
{
374+
throw std::range_error("UTF-16 string has invalid low surrogate");
375+
}
376+
377+
// To get from surrogate pair to Unicode code point:
378+
// - subract 0xD800 from high surrogate, this forms top ten bits
379+
// - subract 0xDC00 from low surrogate, this forms low ten bits
380+
// - add 0x10000
381+
// Leaves a code point in U+10000 to U+10FFFF range.
382+
uint32_t codePoint = highSurrogate - H_SURROGATE_START;
383+
codePoint <<= 10;
384+
codePoint |= lowSurrogate - L_SURROGATE_START;
385+
codePoint |= SURROGATE_PAIR_START;
386+
387+
// 4 bytes need using 21 bits
388+
dest.push_back(char((codePoint >> 18) | 0xF0)); // leading 3 bits
389+
dest.push_back(char(((codePoint >> 12) & LOW_6BITS) | BIT8)); // next 6 bits
390+
dest.push_back(char(((codePoint >> 6) & LOW_6BITS) | BIT8)); // next 6 bits
391+
dest.push_back(char((codePoint & LOW_6BITS) | BIT8)); // trailing 6 bits
392+
}
393+
else
394+
{
395+
if (*src <= 0x7F) // single byte character
396+
{
397+
dest.push_back(static_cast<char>(*src));
398+
}
399+
else if (*src <= 0x7FF) // 2 bytes needed (11 bits used)
400+
{
401+
dest.push_back(char((*src >> 6) | 0xC0)); // leading 5 bits
402+
dest.push_back(char((*src & LOW_6BITS) | BIT8)); // trailing 6 bits
403+
}
404+
else // 3 bytes needed (16 bits used)
405+
{
406+
dest.push_back(char((*src >> 12) | 0xE0)); // leading 4 bits
407+
dest.push_back(char(((*src >> 6) & LOW_6BITS) | BIT8)); // middle 6 bits
408+
dest.push_back(char((*src & LOW_6BITS) | BIT8)); // trailing 6 bits
409+
}
410+
}
411+
}
412+
413+
return dest;
414+
#endif
274415
}
275416

276417
utf16string __cdecl conversions::usascii_to_utf16(const std::string &s)

0 commit comments

Comments
 (0)