Skip to content

Commit 5515244

Browse files
committed
Merge branch 'development' of https://git01.codeplex.com/casablanca into default_workarounds
2 parents c9b857b + e800120 commit 5515244

35 files changed

+276
-206
lines changed

CONTRIBUTORS.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ Brian Wengert (bwengert79)
99
Leslie Brody (Les1966)
1010
Michael M (M1xa)
1111
Matt Peterson (MattPeterson1)
12+
Dmitry Kolomiets (kolomiets)
1213

1314

Release/include/cpprest/asyncrt_utils.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,10 @@ namespace pplx = Concurrency;
4949

5050
#ifndef _MS_WINDOWS
5151
#include <boost/algorithm/string.hpp>
52+
#ifndef ANDROID // CodePlex 269
5253
#include <xlocale.h>
5354
#endif
55+
#endif
5456

5557
/// Various utilities for string conversions and date and time manipulation.
5658
namespace utility
@@ -170,18 +172,20 @@ namespace details
170172
_ASYNCRTIMP scoped_c_thread_locale();
171173
_ASYNCRTIMP ~scoped_c_thread_locale();
172174

175+
#ifndef ANDROID // CodePlex 269
173176
#ifdef _MS_WINDOWS
174177
typedef _locale_t xplat_locale;
175178
#else
176179
typedef locale_t xplat_locale;
177180
#endif
178181

179182
static _ASYNCRTIMP xplat_locale __cdecl c_locale();
183+
#endif
180184
private:
181185
#ifdef _MS_WINDOWS
182186
std::string m_prevLocale;
183187
int m_prevThreadSetting;
184-
#else
188+
#elif !defined(ANDROID)
185189
locale_t m_prevLocale;
186190
#endif
187191
scoped_c_thread_locale(const scoped_c_thread_locale &);

Release/include/cpprest/filestream.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,6 @@ namespace details {
737737
}
738738
#endif
739739

740-
#pragma region Completion callback interface implementations
741740
class _filestream_callback_open : public details::_filestream_callback
742741
{
743742
public:
@@ -942,7 +941,6 @@ namespace details {
942941
_file_info *m_info;
943942
pplx::task_completion_event<int_type> m_op;
944943
};
945-
#pragma endregion
946944

947945
_file_info *m_info;
948946
async_operation_queue m_readOps;

Release/include/cpprest/http_listener.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ class http_listener_impl
139139

140140
http_listener_impl()
141141
: m_closed(true)
142+
, m_close_task(pplx::task_from_result())
142143
{
143144
}
144145

@@ -176,6 +177,7 @@ class http_listener_impl
176177

177178
// Used to record that the listener is closed.
178179
bool m_closed;
180+
pplx::task<void> m_close_task;
179181
};
180182

181183
} // namespace details
@@ -315,4 +317,4 @@ class http_listener
315317
} // namespace http
316318
} // namespace web
317319

318-
#endif /* _CASA_HTTP_LISTENER_H */
320+
#endif /* _CASA_HTTP_LISTENER_H */

Release/include/cpprest/interopstream.h

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ namespace Concurrency { namespace streams {
5757
template<typename CharType> class stdio_ostream;
5858
template<typename CharType> class stdio_istream;
5959

60-
#pragma region Asynchronous streams on top of synchronous stream buffers.
6160
namespace details {
6261

6362
/// <summary>
@@ -104,7 +103,7 @@ namespace Concurrency { namespace streams {
104103
virtual size_t buffer_size(std::ios_base::openmode direction = std::ios_base::in) const { return 0; }
105104
virtual void set_buffer_size(size_t size, std::ios_base::openmode direction = std::ios_base::in) { return; }
106105

107-
virtual pplx::task<bool> _sync() { return pplx::task_from_result(m_buffer->pubsync() != std::char_traits<_CharType>::eof()); }
106+
virtual pplx::task<bool> _sync() { return pplx::task_from_result(m_buffer->pubsync() == 0); }
108107

109108
virtual pplx::task<int_type> _putc(_CharType ch) { return pplx::task_from_result(m_buffer->sputc(ch)); }
110109
virtual pplx::task<size_t> _putn(const _CharType *ptr, size_t size) { return pplx::task_from_result((size_t)m_buffer->sputn(ptr, size)); }
@@ -228,10 +227,6 @@ namespace Concurrency { namespace streams {
228227
stdio_istream & operator =(const stdio_istream &other) { basic_istream<CharType>::operator=(other); return *this; }
229228
};
230229

231-
#pragma endregion
232-
233-
#pragma region Synchronous streams on top of asynchronous stream buffers.
234-
235230
namespace details {
236231

237232
/// <summary>
@@ -504,10 +499,8 @@ namespace Concurrency { namespace streams {
504499
private:
505500
details::basic_async_streambuf<CharType> m_strbuf;
506501
};
507-
#pragma endregion
508502

509503
#if defined(__cplusplus_winrt)
510-
#pragma region WinRT streams interop
511504

512505
/// <summary>
513506
/// Static class containing factory functions for WinRT streams implemented on top of Casablanca async streams.
@@ -554,7 +547,6 @@ namespace Concurrency { namespace streams {
554547
};
555548

556549
#endif
557-
#pragma endregion
558550

559551
}} // namespaces
560552
#pragma warning(pop) // 4100

Release/include/cpprest/json.h

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,16 +150,56 @@ namespace json
150150
/// Constructor creating a JSON string value
151151
/// </summary>
152152
/// <param name="value">The C++ value to create a JSON value from, a C++ STL string of the platform-native character width</param>
153-
_ASYNCRTIMP explicit value(utility::string_t);
153+
/// <remarks>
154+
/// This constructor has O(n) performance because it tries to determine if
155+
/// specified string has characters that should be properly escaped in JSON.
156+
/// <remarks>
157+
_ASYNCRTIMP explicit value(utility::string_t value);
158+
159+
/// <summary>
160+
/// Constructor creating a JSON string value specifying if the string contains characters to escape
161+
/// </summary>
162+
/// <param name="value">The C++ value to create a JSON value from, a C++ STL string of the platform-native character width</param>
163+
/// <param name="has_escape_chars">Whether <paramref name="value" /> contains characters
164+
/// that should be escaped in JSON value</param>
165+
/// <remarks>
166+
/// This constructor has O(1) performance.
167+
/// </remarks>
168+
_ASYNCRTIMP explicit value(utility::string_t value, bool has_escape_chars);
154169

155170
/// <summary>
156171
/// Constructor creating a JSON string value
157172
/// </summary>
158173
/// <param name="value">The C++ value to create a JSON value from, a C++ STL string of the platform-native character width</param>
159-
/// <remarks>This constructor exists in order to avoid string literals matching another constructor,
174+
/// <remarks>
175+
/// <para>
176+
/// This constructor has O(n) performance because it tries to determine if
177+
/// specified string has characters that should be properly escaped in JSON.
178+
/// </para>
179+
/// <para>
180+
/// This constructor exists in order to avoid string literals matching another constructor,
160181
/// as is very likely. For example, conversion to bool does not require a user-defined conversion,
161-
/// and will therefore match first, which means that the JSON value turns up as a boolean.</remarks>
162-
_ASYNCRTIMP explicit value(const utility::char_t *);
182+
/// and will therefore match first, which means that the JSON value turns up as a boolean.
183+
/// </para>
184+
/// </remarks>
185+
_ASYNCRTIMP explicit value(const utility::char_t* value);
186+
187+
/// <summary>
188+
/// Constructor creating a JSON string value
189+
/// </summary>
190+
/// <param name="value">The C++ value to create a JSON value from, a C++ STL string of the platform-native character width</param>
191+
/// <param name="has_escape_chars">Whether <paramref name="value" /> contains characters
192+
/// <remarks>
193+
/// <para>
194+
/// This overload has O(1) performance.
195+
/// </para>
196+
/// <para>
197+
/// This constructor exists in order to avoid string literals matching another constructor,
198+
/// as is very likely. For example, conversion to bool does not require a user-defined conversion,
199+
/// and will therefore match first, which means that the JSON value turns up as a boolean.
200+
/// </para>
201+
/// </remarks>
202+
_ASYNCRTIMP explicit value(const utility::char_t* value, bool has_escape_chars);
163203

164204
/// <summary>
165205
/// Copy constructor
@@ -217,8 +257,24 @@ namespace json
217257
/// </summary>
218258
/// <param name="value">The C++ value to create a JSON value from</param>
219259
/// <returns>A JSON string value</returns>
260+
/// <remarks>
261+
/// This overload has O(n) performance because it tries to determine if
262+
/// specified string has characters that should be properly escaped in JSON.
263+
/// <remarks>
220264
static _ASYNCRTIMP value __cdecl string(utility::string_t value);
221265

266+
/// <summary>
267+
/// Creates a string value specifying if the string contains characters to escape
268+
/// </summary>
269+
/// <param name="value">The C++ value to create a JSON value from</param>
270+
/// <param name="has_escape_chars">Whether <paramref name="value" /> contains characters
271+
/// that should be escaped in JSON value</param>
272+
/// <returns>A JSON string value</returns>
273+
/// <remarks>
274+
/// This overload has O(1) performance.
275+
/// </remarks>
276+
static _ASYNCRTIMP value __cdecl string(utility::string_t value, bool has_escape_chars);
277+
222278
#ifdef _MS_WINDOWS
223279
private:
224280
// Only used internally by JSON parser.

Release/include/cpprest/streams.h

Lines changed: 29 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -953,18 +953,41 @@ namespace Concurrency { namespace streams
953953
if ( !target.can_write() )
954954
return pplx::task_from_exception<size_t>(std::make_exception_ptr(std::runtime_error("source buffer not set up for input of data")));
955955

956-
// Capture 'buffer' rather than 'helper' here due to VC++ 2010 limitations.
957-
auto buffer = helper()->m_buffer;
956+
auto l_buffer = helper()->m_buffer;
957+
auto l_buf_size = this->buf_size;
958+
std::shared_ptr<_read_helper> l_locals = std::make_shared<_read_helper>();
958959

959-
std::shared_ptr<_read_helper> _locals = std::make_shared<_read_helper>();
960+
auto copy_to_target = [l_locals, target, l_buffer, l_buf_size]() mutable -> pplx::task<bool>
961+
{
962+
// We need to capture these, because the object itself may go away
963+
// before we're done processing the data.
964+
//auto locs = _locals;
965+
//auto trg = target;
966+
967+
return l_buffer.getn(l_locals->outbuf, l_buf_size).then([=](size_t rd) mutable -> pplx::task<bool>
968+
{
969+
if (rd == 0)
970+
return pplx::task_from_result(false);
960971

961-
_dev10_ice_workaround wrkarnd(buffer, target, _locals, buf_size);
972+
// Must be nested to capture rd
973+
return target.putn(l_locals->outbuf, rd).then([target, l_locals, rd](size_t wr) mutable -> pplx::task<bool>
974+
{
975+
l_locals->total += wr;
962976

963-
auto loop = pplx::details::do_while(wrkarnd);
977+
if (rd != wr)
978+
// Number of bytes written is less than number of bytes received.
979+
throw std::runtime_error("failed to write all bytes");
980+
981+
return target.sync().then([]() { return true; });
982+
});
983+
});
984+
};
985+
986+
auto loop = pplx::details::do_while(copy_to_target);
964987

965988
return loop.then([=](bool) mutable -> size_t
966989
{
967-
return _locals->total;
990+
return l_locals->total;
968991
});
969992
}
970993

@@ -1104,48 +1127,6 @@ namespace Concurrency { namespace streams
11041127
}
11051128
};
11061129

1107-
// To workaround a VS 2010 internal compiler error, we have to do our own
1108-
// "lambda" here...
1109-
class _dev10_ice_workaround
1110-
{
1111-
public:
1112-
_dev10_ice_workaround(streams::streambuf<CharType> buffer,
1113-
concurrency::streams::streambuf<CharType> target,
1114-
std::shared_ptr<typename basic_istream::_read_helper> locals,
1115-
size_t buf_size)
1116-
: _buffer(buffer), _target(target), _locals(locals), _buf_size(buf_size)
1117-
{
1118-
}
1119-
pplx::task<bool> operator()()
1120-
{
1121-
// We need to capture these, because the object itself may go away
1122-
// before we're done processing the data.
1123-
auto locs = _locals;
1124-
auto trg = _target;
1125-
1126-
auto after_putn =
1127-
[=](size_t wr) mutable -> bool
1128-
{
1129-
locs->total += wr;
1130-
trg.sync().wait();
1131-
return true;
1132-
};
1133-
1134-
return _buffer.getn(locs->outbuf, buf_size).then(
1135-
[=] (size_t rd) mutable -> pplx::task<bool>
1136-
{
1137-
if ( rd == 0 )
1138-
return pplx::task_from_result(false);
1139-
return trg.putn(locs->outbuf, rd).then(after_putn);
1140-
});
1141-
}
1142-
private:
1143-
size_t _buf_size;
1144-
concurrency::streams::streambuf<CharType> _buffer;
1145-
concurrency::streams::streambuf<CharType> _target;
1146-
std::shared_ptr<typename basic_istream::_read_helper> _locals;
1147-
};
1148-
11491130
std::shared_ptr<details::basic_istream_helper<CharType>> m_helper;
11501131
};
11511132

Release/src/build/casablanca110.vcxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
<AdditionalIncludeDirectories>$(CasablancaIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
4444
<PrecompiledHeader>Use</PrecompiledHeader>
4545
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
46-
<AdditionalOptions>-Zm160 %(AdditionalOptions)</AdditionalOptions>
46+
<AdditionalOptions>-Zm160 /bigobj%(AdditionalOptions)</AdditionalOptions>
4747
</ClCompile>
4848
<Link>
4949
<AdditionalDependencies>Winhttp.lib;httpapi.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>

Release/src/build/casablanca110.winrt.vcxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
<AdditionalIncludeDirectories>$(CasablancaIncludeDir);$(CasablancaSrcDir)\pch;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
4949
<PrecompiledHeader>Use</PrecompiledHeader>
5050
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
51-
<AdditionalOptions>-Zm250 %(AdditionalOptions)</AdditionalOptions>
51+
<AdditionalOptions>-Zm250 /bigobj %(AdditionalOptions)</AdditionalOptions>
5252
</ClCompile>
5353
<Link>
5454
<AdditionalDependencies>msxml6.lib;kernel32.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>

Release/src/build/casablanca110.xp.vcxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
<AdditionalIncludeDirectories>$(CasablancaIncludeDir);$(CasablancaSrcDir)\pch;$(WebsocketppIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
4444
<PrecompiledHeader>Use</PrecompiledHeader>
4545
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
46-
<AdditionalOptions>-Zm160 %(AdditionalOptions)</AdditionalOptions>
46+
<AdditionalOptions>-Zm160 /bigobj %(AdditionalOptions)</AdditionalOptions>
4747
</ClCompile>
4848
<Link>
4949
<AdditionalDependencies>Kernel32.lib;Winhttp.lib;httpapi.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies>

0 commit comments

Comments
 (0)