C++ Rest SDK
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.
interopstream.h
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 
36 namespace Concurrency { namespace streams {
37 
38  template<typename CharType> class stdio_ostream;
39  template<typename CharType> class stdio_istream;
40 
41  namespace details {
42 
49  template<typename _CharType>
50  class basic_stdio_buffer : public streambuf_state_manager<_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;
59  basic_stdio_buffer(_In_ std::basic_streambuf<_CharType>* streambuf, std::ios_base::openmode mode)
60  : streambuf_state_manager<_CharType>(mode), m_buffer(streambuf)
61  {
62  }
63 
64  public:
69  {
70  this->_close_read();
71  this->_close_write();
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>
148  stdio_ostream(std::basic_ostream<AlterCharType>& stream)
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 
157  stdio_ostream(const stdio_ostream &other) : basic_ostream<CharType>(other) { }
158 
165  };
166 
180  template<typename CharType>
181  class stdio_istream : public basic_istream<CharType>
182  {
183  public:
191  template <typename AlterCharType>
192  stdio_istream(std::basic_istream<AlterCharType>& stream)
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 
201  stdio_istream(const stdio_istream &other) : basic_istream<CharType>(other) { }
202 
209  };
210 
211  namespace details {
212 
217  template<typename CharType>
218  class basic_async_streambuf : public std::basic_streambuf<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 
226  basic_async_streambuf(const streams::streambuf<CharType> &async_buf) : m_buffer(async_buf)
227  {
228  }
229  protected:
230 
231  //
232  // The following are the functions in std::basic_streambuf that we need to override.
233  //
234 
238  int_type overflow(int_type ch)
239  {
240  try
241  {
242  return m_buffer.putc(CharType(ch)).get();
243  }
244  catch(...)
245  {
246  return traits::eof();
247  }
248  }
249 
253  int_type underflow()
254  {
255  try
256  {
257  return m_buffer.getc().get();
258  }
259  catch(...)
260  {
261  return traits::eof();
262  }
263  }
264 
268  int_type uflow()
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 
338  pos_type seekoff(off_type offset,
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 
357  pos_type seekpos(pos_type pos,
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>
383  class async_ostream : public std::basic_ostream<CharType>
384  {
385  public:
393  template <typename AlterCharType>
395  : std::basic_ostream<CharType>(&m_strbuf),
396  m_strbuf(astream.streambuf())
397  {
398  }
399 
407  template <typename AlterCharType>
409  : std::basic_ostream<CharType>(&m_strbuf),
410  m_strbuf(strbuf)
411  {
412  }
413 
414  private:
416  };
417 
424  template<typename CharType>
425  class async_istream : public std::basic_istream<CharType>
426  {
427  public:
435  template <typename AlterCharType>
437  : std::basic_istream<CharType>(&m_strbuf),
438  m_strbuf(astream.streambuf())
439  {
440  }
441 
449  template <typename AlterCharType>
451  : std::basic_istream<CharType>(&m_strbuf),
452  m_strbuf(strbuf)
453  {
454  }
455 
456  private:
458  };
459 
466  template<typename CharType>
467  class async_iostream : public std::basic_iostream<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
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