33 #include "pplx/pplxtasks.h"
34 #include "cpprest/astreambuf.h"
35 #include "cpprest/streams.h"
52 template<
typename _CollectionType>
56 typedef typename _CollectionType::value_type _CharType;
57 typedef typename basic_streambuf<_CharType>::traits traits;
58 typedef typename basic_streambuf<_CharType>::int_type int_type;
59 typedef typename basic_streambuf<_CharType>::pos_type pos_type;
60 typedef typename basic_streambuf<_CharType>::off_type off_type;
97 virtual utility::size64_t
size()
const
99 return utility::size64_t(m_data.size());
107 virtual size_t buffer_size(std::ios_base::openmode = std::ios_base::in)
const
132 _ASSERTE(m_current_position <= m_data.size());
136 return (
size_t)(writeend - readhead);
141 return pplx::task_from_result(
true);
146 int_type retVal = (this->write(&ch, 1) == 1) ? static_cast<int_type>(ch) : traits::eof();
147 return pplx::task_from_result<int_type>(retVal);
152 return pplx::task_from_result<size_t>(this->write(ptr, count));
165 resize_for_write(m_current_position+count);
168 return (_CharType*)&m_data[m_current_position];
178 update_current_position(m_current_position+actual);
194 virtual bool acquire(_Out_ _CharType*& ptr, _Out_
size_t& count)
199 if (!this->
can_read())
return false;
205 ptr = (_CharType*)&m_data[m_current_position];
222 virtual void release(_Out_writes_opt_ (count) _CharType *ptr, _In_
size_t count)
225 update_current_position(m_current_position + count);
228 virtual pplx::task<size_t> _getn(_Out_writes_ (count) _CharType *ptr, _In_
size_t count)
230 return pplx::task_from_result(this->read(ptr, count));
233 size_t _sgetn(_Out_writes_ (count) _CharType *ptr, _In_
size_t count)
235 return this->read(ptr, count);
238 virtual size_t _scopy(_Out_writes_ (count) _CharType *ptr, _In_
size_t count)
240 return this->read(ptr, count,
false);
245 return pplx::task_from_result(this->read_byte(
true));
248 virtual int_type _sbumpc()
250 return this->read_byte(
true);
255 return pplx::task_from_result(this->read_byte(
false));
260 return this->read_byte(
false);
265 this->read_byte(
true);
266 return pplx::task_from_result(this->read_byte(
false));
271 auto pos =
seekoff(-1, std::ios_base::cur, std::ios_base::in);
272 if ( pos == (pos_type)traits::eof())
273 return pplx::task_from_result(traits::eof());
284 virtual pos_type
getpos(std::ios_base::openmode mode)
const
286 if ( ((mode & std::ios_base::in) && !this->
can_read()) ||
287 ((mode & std::ios_base::out) && !this->
can_write()))
288 return static_cast<pos_type
>(traits::eof());
290 return static_cast<pos_type
>(m_current_position);
300 virtual pos_type
seekpos(pos_type position, std::ios_base::openmode mode)
309 pos_type end(m_data.size());
313 auto pos =
static_cast<size_t>(position);
316 if ((mode & std::ios_base::in) && this->
can_read())
321 update_current_position(pos);
322 return static_cast<pos_type
>(m_current_position);
327 if ((mode & std::ios_base::out) && this->
can_write())
330 resize_for_write(pos);
335 update_current_position(pos);
337 return static_cast<pos_type
>(m_current_position);
341 return static_cast<pos_type
>(traits::eof());
353 virtual pos_type
seekoff(off_type offset, std::ios_base::seekdir way, std::ios_base::openmode mode)
356 pos_type cur =
static_cast<pos_type
>(m_current_position);
357 pos_type end =
static_cast<pos_type
>(m_data.size());
361 case std::ios_base::beg:
362 return seekpos(beg + offset, mode);
364 case std::ios_base::cur:
365 return seekpos(cur + offset, mode);
367 case std::ios_base::end:
368 return seekpos(end + offset, mode);
371 return static_cast<pos_type
>(traits::eof());
383 m_current_position(0)
391 basic_container_buffer(_CollectionType data, std::ios_base::openmode mode)
392 : streambuf_state_manager<typename _CollectionType::value_type>(mode),
393 m_data(std::move(data)),
394 m_current_position((mode & std::ios_base::in) ? 0 : m_data.
size())
399 static void validate_mode(std::ios_base::openmode mode)
402 if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
403 throw std::invalid_argument(
"this combination of modes on container stream not supported");
409 bool can_satisfy(
size_t)
420 int_type read_byte(
bool advance =
true)
423 auto read_size = this->read(&value, 1, advance);
424 return read_size == 1 ?
static_cast<int_type
>(value) : traits::eof();
432 size_t read(_Out_writes_ (count) _CharType *ptr, _In_
size_t count,
bool advance =
true)
434 if (!can_satisfy(count))
440 size_t newPos = m_current_position + read_size;
442 auto readBegin = begin(m_data) + m_current_position;
443 auto readEnd = begin(m_data) + newPos;
447 std::copy(readBegin, readEnd, stdext::checked_array_iterator<_CharType *>(ptr, count));
449 std::copy(readBegin, readEnd, ptr);
454 update_current_position(newPos);
457 return (
size_t) read_size;
463 size_t write(
const _CharType *ptr,
size_t count)
465 if (!this->
can_write() || (count == 0))
return 0;
467 auto newSize = m_current_position + count;
470 resize_for_write(newSize);
473 std::copy(ptr, ptr + count, begin(m_data) + m_current_position);
476 update_current_position(newSize);
484 void resize_for_write(
size_t newPos)
487 if (newPos > m_data.size())
489 m_data.resize(newPos);
496 void update_current_position(
size_t newPos)
499 m_current_position = newPos;
500 _ASSERTE(m_current_position <= m_data.size());
504 _CollectionType m_data;
507 size_t m_current_position;
522 template<
typename _CollectionType>
523 class container_buffer :
public streambuf<typename _CollectionType::value_type>
526 typedef typename _CollectionType::value_type char_type;
534 :
streambuf<typename _CollectionType::value_type>(
535 std::shared_ptr<details::basic_container_buffer<_CollectionType>>(new streams::details::basic_container_buffer<_CollectionType>(std::move(data), mode)))
544 :
streambuf<typename _CollectionType::value_type>(
545 std::shared_ptr<details::basic_container_buffer<_CollectionType>>(new details::basic_container_buffer<_CollectionType>(mode)))
549 _CollectionType& collection()
const
562 template<
typename _CollectionType>
567 typedef typename _CollectionType::value_type char_type;
575 static concurrency::streams::basic_istream<char_type>
open_istream(_CollectionType data)
577 return concurrency::streams::basic_istream<char_type>(buffer_type(std::move(data), std::ios_base::in));
586 return concurrency::streams::basic_ostream<char_type>(buffer_type(std::ios_base::out));
613 template<
typename _CollectionType>
614 static concurrency::streams::istream
open_istream(_CollectionType data)
624 template<
typename _CollectionType>
container_buffer(std::ios_base::openmode mode=std::ios_base::out)
Creates a container_buffer starting from an empty collection.
Definition: containerstream.h:543
virtual pplx::task< int_type > getc()
Reads a single character from the stream without advancing the read position.
Definition: astreambuf.h:526
virtual bool is_open() const
Checks if the stream buffer is open.
Definition: astreambuf.h:390
Reference-counted stream buffer.
Definition: astreambuf.h:804
static concurrency::streams::istream open_istream(_CollectionType data)
Creates a single byte character input stream given an STL container.
Definition: containerstream.h:614
static concurrency::streams::basic_ostream< char_type > open_ostream()
Creates an output stream using an STL container as the storage.
Definition: containerstream.h:584
virtual utility::size64_t size() const
Gets the size of the stream, if known. Calls to has_size will determine whether the result of size ca...
Definition: containerstream.h:97
virtual size_t buffer_size(std::ios_base::openmode=std::ios_base::in) const
Get the stream buffer size, if one has been set.
Definition: containerstream.h:107
A static class to allow users to create input and out streams based off STL collections. The sole purpose of this class to avoid users from having to know anything about stream buffers.
Definition: containerstream.h:563
virtual bool can_read() const
can_read is used to determine whether a stream buffer will support read operations (get)...
Definition: astreambuf.h:373
virtual void set_buffer_size(size_t, std::ios_base::openmode=std::ios_base::in)
Sets the stream buffer implementation to buffer or not buffer.
Definition: containerstream.h:118
virtual pplx::task< void > _close_read()
The real read head close operation, implementation should override it if there is any resource to be ...
Definition: astreambuf.h:711
The basic_container_buffer class serves as a memory-based steam buffer that supports writing or readi...
Definition: containerstream.h:41
virtual pos_type seekpos(pos_type position, std::ios_base::openmode mode)
Seeks to the given position.
Definition: containerstream.h:300
virtual bool acquire(_Out_ _CharType *&ptr, _Out_ size_t &count)
Gets a pointer to the next already allocated contiguous block of data.
Definition: containerstream.h:194
virtual pplx::task< void > _close_write()
The real write head close operation, implementation should override it if there is any resource to be...
Definition: astreambuf.h:720
static concurrency::streams::ostream open_ostream()
Creates a single byte character output stream using an STL container as storage.
Definition: containerstream.h:625
virtual bool can_write() const
can_write is used to determine whether a stream buffer will support write operations (put)...
Definition: astreambuf.h:381
_CharType * _alloc(size_t count)
Allocates a contiguous memory block and returns it.
Definition: containerstream.h:160
virtual pos_type seekoff(off_type offset, std::ios_base::seekdir way, std::ios_base::openmode mode)
Seeks to a position given by a relative offset.
Definition: containerstream.h:353
Definition: astreambuf.h:362
The Parallel Patterns Library (PPL) task class. A task object represents work that can be executed as...
Definition: pplxtasks.h:176
virtual size_t in_avail() const
For any input stream, in_avail returns the number of characters that are immediately available to be ...
Definition: containerstream.h:128
virtual pos_type getpos(std::ios_base::openmode mode) const
Gets the current read or write position in the stream.
Definition: containerstream.h:284
The bytestream is a static class that allows an input stream to be constructed from any STL container...
Definition: containerstream.h:603
container_buffer(_CollectionType data, std::ios_base::openmode mode=std::ios_base::in)
Creates a container_buffer given a collection, copying its data into the buffer.
Definition: containerstream.h:533
Definition: astreambuf.h:37
_CollectionType & collection()
Returns the underlying data container
Definition: containerstream.h:65
virtual bool can_seek() const
can_seek is used to determine whether a stream buffer supports seeking.
Definition: containerstream.h:86
virtual void release(_Out_writes_opt_(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: containerstream.h:222
void _commit(size_t actual)
Submits a block already allocated by the stream buffer.
Definition: containerstream.h:175
static concurrency::streams::basic_istream< char_type > open_istream(_CollectionType data)
Creates an input stream given an STL container.
Definition: containerstream.h:575
container_stream< std::basic_string< char > > stringstream
The stringstream allows an input stream to be constructed from std::string or std::wstring For output...
Definition: containerstream.h:594
The basic_container_buffer class serves as a memory-based steam buffer that supports writing or readi...
Definition: containerstream.h:53
virtual bool has_size() const
has_size is used to determine whether a stream buffer supports size().
Definition: containerstream.h:91
virtual ~basic_container_buffer()
Destructor
Definition: containerstream.h:73