27 #ifndef _CASA_STREAMS_H
28 #define _CASA_STREAMS_H
30 #include "cpprest/astreambuf.h"
35 template<
typename CharType>
class basic_ostream;
36 template<
typename CharType>
class basic_istream;
39 template<
typename CharType>
50 concurrency::streams::streambuf<CharType> m_buffer;
53 template<
typename CharType>
64 concurrency::streams::streambuf<CharType> m_buffer;
67 template <
typename CharType>
71 static std::basic_string<CharType> format(
const T &val)
73 std::basic_ostringstream<CharType> ss;
83 static std::basic_string<uint8_t> format(
const T &val)
85 std::basic_ostringstream<char> ss;
87 return reinterpret_cast<const uint8_t *
>(ss.str().c_str());
90 static std::basic_string<uint8_t> format(
const utf16string &val)
97 static const char *_in_stream_msg =
"stream not set up for input of data";
98 static const char *_in_streambuf_msg =
"stream buffer not set up for input of data";
99 static const char *_out_stream_msg =
"stream not set up for output of data";
100 static const char *_out_streambuf_msg =
"stream buffer not set up for output of data";
106 template<
typename CharType>
112 typedef typename traits::int_type int_type;
113 typedef typename traits::pos_type pos_type;
114 typedef typename traits::off_type off_type;
139 m_helper(std::make_shared<details::basic_ostream_helper<CharType>>(buffer))
141 _verify_and_throw(details::_out_streambuf_msg);
150 helper()->m_buffer.close(std::ios_base::out) :
151 pplx::task_from_result();
161 helper()->m_buffer.close(std::ios_base::out, eptr) :
162 pplx::task_from_result();
172 if ( !_verify_and_return_task(details::_out_stream_msg, result) )
return result;
173 return helper()->m_buffer.putc(ch);
189 CASABLANCA_DEPRECATED(
"Unsafe API that will be removed in future releases, use one of the other write overloads instead.")
192 static_assert(
sizeof(CharType) == 1,
"binary write is only supported for single-byte streams");
193 static_assert(std::is_trivial<T>::value,
"unsafe to use with non-trivial types");
196 if ( !_verify_and_return_task(details::_out_stream_msg, result) )
return result;
198 auto copy = std::make_shared<T>(std::move(value));
199 return helper()->m_buffer.putn_nocopy((CharType*)copy.get(),
sizeof(T)).then([copy](
pplx::task<size_t> op) ->
size_t {
return op.
get(); });
210 if ( !_verify_and_return_task(details::_out_stream_msg, result) )
return result;
212 return pplx::task_from_exception<size_t>(std::make_exception_ptr(std::runtime_error(
"source buffer not set up for input of data")));
215 return pplx::task_from_result((
size_t)0);
217 auto buffer = helper()->m_buffer;
218 auto data = buffer.alloc(count);
220 if ( data !=
nullptr )
229 return source.
getn(data, count).then(post_read);
233 size_t available = 0;
235 const bool acquired = source.
acquire(data, available);
236 if (available >= count)
245 return buffer.putn_nocopy(data, count).then(post_write);
255 std::shared_ptr<CharType> buf(
new CharType[count], [](CharType *buf) {
delete [] buf; });
266 return b.putn_nocopy(buf.get(), op.get()).then(post_write);
269 return source.
getn(buf.get(), count).then(post_read);
281 if ( !_verify_and_return_task(details::_out_stream_msg, result) )
return result;
285 return pplx::task_from_result<size_t>(0);
289 auto sharedStr = std::make_shared<std::basic_string<CharType>>(str);
290 return helper()->m_buffer.putn_nocopy(sharedStr->c_str(), sharedStr->size()).then([sharedStr](
size_t size) {
return size; });
305 if ( !_verify_and_return_task(details::_out_stream_msg, result) )
return result;
322 if ( !_verify_and_return_task(details::_out_stream_msg, result) )
return result;
324 str.push_back(CharType(
'\n'));
334 if ( !_verify_and_return_task(details::_out_stream_msg, result) )
return result;
335 return helper()->m_buffer.sync();
343 pos_type
seek(pos_type pos)
const
345 _verify_and_throw(details::_out_stream_msg);
346 return helper()->m_buffer.seekpos(pos, std::ios_base::out);
355 pos_type
seek(off_type off, std::ios_base::seekdir way)
const
357 _verify_and_throw(details::_out_stream_msg);
358 return helper()->m_buffer.seekoff(off, way, std::ios_base::out);
367 _verify_and_throw(details::_out_stream_msg);
368 return helper()->m_buffer.getpos(std::ios_base::out);
381 bool is_valid()
const {
return (m_helper !=
nullptr) && ((bool)m_helper->m_buffer); }
398 concurrency::streams::streambuf<CharType>
streambuf()
const
400 return helper()->m_buffer;
413 bool _verify_and_return_task(
const char *msg,
pplx::task<T> &tsk)
const
415 auto buffer = helper()->m_buffer;
416 if ( !(buffer.exception() ==
nullptr) )
418 tsk = pplx::task_from_exception<T>(buffer.exception());
421 if ( !buffer.can_write() )
423 tsk = pplx::task_from_exception<T>(std::make_exception_ptr(std::runtime_error(msg)));
429 void _verify_and_throw(
const char *msg)
const
431 auto buffer = helper()->m_buffer;
432 if ( !(buffer.exception() ==
nullptr) )
433 std::rethrow_exception(buffer.exception());
434 if ( !buffer.can_write() )
435 throw std::runtime_error(msg);
438 std::shared_ptr<details::basic_ostream_helper<CharType>> helper()
const
441 throw std::logic_error(
"uninitialized stream object");
445 std::shared_ptr<details::basic_ostream_helper<CharType>> m_helper;
448 template<
typename int_type>
451 typedef std::false_type _is_integral;
452 typedef std::false_type _is_unsigned;
456 #define _INT_TRAIT(_t,_low,_high) template<> struct _type_parser_integral_traits<_t>{typedef std::true_type _is_integral;typedef std::false_type _is_unsigned;static const int64_t _min = _low;static const int64_t _max = _high;};
457 #define _UINT_TRAIT(_t,_low,_high) template<> struct _type_parser_integral_traits<_t>{typedef std::true_type _is_integral;typedef std::true_type _is_unsigned;static const uint64_t _max = _high;};
459 _INT_TRAIT(
char,INT8_MIN,INT8_MAX)
460 _INT_TRAIT(
signed char,INT8_MIN,INT8_MAX)
461 _INT_TRAIT(
short,INT16_MIN,INT16_MAX)
462 _INT_TRAIT(utf16char,INT16_MIN,INT16_MAX)
463 _INT_TRAIT(
int,INT32_MIN,INT32_MAX)
464 _INT_TRAIT(
long, LONG_MIN, LONG_MAX)
465 _INT_TRAIT(
long long, LLONG_MIN, LLONG_MAX)
466 _UINT_TRAIT(
unsigned char,UINT8_MIN,UINT8_MAX)
467 _UINT_TRAIT(
unsigned short,UINT16_MIN,UINT16_MAX)
468 _UINT_TRAIT(
unsigned int,UINT32_MIN,UINT32_MAX)
469 _UINT_TRAIT(
unsigned long, ULONG_MIN, ULONG_MAX)
470 _UINT_TRAIT(
unsigned long long, ULLONG_MIN, ULLONG_MAX)
472 #define _INT_TRAIT(_t) template<> struct _type_parser_integral_traits<_t>{typedef std::true_type _is_integral;typedef std::false_type _is_unsigned;static const int64_t _min = std::numeric_limits<_t>::min();static const int64_t _max = (std::numeric_limits<_t>::max)();};
473 #define _UINT_TRAIT(_t) template<> struct _type_parser_integral_traits<_t>{typedef std::true_type _is_integral;typedef std::true_type _is_unsigned;static const uint64_t _max = (std::numeric_limits<_t>::max)();};
476 _INT_TRAIT(
signed char)
478 _INT_TRAIT(utf16char)
481 _INT_TRAIT(
long long)
482 _UINT_TRAIT(
unsigned char)
483 _UINT_TRAIT(
unsigned short)
484 _UINT_TRAIT(
unsigned int)
485 _UINT_TRAIT(
unsigned long)
486 _UINT_TRAIT(
unsigned long long)
489 template<
typename CharType>
493 typedef typename ::concurrency::streams::char_traits<CharType>::int_type int_type;
504 template<
typename StateType,
typename ReturnType,
typename AcceptFunctor,
typename ExtractFunctor>
512 template<
typename CharType,
typename T>
518 typename _type_parser_integral_traits<T>::_is_integral ii;
519 typename _type_parser_integral_traits<T>::_is_unsigned ui;
520 return _parse(buffer, ii, ui);
525 _parse_floating_point(buffer);
531 static_assert(
false,
"type is not supported for extraction from a stream");
533 throw std::runtime_error(
"type is not supported for extraction from a stream");
542 int64_t val = op.
get();
546 throw std::range_error(
"input out of range for target type");
555 uint64_t val = op.
get();
559 throw std::range_error(
"input out of range for target type");
567 template<
typename CharType>
574 typedef typename traits::pos_type pos_type;
575 typedef typename traits::off_type off_type;
592 _verify_and_throw(details::_in_streambuf_msg);
608 m_helper = other.m_helper;
618 helper()->m_buffer.close(std::ios_base::in) :
619 pplx::task_from_result();
629 m_helper->m_buffer.close(std::ios_base::in, eptr) :
630 pplx::task_from_result();
639 return is_valid() ? m_helper->m_buffer.is_eof() :
false;
649 if ( !_verify_and_return_task(details::_in_stream_msg, result) )
return result;
650 return helper()->m_buffer.bumpc();
666 CASABLANCA_DEPRECATED(
"Unsafe API that will be removed in future releases, use one of the other read overloads instead.")
669 static_assert(
sizeof(CharType) == 1,
"binary read is only supported for single-byte streams");
670 static_assert(std::is_trivial<T>::value,
"unsafe to use with non-trivial types");
673 if ( !_verify_and_return_task(details::_in_stream_msg, result) )
return result;
675 auto copy = std::make_shared<T>();
676 return helper()->m_buffer.getn((CharType*)copy.get(),
sizeof(T)).then([copy](
pplx::task<size_t> op) -> T
678 return std::move(*copy);
691 if ( !_verify_and_return_task(details::_in_stream_msg, result) )
return result;
693 return pplx::task_from_exception<size_t>(std::make_exception_ptr(std::runtime_error(
"target not set up for output of data")));
696 auto buffer = helper()->m_buffer;
698 auto data = target.
alloc(count);
700 if ( data !=
nullptr )
709 return buffer.getn(data, count).then(post_read);
713 size_t available = 0;
715 const bool acquired = buffer.acquire(data, available);
716 if (available >= count)
722 b.release(data, op.get());
725 return target.
putn_nocopy(data, count).then(post_write);
732 buffer.release(data, 0);
735 std::shared_ptr<CharType> buf(
new CharType[count], [](CharType *buf) {
delete [] buf; });
746 return trg.putn_nocopy(buf.get(), op.get()).then(post_write);
749 return helper()->m_buffer.getn(buf.get(), count).then(post_read);
761 if ( !_verify_and_return_task(details::_in_stream_msg, result) )
return result;
762 return helper()->m_buffer.getc();
775 if ( !_verify_and_return_task(details::_in_stream_msg, result) )
return result;
777 return pplx::task_from_exception<size_t>(std::make_exception_ptr(std::runtime_error(
"target not set up for output of data")));
780 auto buffer = helper()->m_buffer;
782 int_type req_async = ::concurrency::streams::char_traits<CharType>::requires_async();
784 std::shared_ptr<_read_helper> _locals = std::make_shared<_read_helper>();
786 auto flush = [=]()
mutable
788 return target.
putn_nocopy(_locals->outbuf, _locals->write_pos).then([=](
size_t wrote)
mutable
790 _locals->total += wrote;
791 _locals->write_pos = 0;
792 return target.
sync();
796 auto update = [=](int_type ch)
mutable
798 if (ch == ::concurrency::streams::char_traits<CharType>::eof())
return false;
799 if (ch == delim)
return false;
801 _locals->outbuf[_locals->write_pos] =
static_cast<CharType
>(ch);
802 _locals->write_pos += 1;
804 if (_locals->is_full())
816 while (buffer.in_avail() > 0)
818 int_type ch = buffer.sbumpc();
827 return pplx::task_from_result(
false);
830 return buffer.bumpc().then(update);
833 return loop.then([=](
bool)
mutable
835 return flush().then([=] {
return _locals->total; });
847 if ( !_verify_and_return_task(details::_in_stream_msg, result) )
return result;
849 return pplx::task_from_exception<size_t>(std::make_exception_ptr(std::runtime_error(
"target not set up for receiving data")));
852 concurrency::streams::streambuf<CharType> buffer = helper()->m_buffer;
854 typename concurrency::streams::char_traits<CharType>::int_type req_async = concurrency::streams::char_traits<CharType>::requires_async();
856 std::shared_ptr<_read_helper> _locals = std::make_shared<_read_helper>();
858 auto flush = [=]()
mutable
860 return target.
putn_nocopy(_locals->outbuf, _locals->write_pos).then([=](
size_t wrote)
mutable
862 _locals->total += wrote;
863 _locals->write_pos = 0;
864 return target.
sync();
868 auto update = [=](
typename concurrency::streams::char_traits<CharType>::int_type ch)
mutable
870 if (ch == concurrency::streams::char_traits<CharType>::eof())
return false;
871 if (ch ==
'\n')
return false;
874 _locals->saw_CR =
true;
878 _locals->outbuf[_locals->write_pos] =
static_cast<CharType
>(ch);
879 _locals->write_pos += 1;
881 if (_locals->is_full())
891 auto update_after_cr = [=] (
typename concurrency::streams::char_traits<CharType>::int_type ch)
mutable ->
pplx::task<bool>
893 if (ch == concurrency::streams::char_traits<CharType>::eof())
return pplx::task_from_result(
false);
896 return buffer.bumpc().then([](
900 concurrency::streams::char_traits<CharType>::int_type) {
return false; });
902 return pplx::task_from_result(
false);
907 while ( buffer.in_avail() > 0 )
909 #ifndef _WIN32 // Required by GCC, because concurrency::streams::char_traits<CharType> is a dependent scope
912 concurrency::streams::char_traits<CharType>::int_type ch;
919 return pplx::task_from_result(
false);
922 ch = buffer.sbumpc();
929 return pplx::task_from_result(
false);
935 return buffer.getc().then(update_after_cr);
937 return buffer.bumpc().then(update);
940 return loop.then([=](
bool)
mutable
942 return flush().then([=] {
return _locals->total; });
954 if ( !_verify_and_return_task(
"stream not set up for output of data", result) )
return result;
956 return pplx::task_from_exception<size_t>(std::make_exception_ptr(std::runtime_error(
"source buffer not set up for input of data")));
958 auto l_buffer = helper()->m_buffer;
959 auto l_buf_size = this->buf_size;
960 std::shared_ptr<_read_helper> l_locals = std::make_shared<_read_helper>();
962 auto copy_to_target = [l_locals, target, l_buffer, l_buf_size]()
mutable ->
pplx::task<bool>
969 return l_buffer.getn(l_locals->outbuf, l_buf_size).then([=](
size_t rd)
mutable ->
pplx::task<bool>
972 return pplx::task_from_result(
false);
975 return target.putn_nocopy(l_locals->outbuf, rd).then([target, l_locals, rd](
size_t wr)
mutable ->
pplx::task<bool>
977 l_locals->total += wr;
981 throw std::runtime_error(
"failed to write all bytes");
983 return target.sync().then([]() {
return true; });
988 auto loop = pplx::details::do_while(copy_to_target);
990 return loop.then([=](
bool)
mutable ->
size_t
992 return l_locals->total;
1003 _verify_and_throw(details::_in_stream_msg);
1004 return helper()->m_buffer.seekpos(pos, std::ios_base::in);
1013 pos_type
seek(off_type off, std::ios_base::seekdir way)
const
1015 _verify_and_throw(details::_in_stream_msg);
1016 return helper()->m_buffer.seekoff(off, way, std::ios_base::in);
1025 _verify_and_throw(details::_in_stream_msg);
1026 return helper()->m_buffer.getpos(std::ios_base::in);
1038 bool is_valid()
const {
return (m_helper !=
nullptr) && ((bool)m_helper->m_buffer); }
1056 return helper()->m_buffer;
1070 template<
typename T>
1074 if ( !_verify_and_return_task(details::_in_stream_msg, result) )
return result;
1080 template<
typename T>
1081 bool _verify_and_return_task(
const char *msg,
pplx::task<T> &tsk)
const
1083 auto buffer = helper()->m_buffer;
1084 if ( !(buffer.exception() ==
nullptr) )
1086 tsk = pplx::task_from_exception<T>(buffer.exception());
1089 if ( !buffer.can_read() )
1091 tsk = pplx::task_from_exception<T>(std::make_exception_ptr(std::runtime_error(msg)));
1097 void _verify_and_throw(
const char *msg)
const
1099 auto buffer = helper()->m_buffer;
1100 if ( !(buffer.exception() ==
nullptr) )
1101 std::rethrow_exception(buffer.exception());
1102 if ( !buffer.can_read() )
1103 throw std::runtime_error(msg);
1106 std::shared_ptr<details::basic_istream_helper<CharType>> helper()
const
1109 throw std::logic_error(
"uninitialized stream object");
1113 static const size_t buf_size = 16*1024;
1118 CharType outbuf[buf_size];
1122 bool is_full()
const
1124 return write_pos == buf_size;
1127 _read_helper() : total(0), write_pos(0), saw_CR(false)
1132 std::shared_ptr<details::basic_istream_helper<CharType>> m_helper;
1135 typedef basic_ostream<uint8_t> ostream;
1136 typedef basic_istream<uint8_t> istream;
1138 typedef basic_ostream<utf16char> wostream;
1139 typedef basic_istream<utf16char> wistream;
1141 template<
typename CharType>
1142 pplx::task<void> concurrency::streams::_type_parser_base<CharType>::_skip_whitespace(streams::streambuf<CharType> buffer)
1144 int_type req_async = concurrency::streams::char_traits<CharType>::requires_async();
1146 auto update = [=] (int_type ch)
mutable
1150 if (buffer.sbumpc() == req_async)
1154 buffer.nextc().wait();
1164 while (buffer.in_avail() > 0)
1166 int_type ch = buffer.sgetc();
1168 if (ch == req_async)
1173 return pplx::task_from_result(
false);
1176 return buffer.getc().then(update);
1185 template<
typename CharType>
1186 template<
typename StateType,
typename ReturnType,
typename AcceptFunctor,
typename ExtractFunctor>
1188 concurrency::streams::streambuf<CharType> buffer,
1189 AcceptFunctor accept_character,
1190 ExtractFunctor extract)
1192 std::shared_ptr<StateType> state = std::make_shared<StateType>();
1196 int_type ch = op.
get();
1197 if (ch == concurrency::streams::char_traits<CharType>::eof())
return pplx::task_from_result(
false);
1198 bool accptd = accept_character(state, ch);
1200 return pplx::task_from_result(
false);
1202 concurrency::streams::streambuf<CharType> buf = buffer;
1203 return buf.bumpc().then([](int_type) {
return true; });
1208 concurrency::streams::streambuf<CharType> buf = buffer;
1213 auto get_op = buf.getc();
1214 while (get_op.is_done())
1216 auto condition = update(get_op);
1217 if (!condition.is_done() || !condition.get())
1220 get_op = buf.getc();
1223 return get_op.then(update);
1237 return pplx::details::do_while(peek_char).then(finish);
1241 template<
typename CharType>
1244 typedef typename _type_parser_base<CharType>::int_type int_type;
1248 return concurrency::streams::_type_parser_base<CharType>::template _parse_input<std::basic_string<CharType>, std::string>(buffer, _accept_char, _extract_result);
1252 static bool _accept_char(std::shared_ptr<std::basic_string<CharType>> state, int_type ch)
1254 if ( ch == concurrency::streams::char_traits<CharType>::eof() || isspace(ch))
return false;
1255 state->push_back(CharType(ch));
1260 return pplx::task_from_result(*state);
1264 template<
typename CharType>
1268 typedef typename _type_parser_base<CharType>::int_type int_type;
1276 _int64_state() : result(0), correct(
false), minus(0) {}
1283 static bool _accept_char(std::shared_ptr<_int64_state> state, int_type ch)
1285 if ( ch == concurrency::streams::char_traits<CharType>::eof())
return false;
1286 if ( state->minus == 0 )
1289 if ( !::isdigit(ch) && ch != int_type(
'+') && ch != int_type(
'-') )
1294 if ( !::isdigit(ch) )
return false;
1298 state->correct =
true;
1300 if ( ch == int_type(
'+') )
1304 else if ( ch == int_type(
'-') )
1310 if (state->minus == 0) state->minus = 1;
1313 bool positive = state->result >= 0;
1315 state->result *= 10;
1316 state->result += int64_t(ch-int_type(
'0'));
1318 if ( (state->result >= 0) != positive )
1320 state->correct =
false;
1329 if (!state->correct)
1330 throw std::range_error(
"integer value is too large to fit in 64 bits");
1332 int64_t result = (state->minus == 2) ? -state->result : state->result;
1333 return pplx::task_from_result<int64_t>(result);
1337 template <
typename FloatingPo
int>
1340 _double_state() : result(0), minus(0), after_comma(0), exponent(
false), exponent_number(0), exponent_minus(0), complete(
false), p_exception_string() {}
1342 FloatingPoint result;
1346 int exponent_number;
1347 char exponent_minus;
1349 std::string p_exception_string;
1352 template <
typename FloatingPo
int,
typename int_type>
1353 static std::string create_exception_message(int_type ch,
bool exponent)
1355 std::ostringstream os;
1356 os <<
"Invalid character '" << char(ch) <<
"'" << (exponent ?
" in exponent" :
"");
1360 template <
typename FloatingPo
int,
typename int_type>
1361 static bool _accept_char(std::shared_ptr<_double_state<FloatingPoint>> state, int_type ch)
1363 if ( state->minus == 0 )
1365 if ( !::isdigit(ch) && ch != int_type(
'.') && ch != int_type(
'+') && ch != int_type(
'-') )
1367 if (!state->complete)
1368 state->p_exception_string = create_exception_message<FloatingPoint, int_type>(ch,
false);
1374 if (!state->exponent && !::isdigit(ch) && ch != int_type(
'.') && ch != int_type(
'E') && ch != int_type(
'e'))
1376 if (!state->complete)
1377 state->p_exception_string = create_exception_message<FloatingPoint, int_type>(ch,
false);
1381 if (state->exponent && !::isdigit(ch) && ch != int_type(
'+') && ch != int_type(
'-'))
1383 if (!state->complete)
1384 state->p_exception_string = create_exception_message<FloatingPoint, int_type>(ch,
true);
1391 case int_type(
'+') :
1392 state->complete = false;
1393 if (state->exponent)
1395 if (state->exponent_minus != 0)
1397 state->p_exception_string =
"The exponent sign already set";
1400 state->exponent_minus = 1;
1407 case int_type(
'-') :
1408 state->complete = false;
1409 if (state->exponent)
1411 if (state->exponent_minus != 0)
1413 state->p_exception_string =
"The exponent sign already set";
1417 state->exponent_minus = 2;
1424 case int_type(
'.') :
1425 state->complete = false;
1426 if (state->after_comma > 0)
1429 state->after_comma = 1;
1431 case int_type(
'E') : case int_type(
'e') :
1432 state->complete = false;
1433 if (state->exponent)
1435 state->exponent_number = 0;
1436 state->exponent =
true;
1439 state->complete =
true;
1440 if (!state->exponent)
1442 if (state->minus == 0)
1445 state->result *= 10;
1446 state->result += int64_t(ch-int_type(
'0'));
1448 if (state->after_comma > 0)
1449 state->after_comma++;
1453 if (state->exponent_minus == 0) state->exponent_minus = 1;
1454 state->exponent_number *= 10;
1455 state->exponent_number += int64_t(ch-int_type(
'0'));
1461 template <
typename FloatingPo
int>
1464 if (state->p_exception_string.length() > 0)
1465 throw std::runtime_error(state->p_exception_string.c_str());
1467 if (!state->complete && state->exponent)
1468 throw std::runtime_error(
"Incomplete exponent");
1470 FloatingPoint result =
static_cast<FloatingPoint
>((state->minus == 2) ? -state->result : state->result);
1471 if (state->exponent_minus == 2)
1472 state->exponent_number = 0 - state->exponent_number;
1474 if (state->after_comma > 0)
1475 state->exponent_number -= state->after_comma-1;
1477 if (state->exponent_number >= 0)
1479 result *= pow(FloatingPoint(10.0), state->exponent_number);
1481 #pragma push_macro ("max")
1484 if (result > std::numeric_limits<FloatingPoint>::max() || result < -std::numeric_limits<FloatingPoint>::max())
1485 throw std::overflow_error(
"The value is too big");
1486 #pragma pop_macro ("max")
1490 bool is_zero = (result == 0);
1492 result /= pow(FloatingPoint(10.0), -state->exponent_number);
1495 result > -std::numeric_limits<FloatingPoint>::denorm_min() &&
1496 result < std::numeric_limits<FloatingPoint>::denorm_min())
1497 throw std::underflow_error(
"The value is too small");
1500 return pplx::task_from_result<FloatingPoint>(result);
1503 template<
typename CharType>
1507 typedef typename _type_parser_base<CharType>::int_type int_type;
1515 template<
typename CharType>
1519 typedef typename _type_parser_base<CharType>::int_type int_type;
1528 template<
typename CharType>
1532 typedef typename _type_parser_base<CharType>::int_type int_type;
1539 struct _uint64_state
1541 _uint64_state() : result(0), correct(
false) {}
1546 static bool _accept_char(std::shared_ptr<_uint64_state> state, int_type ch)
1548 if ( !::isdigit(ch) )
return false;
1551 state->correct =
true;
1554 state->result *= 10;
1555 state->result += uint64_t(ch-int_type(
'0'));
1562 if (!state->correct)
1563 throw std::range_error(
"integer value is too large to fit in 64 bits");
1564 return pplx::task_from_result(state->result);
1568 template<
typename CharType>
1572 typedef typename _type_parser_base<CharType>::int_type int_type;
1580 _bool_state() : state(0) { }
1585 static bool _accept_char(std::shared_ptr<_bool_state> state, int_type ch)
1587 switch (state->state)
1590 if ( ch == int_type(
't') ) state->state = 1;
1591 else if ( ch == int_type(
'f') ) state->state = 4;
1592 else if ( ch == int_type(
'1') ) state->state = 8;
1593 else if ( ch == int_type(
'0') ) state->state = 9;
1597 if ( ch == int_type(
'r') ) state->state = 2;
1601 if ( ch == int_type(
'u') ) state->state = 3;
1605 if ( ch == int_type(
'e') ) state->state = 8;
1609 if ( ch == int_type(
'a') ) state->state = 5;
1613 if ( ch == int_type(
'l') ) state->state = 6;
1617 if ( ch == int_type(
's') ) state->state = 7;
1621 if ( ch == int_type(
'e') ) state->state = 9;
1630 static pplx::task<bool> _extract_result(std::shared_ptr<_bool_state> state)
1632 bool correct = (state->state == 8 || state->state == 9);
1635 std::runtime_error exc(
"cannot parse as Boolean value");
1638 return pplx::task_from_result(state->state == 8);
1642 template<
typename CharType>
1645 typedef typename concurrency::streams::streambuf<CharType>::int_type int_type;
1659 concurrency::streams::streambuf<CharType> buf = buffer;
1660 return buf.
bumpc().then(
1661 [=](
pplx::task<
typename concurrency::streams::streambuf<CharType>::int_type> op) ->
signed char
1663 int_type val = op.
get();
1664 if (val == concurrency::streams::char_traits<CharType>::eof())
1665 throw std::runtime_error(
"reached end-of-stream while constructing a value");
1666 return static_cast<signed char>(val);
1671 template<
typename CharType>
1674 typedef typename concurrency::streams::streambuf<CharType>::int_type int_type;
1688 concurrency::streams::streambuf<CharType> buf = buffer;
1689 return buf.
bumpc().then(
1690 [=](
pplx::task<
typename concurrency::streams::streambuf<CharType>::int_type> op) ->
unsigned char
1692 int_type val = op.
get();
1693 if (val == concurrency::streams::char_traits<CharType>::eof())
1694 throw std::runtime_error(
"reached end-of-stream while constructing a value");
1695 return static_cast<unsigned char>(val);
1700 template<
typename CharType>
1703 typedef typename concurrency::streams::streambuf<CharType>::int_type int_type;
1711 return _get_char(buffer);
1717 concurrency::streams::streambuf<CharType> buf = buffer;
1718 return buf.
bumpc().then(
1719 [=](
pplx::task<
typename concurrency::streams::streambuf<CharType>::int_type> op) ->
char
1721 int_type val = op.
get();
1722 if (val == concurrency::streams::char_traits<CharType>::eof())
1723 throw std::runtime_error(
"reached end-of-stream while constructing a value");
1736 return _parse_input<std::basic_string<char>,std::basic_string<wchar_t>>(buffer, _accept_char, _extract_result);
1740 static bool _accept_char(
const std::shared_ptr<std::basic_string<char>> &state, int_type ch)
1742 if ( ch == concurrency::streams::char_traits<char>::eof() || isspace(ch))
return false;
1743 state->push_back(
char(ch));
1753 class type_parser<signed char,std::basic_string<wchar_t>> :
public _type_parser_base<signed char>
1758 return _parse_input<std::basic_string<char>,std::basic_string<wchar_t>>(buffer, _accept_char, _extract_result);
1762 static bool _accept_char(
const std::shared_ptr<std::basic_string<char>> &state, int_type ch)
1764 if ( ch == concurrency::streams::char_traits<char>::eof() || isspace(ch))
return false;
1765 state->push_back(
char(ch));
1775 class type_parser<unsigned char,std::basic_string<wchar_t>> :
public _type_parser_base<unsigned char>
1780 return _parse_input<std::basic_string<char>,std::basic_string<wchar_t>>(buffer, _accept_char, _extract_result);
1784 static bool _accept_char(
const std::shared_ptr<std::basic_string<char>> &state, int_type ch)
1786 if ( ch == concurrency::streams::char_traits<char>::eof() || isspace(ch))
return false;
1787 state->push_back(
char(ch));
concurrency::streams::streambuf< CharType > streambuf() const
Get the underlying stream buffer.
Definition: streams.h:398
Class used to handle asychronous parsing for basic_istream::extract. To support new types create a ne...
Definition: streams.h:513
_ASYNCRTIMP std::string __cdecl utf16_to_utf8(const utf16string &w)
Converts a UTF-16 string to a UTF-8 string.
pplx::task< int_type > write(CharType ch) const
Put a single character into the stream.
Definition: streams.h:169
pplx::task< size_t > read(streams::streambuf< CharType > target, size_t count) const
Reads up to count characters and place into the provided buffer.
Definition: streams.h:688
The pplx namespace provides classes and functions that give you access to the Concurrency Runtime...
Definition: pplx.h:81
task_status wait() const
Waits for this task to reach a terminal state. It is possible for wait to execute the task inline...
Definition: pplxtasks.h:3512
bool is_open() const
Test whether the stream is open for writing.
Definition: streams.h:1049
basic_ostream & operator=(const basic_ostream &other)
Assignment operator
Definition: streams.h:132
pos_type seek(pos_type pos) const
Seeks to the specified write position.
Definition: streams.h:343
Reference-counted stream buffer.
Definition: astreambuf.h:804
virtual void release(_Out_writes_(count) _CharType *ptr, _In_ size_t count)
Releases a block of data acquired using ::acquire method. This frees the stream buffer to de-allocate...
Definition: astreambuf.h:1030
pplx::task< size_t > write(streams::streambuf< CharType > source, size_t count) const
Write a number of characters from a given stream buffer into the stream.
Definition: streams.h:207
Base interface for all asynchronous output streams.
Definition: astreambuf.h:792
pplx::task< size_t > read_to_end(streams::streambuf< CharType > target) const
Read until reaching the end of the stream.
Definition: streams.h:951
_ASYNCRTIMP utf16string __cdecl utf8_to_utf16(const std::string &s)
Converts a UTF-8 string to a UTF-16
basic_ostream()
Default constructor
Definition: streams.h:119
pplx::task< void > close(std::exception_ptr eptr) const
Close the stream with exception, preventing further read operations.
Definition: streams.h:626
void get() const
Returns the result this task produced. If the task is not in a terminal state, a call to get will wai...
Definition: pplxtasks.h:4440
pplx::task< size_t > print(const std::basic_string< CharType > &str) const
Write the specified string to the output stream.
Definition: streams.h:278
basic_istream & operator=(const basic_istream &other)
Assignment operator
Definition: streams.h:606
pplx::task< void > close() const
Close the stream, preventing further write operations.
Definition: streams.h:147
pplx::task< void > close() const
Close the stream, preventing further read operations.
Definition: streams.h:615
virtual pplx::task< size_t > getn(_Out_writes_(count) _CharType *ptr, _In_ size_t count)
Reads up to a given number of characters from the stream.
Definition: astreambuf.h:1121
virtual pplx::task< int_type > bumpc()
Reads a single character from the stream and advances the read position.
Definition: astreambuf.h:1063
Definition: streams.h:1338
pplx::task< size_t > read_to_delim(streams::streambuf< CharType > target, int_type delim) const
Read characters until a delimiter or EOF is found, and place them into the target. Proceed past the delimiter, but don't include it in the target buffer.
Definition: streams.h:772
pos_type seek(off_type off, std::ios_base::seekdir way) const
Seeks to the specified write position.
Definition: streams.h:355
pplx::task< void > close(std::exception_ptr eptr) const
Close the stream with exception, preventing further write operations.
Definition: streams.h:158
pplx::task< T > extract() const
Read a value of type T from the stream.
Definition: streams.h:1071
The Parallel Patterns Library (PPL) task class. A task object represents work that can be executed as...
Definition: pplxtasks.h:176
Definition: streams.h:449
bool is_valid() const
Test whether the stream has been initialized with a valid stream buffer.
Definition: streams.h:381
bool is_open() const
Test whether the stream is open for writing.
Definition: streams.h:392
pplx::task< size_t > print(const T &val) const
Write a value of type T to the output stream.
Definition: streams.h:302
task_status wait() const
Waits for this task to reach a terminal state. It is possible for wait to execute the task inline...
Definition: pplxtasks.h:4426
pplx::task< int_type > read() const
Get the next character and return it as an int_type. Advance the read position.
Definition: streams.h:646
pplx::task< size_t > print_line(const T &val) const
Write a value of type T to the output stream and append a newline character.
Definition: streams.h:319
bool can_seek() const
can_seek is used to determine whether the stream supports seeking.
Definition: streams.h:375
_ReturnType get() const
Returns the result this task produced. If the task is not in a terminal state, a call to get will wai...
Definition: pplxtasks.h:3534
Base interface for all asynchronous input streams.
Definition: astreambuf.h:791
The Parallel Patterns Library (PPL) task class. A task object represents work that can be executed as...
Definition: pplxtasks.h:4173
concurrency::streams::streambuf< CharType > streambuf() const
Get the underlying stream buffer.
Definition: streams.h:1054
pplx::task< int_type > peek() const
Get the next character and return it as an int_type. Do not advance the read position.
Definition: streams.h:758
pos_type tell() const
Get the current write position, i.e. the offset from the beginning of the stream. ...
Definition: streams.h:1023
virtual void commit(size_t count)
Submits a block already allocated by the stream buffer.
Definition: astreambuf.h:999
pplx::task< void > flush() const
Flush any buffered output data.
Definition: streams.h:331
basic_istream(streams::streambuf< CharType > buffer)
Constructor
Definition: streams.h:590
pplx::task< size_t > read_line(streams::streambuf< CharType > target) const
Read until reaching a newline character. The newline is not included in the target.
Definition: streams.h:844
Definition: astreambuf.h:37
basic_ostream(streams::streambuf< CharType > buffer)
Constructor
Definition: streams.h:138
basic_ostream(const basic_ostream &other)
Copy constructor
Definition: streams.h:125
bool is_eof() const
Tests whether last read cause the stream reach EOF.
Definition: streams.h:637
Definition: streams.h:490
virtual pplx::task< void > sync()
For output streams, flush any internally buffered data to the underlying medium.
Definition: astreambuf.h:1180
bool can_seek() const
can_seek is used to determine whether the stream supports seeking.
Definition: streams.h:1033
basic_istream()
Default constructor
Definition: streams.h:581
basic_istream(const basic_istream &other)
Copy constructor
Definition: streams.h:599
virtual _CharType * alloc(size_t count)
Allocates a contiguous memory block and returns it.
Definition: astreambuf.h:990
bool is_valid() const
Test whether the stream has been initialized with a valid stream buffer.
Definition: streams.h:1038
pos_type tell() const
Get the current write position, i.e. the offset from the beginning of the stream. ...
Definition: streams.h:365
virtual pplx::task< size_t > putn_nocopy(const _CharType *ptr, size_t count)
Writes a number of characters to the stream. Note: callers must make sure the data to be written is v...
Definition: astreambuf.h:1054
virtual bool acquire(_Out_ _CharType *&ptr, _Out_ size_t &count)
Gets a pointer to the next already allocated contiguous block of data.
Definition: astreambuf.h:1017
pos_type seek(off_type off, std::ios_base::seekdir way) const
Seeks to the specified write position.
Definition: streams.h:1013
Extending the standard char_traits type with one that adds values and types that are unique to "C++ R...
Definition: astreambuf.h:50
virtual bool can_read() const
can_read is used to determine whether a stream buffer will support read operations (get)...
Definition: astreambuf.h:889
virtual bool can_write() const
can_write is used to determine whether a stream buffer will support write operations (put)...
Definition: astreambuf.h:894
pos_type seek(pos_type pos) const
Seeks to the specified write position.
Definition: streams.h:1001