1 /***
2 * ==++==
3 *
4 * Copyright (c) Microsoft Corporation. All rights reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * ==--==
17 * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
18 *
19 * Adapter classes for async and STD stream buffers, used to connect std-based and async-based APIs.
20 *
21 * For the latest on this and related APIs, please see http://casablanca.codeplex.com.
22 *
23 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
24 ****/
25 #pragma once
26
27 #include "pplx/pplxtasks.h"
28 #include "cpprest/astreambuf.h"
29 #include "cpprest/streams.h"
30
31 #if defined(_WIN32)
32 #pragma warning(push)
33 #pragma warning(disable : 4250)
34 #endif
35
37
40
41 namespace details {
42
49 template<typename _CharType>
51 {
52 typedef concurrency::streams::char_traits<_CharType> traits;
53 typedef typename traits::int_type int_type;
54 typedef typename traits::pos_type pos_type;
55 typedef typename traits::off_type off_type;
61 {
62 }
63
64 public:
69 {
72 }
73
74 private:
75 //
76 // The functions overridden below here are documented elsewhere.
77 // See astreambuf.h for further information.
78 //
79 virtual bool can_seek()
const {
return this->
is_open(); }
80 virtual bool has_size() const { return false; }
81
82 virtual size_t in_avail() const { return (size_t)m_buffer->in_avail(); }
83
84 virtual size_t buffer_size(std::ios_base::openmode) const { return 0; }
85 virtual void set_buffer_size(size_t, std::ios_base::openmode) { return; }
86
87 virtual pplx::task<bool> _sync() {
return pplx::task_from_result(m_buffer->pubsync() == 0); }
88
89 virtual pplx::task<int_type> _putc(_CharType ch) {
return pplx::task_from_result(m_buffer->sputc(ch)); }
90 virtual pplx::task<size_t> _putn(
const _CharType *ptr,
size_t size) {
return pplx::task_from_result((
size_t)m_buffer->sputn(ptr, size)); }
91
92 size_t _sgetn(_Out_writes_ (size) _CharType *ptr, _In_ size_t size) const { return m_buffer->sgetn(ptr, size); }
93 virtual size_t _scopy(_Out_writes_ (size) _CharType *, _In_ size_t size) { (void)(size); return (size_t)-1; }
94
95 virtual pplx::task<size_t> _getn(_Out_writes_ (size) _CharType *ptr, _In_
size_t size) {
return pplx::task_from_result((
size_t)m_buffer->sgetn(ptr, size)); }
96
97 virtual int_type _sbumpc() { return m_buffer->sbumpc(); }
98 virtual int_type _sgetc() { return m_buffer->sgetc(); }
99
100 virtual pplx::task<int_type> _bumpc() {
return pplx::task_from_result<int_type>(m_buffer->sbumpc()); }
101 virtual pplx::task<int_type> _getc() {
return pplx::task_from_result<int_type>(m_buffer->sgetc()); }
102 virtual pplx::task<int_type> _nextc() {
return pplx::task_from_result<int_type>(m_buffer->snextc()); }
103 virtual pplx::task<int_type> _ungetc() {
return pplx::task_from_result<int_type>(m_buffer->sungetc()); }
104
105 virtual pos_type getpos(std::ios_base::openmode mode) const { return m_buffer->pubseekoff(0, std::ios_base::cur, mode); }
106 virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode) { return m_buffer->pubseekpos(pos, mode); }
107 virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode mode) { return m_buffer->pubseekoff(off, dir, mode); }
108
109 virtual _CharType* _alloc(size_t) { return nullptr; }
110 virtual void _commit(size_t) {}
111
112 virtual bool acquire(_CharType*&, size_t&) { return false; }
113 virtual void release(_CharType *, size_t) { }
114
115 template<typename CharType> friend class concurrency::streams::stdio_ostream;
116 template<typename CharType> friend class concurrency::streams::stdio_istream;
117
118 std::basic_streambuf<_CharType>* m_buffer;
119 };
120
121 } // namespace details
122
136 template<typename CharType>
137 class stdio_ostream : public basic_ostream<CharType>
138 {
139 public:
147 template <typename AlterCharType>
149 :
basic_ostream<CharType>(streams::streambuf<AlterCharType>(std::shared_ptr<details::basic_stdio_buffer<AlterCharType>>(new details::basic_stdio_buffer<AlterCharType>(stream.rdbuf(), std::ios_base::out))))
150 {
151 }
152
158
165 };
166
180 template<typename CharType>
181 class stdio_istream : public basic_istream<CharType>
182 {
183 public:
191 template <typename AlterCharType>
193 :
basic_istream<CharType>(streams::streambuf<AlterCharType>(std::shared_ptr<details::basic_stdio_buffer<AlterCharType>>(new details::basic_stdio_buffer<AlterCharType>(stream.rdbuf(), std::ios_base::in))))
194 {
195 }
196
202
209 };
210
211 namespace details {
212
217 template<typename CharType>
219 {
220 public:
221 typedef concurrency::streams::char_traits<CharType> traits;
222 typedef typename traits::int_type int_type;
223 typedef typename traits::pos_type pos_type;
224 typedef typename traits::off_type off_type;
225
227 {
228 }
229 protected:
230
231 //
232 // The following are the functions in std::basic_streambuf that we need to override.
233 //
234
239 {
240 try
241 {
242 return m_buffer.putc(CharType(ch)).get();
243 }
244 catch(...)
245 {
246 return traits::eof();
247 }
248 }
249
254 {
255 try
256 {
257 return m_buffer.getc().get();
258 }
259 catch(...)
260 {
261 return traits::eof();
262 }
263 }
264
269 {
270 try
271 {
272 return m_buffer.bumpc().get();
273 }
274 catch(...)
275 {
276 return traits::eof();
277 }
278 }
279
283 std::streamsize
xsgetn(_Out_writes_ (count) CharType* ptr, _In_ std::streamsize count)
284 {
285 size_t cnt = size_t(count);
286 size_t read_so_far = 0;
287
288 try
289 {
290 while (read_so_far < cnt)
291 {
292 size_t rd = m_buffer.getn(ptr+read_so_far, cnt-read_so_far).get();
293 read_so_far += rd;
294 if ( rd == 0 )
295 break;
296 }
297 return read_so_far;
298 }
299 catch(...)
300 {
301 return 0;
302 }
303 }
304
308 std::streamsize
xsputn(
const CharType* ptr, std::streamsize count)
309 {
310 try
311 {
312 return m_buffer.putn_nocopy(ptr, static_cast<size_t>(count)).get();
313 }
314 catch(...)
315 {
316 return 0;
317 }
318 }
319
323 int sync()
// must be int as per std::basic_streambuf
324 {
325 try
326 {
327 m_buffer.sync().wait();
328 }
329 catch(...)
330 {
331 }
332 return 0;
333 }
334
339 std::ios_base::seekdir dir,
340 std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
341 {
342 try
343 {
344 if ( dir == std::ios_base::cur && offset == 0) // Special case for getting the current position.
345 return m_buffer.getpos(mode);
346 return m_buffer.seekoff(offset,dir,mode);
347 }
348 catch(...)
349 {
350 return (pos_type(-1));
351 }
352 }
353
358 std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out)
359 {
360 try
361 {
362 return m_buffer.seekpos(pos, mode);
363 }
364 catch(...)
365 {
366 return (pos_type(-1));
367 }
368 }
369
370 private:
371 concurrency::streams::streambuf<CharType> m_buffer;
372 };
373
374 } // namespace details
375
382 template<typename CharType>
384 {
385 public:
393 template <typename AlterCharType>
396 m_strbuf(astream.streambuf())
397 {
398 }
399
407 template <typename AlterCharType>
410 m_strbuf(strbuf)
411 {
412 }
413
414 private:
416 };
417
424 template<typename CharType>
426 {
427 public:
435 template <typename AlterCharType>
438 m_strbuf(astream.streambuf())
439 {
440 }
441
449 template <typename AlterCharType>
452 m_strbuf(strbuf)
453 {
454 }
455
456 private:
458 };
459
466 template<typename CharType>
468 {
469 public:
475 : std::basic_iostream<CharType>(&m_strbuf),
476 m_strbuf(strbuf)
477 {
478 }
479
480 private:
482 };
483
484 #if defined(__cplusplus_winrt)
485
490 class winrt_stream
491 {
492 public:
503 _ASYNCRTIMP static Windows::Storage::Streams::IInputStream^ __cdecl create_input_stream(const concurrency::streams::streambuf<uint8_t> &buffer);
504
515 _ASYNCRTIMP static Windows::Storage::Streams::IOutputStream^ __cdecl create_output_stream(const concurrency::streams::streambuf<uint8_t> &buffer);
516
527 _ASYNCRTIMP static Windows::Storage::Streams::IRandomAccessStream^ __cdecl create_random_access_stream(const concurrency::streams::streambuf<uint8_t> &buffer);
528 };
529
530 #endif
531
532 }} // namespaces
533
534 #if defined(_WIN32)
535 #pragma warning(pop)
536 #endif
stdio_ostream(const stdio_ostream &other)
Copy constructor
Definition: interopstream.h:157
int_type overflow(int_type ch)
Writes one byte to the stream buffer.
Definition: interopstream.h:238
int_type underflow()
Gets one byte from the stream buffer without moving the read position.
Definition: interopstream.h:253
int_type uflow()
Gets one byte from the stream buffer and move the read position one character.
Definition: interopstream.h:268
int sync()
Synchronizes with the underlying medium.
Definition: interopstream.h:323
std::streamsize xsgetn(_Out_writes_(count) CharType *ptr, _In_ std::streamsize count)
Gets a number of characters from the buffer and place it into the provided memory block...
Definition: interopstream.h:283
virtual bool is_open() const
Checks if the stream buffer is open.
Definition: astreambuf.h:390
basic_ostream & operator=(const basic_ostream &other)
Assignment operator
Definition: streams.h:132
Reference-counted stream buffer.
Definition: astreambuf.h:804
async_ostream(const streams::streambuf< AlterCharType > &strbuf)
Constructor
Definition: interopstream.h:408
stdio_istream & operator=(const stdio_istream &other)
Assignment operator
Definition: interopstream.h:208
pos_type seekoff(off_type offset, std::ios_base::seekdir dir, std::ios_base::openmode mode=std::ios_base::in|std::ios_base::out)
Seeks to the given offset relative to the beginning, end, or current position.
Definition: interopstream.h:338
Base interface for all asynchronous output streams.
Definition: astreambuf.h:792
async_istream(const streams::basic_istream< AlterCharType > &astream)
Constructor
Definition: interopstream.h:436
stdio_istream(std::basic_istream< AlterCharType > &stream)
Constructor
Definition: interopstream.h:192
pos_type seekpos(pos_type pos, std::ios_base::openmode mode=std::ios_base::in|std::ios_base::out)
Seeks to the given offset relative to the beginning of the stream.
Definition: interopstream.h:357
async_istream(const streams::streambuf< AlterCharType > &strbuf)
Constructor
Definition: interopstream.h:450
A concrete STL ostream which relies on an asynchronous stream for its I/O.
Definition: interopstream.h:383
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: astreambuf.h:676
async_ostream(const streams::basic_ostream< AlterCharType > &astream)
Constructor
Definition: interopstream.h:394
A concrete STL istream which relies on an asynchronous stream buffer for its I/O. ...
Definition: interopstream.h:467
stdio_ostream represents an async ostream derived from a standard synchronous stream, as defined by the "std" namespace. It is constructed from a reference to a standard stream, which must be valid for the lifetime of the asynchronous stream.
Definition: interopstream.h:38
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
basic_istream & operator=(const basic_istream &other)
Assignment operator
Definition: streams.h:606
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
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
A concrete STL istream which relies on an asynchronous stream for its I/O.
Definition: interopstream.h:425
async_iostream(const streams::streambuf< CharType > &strbuf)
Constructor
Definition: interopstream.h:474
IO streams stream buffer implementation used to interface with an async streambuffer underneath...
Definition: interopstream.h:218
stdio_istream represents an async istream derived from a standard synchronous stream, as defined by the "std" namespace. It is constructed from a reference to a standard stream, which must be valid for the lifetime of the asynchronous stream.
Definition: interopstream.h:39
Base interface for all asynchronous input streams.
Definition: astreambuf.h:791
Definition: astreambuf.h:37
virtual ~basic_stdio_buffer()
Destructor
Definition: interopstream.h:68
The basic_stdio_buffer class serves to support interoperability with STL stream buffers. Sitting atop a std::streambuf, which does all the I/O, instances of this class may read and write data to standard iostreams. The class itself should not be used in application code, it is used by the stream definitions farther down in the header file.
Definition: interopstream.h:50
stdio_ostream(std::basic_ostream< AlterCharType > &stream)
Constructor
Definition: interopstream.h:148
std::streamsize xsputn(const CharType *ptr, std::streamsize count)
Writes a given number of characters from the provided block into the stream buffer.
Definition: interopstream.h:308
stdio_ostream & operator=(const stdio_ostream &other)
Assignment operator
Definition: interopstream.h:164
stdio_istream(const stdio_istream &other)
Copy constructor
Definition: interopstream.h:201