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.
filestream.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 * Asynchronous File streams
20 *
21 * For the latest on this and related APIs, please see http://casablanca.codeplex.com.
22 *
23 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
24 ****/
25 #pragma once
26 
27 #ifndef _CASA_FILE_STREAMS_H
28 #define _CASA_FILE_STREAMS_H
29 
30 #include "cpprest/details/fileio.h"
31 #include "cpprest/astreambuf.h"
32 #include "cpprest/streams.h"
33 #include <assert.h>
34 
35 #ifndef _CONCRT_H
36 #ifndef _LWRCASE_CNCRRNCY
37 #define _LWRCASE_CNCRRNCY
38 // Note to reader: we're using lower-case namespace names everywhere, but the 'Concurrency' namespace
39 // is capitalized for historical reasons. The alias let's us pretend that style issue doesn't exist.
40 namespace Concurrency { }
41 namespace concurrency = Concurrency;
42 #endif
43 #endif
44 
45 namespace Concurrency { namespace streams
46 {
47  // Forward declarations
48  template<typename _CharType> class file_buffer;
49 
50 namespace details {
51  // This operation queue is NOT thread safe
53  {
54  pplx::task<void> m_lastOperation;
55  public:
57  {
58  m_lastOperation = pplx::task_from_result();
59  }
60 
61  // It only accepts functors that take no argument and return pplx::task<T>
62  // This function may execute op inline, thus it could throw immediately
63  template <typename Func>
64  auto enqueue_operation(Func &&op) -> decltype(op())
65  {
66  decltype(op()) res; // res is task<T> , which always has default constructor
67  if (m_lastOperation.is_done())
68  {
69  res = op(); // Exceptions are expected to be thrown directly without catching
70  if (res.is_done())
71  return res;
72  }
73  else
74  {
75  res = m_lastOperation.then([=] {
76  return op(); // It will cause task unwrapping
77  });
78  }
79  m_lastOperation = res.then([&] (decltype(op())) {
80  // This empty task is necessary for keeping the rest of the operations on the list running
81  // even when the previous operation gets error.
82  // Don't observe exception here.
83  });
84  return res;
85  }
86 
87  void wait() const
88  {
89  m_lastOperation.wait();
90  }
91  };
92 
93 
98  template<typename _CharType>
100  {
101  public:
102  typedef typename basic_streambuf<_CharType>::traits traits;
103  typedef typename basic_streambuf<_CharType>::int_type int_type;
104  typedef typename basic_streambuf<_CharType>::pos_type pos_type;
105  typedef typename basic_streambuf<_CharType>::off_type off_type;
106 
107  virtual ~basic_file_buffer()
108  {
109  if( this->can_read() )
110  {
111  this->_close_read().wait();
112  }
113 
114  if (this->can_write())
115  {
116  this->_close_write().wait();
117  }
118  }
119 
120  protected:
121 
125  virtual bool can_seek() const { return this->is_open(); }
126 
130  virtual bool has_size() const { return this->is_open(); }
131 
132  virtual utility::size64_t size() const
133  {
134  if (!this->is_open())
135  return 0;
136  return _get_size(m_info, sizeof(_CharType));
137  }
138 
139 
145  virtual size_t buffer_size(std::ios_base::openmode direction = std::ios_base::in) const
146  {
147  if ( direction == std::ios_base::in )
148  return m_info->m_buffer_size;
149  else
150  return 0;
151  }
152 
160  virtual void set_buffer_size(size_t size, std::ios_base::openmode direction = std::ios_base::in)
161  {
162  if ( direction == std::ios_base::out ) return;
163 
164  m_info->m_buffer_size = size;
165 
166  if ( size == 0 && m_info->m_buffer != nullptr )
167  {
168  delete m_info->m_buffer;
169  m_info->m_buffer = nullptr;
170  }
171  }
172 
178  virtual size_t in_avail() const
179  {
181 
182  return _in_avail_unprot();
183  }
184 
185  size_t _in_avail_unprot() const
186  {
187  if ( !this->is_open() ) return 0;
188 
189  if ( m_info->m_buffer == nullptr || m_info->m_buffill == 0 ) return 0;
190  if ( m_info->m_bufoff > m_info->m_rdpos || (m_info->m_bufoff+m_info->m_buffill) < m_info->m_rdpos ) return 0;
191 
192  msl::safeint3::SafeInt<size_t> rdpos(m_info->m_rdpos);
193  msl::safeint3::SafeInt<size_t> buffill(m_info->m_buffill);
194  msl::safeint3::SafeInt<size_t> bufpos = rdpos - m_info->m_bufoff;
195 
196  return buffill - bufpos;
197  }
198 
199  _file_info * _close_stream()
200  {
201  // indicate that we are no longer open
202  auto fileInfo = m_info;
203  m_info = nullptr;
204  return fileInfo;
205  }
206 
207  static pplx::task<void> _close_file(_In_ _file_info * fileInfo)
208  {
210  auto callback = new _filestream_callback_close(result_tce);
211 
212  if ( !_close_fsb_nolock(&fileInfo, callback) )
213  {
214  delete callback;
215  return pplx::task_from_result();
216  }
217  return pplx::create_task(result_tce);
218  }
219 
220  // Workaround GCC compiler bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58972
221  void _invoke_parent_close_read()
222  {
224  }
225 
227  {
228  return m_readOps.enqueue_operation([this]
229  {
230  _invoke_parent_close_read();
231 
232  if (this->can_write())
233  {
234  return pplx::task_from_result();
235  }
236  else
237  {
238  // Neither heads are open. Close the underlying device
239  // to indicate that we are no longer open
240  auto fileInfo = _close_stream();
241 
242  return _close_file(fileInfo);
243  }
244  });
245  }
246 
248  {
250  if (this->can_read())
251  {
252  // Read head is still open. Just flush the write data
253  return flush_internal();
254  }
255  else
256  {
257  // Neither heads are open. Close the underlying device
258 
259  // We need to flush all writes if the file was opened for writing.
260  return flush_internal().then([=](pplx::task<void> flushTask) -> pplx::task<void>
261  {
262  // swallow exception from flush
263  try
264  {
265  flushTask.wait();
266  }
267  catch(...)
268  {
269  }
270 
271  // indicate that we are no longer open
272  auto fileInfo = this->_close_stream();
273 
274  return this->_close_file(fileInfo);
275  });
276  }
277  }
278 
284  virtual pplx::task<int_type> _putc(_CharType ch)
285  {
286  auto result_tce = pplx::task_completion_event<size_t>();
287  auto callback = new _filestream_callback_write<size_t>(m_info, result_tce);
288 
289  // Potentially we should consider deprecating this API, it is TERRIBLY inefficient.
290  std::shared_ptr<_CharType> sharedCh;
291  try
292  {
293  sharedCh = std::make_shared<_CharType>(ch);
294  } catch (const std::bad_alloc &)
295  {
296  delete callback;
297  throw;
298  }
299 
300  size_t written = _putn_fsb(m_info, callback, sharedCh.get(), 1, sizeof(_CharType));
301  if (written == sizeof(_CharType))
302  {
303  delete callback;
304  return pplx::task_from_result<int_type>(ch);
305  }
306 
307  return pplx::create_task(result_tce).then([sharedCh](size_t)
308  {
309  return static_cast<int_type>(*sharedCh);
310  });
311  }
312 
318  _CharType* _alloc(size_t)
319  {
320  return nullptr;
321  }
322 
327  void _commit(size_t)
328  {
329  }
330 
344  virtual bool acquire(_Out_ _CharType*& ptr, _Out_ size_t& count)
345  {
346  ptr = nullptr;
347  count = 0;
348  return false;
349  }
350 
357  virtual void release(_Out_writes_ (count) _CharType *, _In_ size_t count)
358  {
359  (void)(count);
360  }
361 
368  virtual pplx::task<size_t> _putn(const _CharType *ptr, size_t count)
369  {
370  auto result_tce = pplx::task_completion_event<size_t>();
371  auto callback = new _filestream_callback_write<size_t>(m_info, result_tce);
372 
373  size_t written = _putn_fsb(m_info, callback, ptr, count, sizeof(_CharType));
374 
375  if ( written != 0 && written != -1 )
376  {
377  delete callback;
378  written = written/sizeof(_CharType);
379  return pplx::task_from_result<size_t>(written);
380  }
381  return pplx::create_task(result_tce);
382  }
383 
384  // Temporarily needed until the deprecated putn is removed.
385  virtual pplx::task<size_t> _putn(const _CharType *ptr, size_t count, bool copy)
386  {
387  if (copy)
388  {
389  auto sharedData = std::make_shared<std::vector<_CharType>>(ptr, ptr + count);
390  return _putn(ptr, count).then([sharedData](size_t size)
391  {
392  return size;
393  });
394  }
395  else
396  {
397  return _putn(ptr, count);
398  }
399  }
400 
406  {
407  return m_readOps.enqueue_operation([this]()-> pplx::task<int_type> {
408  if ( _in_avail_unprot() > 0 )
409  {
411 
412  // Check again once the lock is held.
413 
414  if ( _in_avail_unprot() > 0 )
415  {
416  auto bufoff = m_info->m_rdpos - m_info->m_bufoff;
417  _CharType ch = m_info->m_buffer[bufoff*sizeof(_CharType)];
418  m_info->m_rdpos += 1;
419  return pplx::task_from_result<int_type>(ch);
420  }
421  }
422 
423  auto result_tce = pplx::task_completion_event<int_type>();
424  auto callback = new _filestream_callback_bumpc(m_info, result_tce);
425 
426  size_t ch = _getn_fsb(m_info, callback, &callback->m_ch, 1, sizeof(_CharType));
427 
428  if ( ch == sizeof(_CharType) )
429  {
431  m_info->m_rdpos += 1;
432  _CharType ch1 = (_CharType)callback->m_ch;
433  delete callback;
434  return pplx::task_from_result<int_type>(ch1);
435  }
436  return pplx::create_task(result_tce);
437  });
438  }
439 
445  virtual int_type _sbumpc()
446  {
447  m_readOps.wait();
448  if ( m_info->m_atend ) return traits::eof();
449 
450  if ( _in_avail_unprot() == 0 ) return traits::requires_async();
451 
453 
454  if ( _in_avail_unprot() == 0 ) return traits::requires_async();
455 
456  auto bufoff = m_info->m_rdpos - m_info->m_bufoff;
457  _CharType ch = m_info->m_buffer[bufoff*sizeof(_CharType)];
458  m_info->m_rdpos += 1;
459  return (int_type)ch;
460  }
461 
462  pplx::task<int_type> _getcImpl()
463  {
464  if ( _in_avail_unprot() > 0 )
465  {
467 
468  // Check again once the lock is held.
469 
470  if ( _in_avail_unprot() > 0 )
471  {
472  auto bufoff = m_info->m_rdpos - m_info->m_bufoff;
473  _CharType ch = m_info->m_buffer[bufoff*sizeof(_CharType)];
474  return pplx::task_from_result<int_type>(ch);
475  }
476  }
477 
478  auto result_tce = pplx::task_completion_event<int_type>();
479  auto callback = new _filestream_callback_getc(m_info, result_tce);
480 
481  size_t ch = _getn_fsb(m_info, callback, &callback->m_ch, 1, sizeof(_CharType));
482 
483  if ( ch == sizeof(_CharType) )
484  {
486  _CharType ch1 = (_CharType)callback->m_ch;
487  delete callback;
488  return pplx::task_from_result<int_type>(ch1);
489  }
490  return pplx::create_task(result_tce);
491 
492  }
493 
499  {
500  return m_readOps.enqueue_operation([this]()-> pplx::task<int_type> {
501  return _getcImpl();
502  });
503  }
504 
510  int_type _sgetc()
511  {
512  m_readOps.wait();
513  if ( m_info->m_atend ) return traits::eof();
514 
515  if ( _in_avail_unprot() == 0 ) return traits::requires_async();
516 
518 
519  if ( _in_avail_unprot() == 0 ) return traits::requires_async();
520 
521  auto bufoff = m_info->m_rdpos - m_info->m_bufoff;
522  _CharType ch = m_info->m_buffer[bufoff*sizeof(_CharType)];
523  return (int_type)ch;
524  }
525 
531  {
532  return m_readOps.enqueue_operation([this]()-> pplx::task<int_type> {
533  _seekrdpos_fsb(m_info, m_info->m_rdpos+1, sizeof(_CharType));
534  if ( m_info->m_atend )
535  return pplx::task_from_result(basic_file_buffer<_CharType>::traits::eof());
536  return this->_getcImpl();
537  });
538  }
539 
545  {
546  return m_readOps.enqueue_operation([this]()-> pplx::task<int_type> {
547  if ( m_info->m_rdpos == 0 )
548  return pplx::task_from_result<int_type>(basic_file_buffer<_CharType>::traits::eof());
549  _seekrdpos_fsb(m_info, m_info->m_rdpos-1, sizeof(_CharType));
550  return this->_getcImpl();
551  });
552  }
553 
560  virtual pplx::task<size_t> _getn(_Out_writes_ (count) _CharType *ptr, _In_ size_t count)
561  {
562  return m_readOps.enqueue_operation([=] ()-> pplx::task<size_t>{
563  if ( m_info->m_atend || count == 0 )
564  return pplx::task_from_result<size_t>(0);
565 
566  if ( _in_avail_unprot() >= count )
567  {
569 
570  // Check again once the lock is held.
571 
572  if ( _in_avail_unprot() >= count )
573  {
574  auto bufoff = m_info->m_rdpos - m_info->m_bufoff;
575  std::memcpy((void *)ptr, this->m_info->m_buffer+bufoff*sizeof(_CharType), count*sizeof(_CharType));
576 
577  m_info->m_rdpos += count;
578  return pplx::task_from_result<size_t>(count);
579  }
580  }
581 
582  auto result_tce = pplx::task_completion_event<size_t>();
583  auto callback = new _filestream_callback_read(m_info, result_tce);
584 
585  size_t read = _getn_fsb(m_info, callback, ptr, count, sizeof(_CharType));
586 
587  if ( read != 0 && read != -1)
588  {
589  delete callback;
591  m_info->m_rdpos += read/sizeof(_CharType);
592  return pplx::task_from_result<size_t>(read/sizeof(_CharType));
593  }
594  return pplx::create_task(result_tce);
595  });
596  }
597 
605  size_t _sgetn(_Out_writes_ (count) _CharType *ptr, _In_ size_t count)
606  {
607  m_readOps.wait();
608  if ( m_info->m_atend ) return 0;
609 
610  if ( count == 0 || in_avail() == 0 ) return 0;
611 
613 
614  size_t available = _in_avail_unprot();
615  size_t copy = (count < available) ? count : available;
616 
617  auto bufoff = m_info->m_rdpos - m_info->m_bufoff;
618  std::memcpy((void *)ptr, this->m_info->m_buffer+bufoff*sizeof(_CharType), copy*sizeof(_CharType));
619 
620  m_info->m_rdpos += copy;
621  m_info->m_atend = (copy < count);
622  return copy;
623  }
624 
632  virtual size_t _scopy(_CharType *, size_t)
633  {
634  return 0;
635  }
636 
644  virtual pos_type getpos(std::ios_base::openmode mode) const
645  {
646  return const_cast<basic_file_buffer*>(this)->seekoff(0, std::ios_base::cur, mode);
647  }
648 
657  virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode)
658  {
659  if ( mode == std::ios_base::in )
660  {
661  m_readOps.wait();
662  return (pos_type)_seekrdpos_fsb(m_info, size_t(pos), sizeof(_CharType));
663  }
664  else if ( (m_info->m_mode & std::ios::ios_base::app) == 0 )
665  {
666  return (pos_type)_seekwrpos_fsb(m_info, size_t(pos), sizeof(_CharType));
667  }
669  }
670 
680  virtual pos_type seekoff(off_type offset, std::ios_base::seekdir way, std::ios_base::openmode mode)
681  {
682  if ( mode == std::ios_base::in )
683  {
684  m_readOps.wait();
685  switch ( way )
686  {
687  case std::ios_base::beg:
688  return (pos_type)_seekrdpos_fsb(m_info, size_t(offset), sizeof(_CharType));
689  case std::ios_base::cur:
690  return (pos_type)_seekrdpos_fsb(m_info, size_t(m_info->m_rdpos+offset), sizeof(_CharType));
691  case std::ios_base::end:
692  return (pos_type)_seekrdtoend_fsb(m_info, int64_t(offset), sizeof(_CharType));
693  default:
694  // Fail on invalid input (_S_ios_seekdir_end)
695  assert(false);
696  }
697  }
698  else if ( (m_info->m_mode & std::ios::ios_base::app) == 0 )
699  {
700  switch ( way )
701  {
702  case std::ios_base::beg:
703  return (pos_type)_seekwrpos_fsb(m_info, size_t(offset), sizeof(_CharType));
704  case std::ios_base::cur:
705  return (pos_type)_seekwrpos_fsb(m_info, size_t(m_info->m_wrpos+offset), sizeof(_CharType));
706  case std::ios_base::end:
707  return (pos_type)_seekwrpos_fsb(m_info, size_t(-1), sizeof(_CharType));
708  default:
709  // Fail on invalid input (_S_ios_seekdir_end)
710  assert(false);
711  }
712  }
713  return (pos_type)traits::eof();
714  }
715 
720  {
721  return flush_internal().then([](){return true;});
722  }
723 
724  private:
725  template<typename _CharType1> friend class ::concurrency::streams::file_buffer;
726 
727  pplx::task<void> flush_internal()
728  {
730  auto callback = utility::details::make_unique<_filestream_callback_write_b>(m_info, result_tce);
731 
732  if ( !_sync_fsb(m_info, callback.get()) )
733  {
734  return pplx::task_from_exception<void>(std::runtime_error("failure to flush stream"));
735  }
736  callback.release();
737  return pplx::create_task(result_tce);
738  }
739 
740  basic_file_buffer(_In_ _file_info *info) : streambuf_state_manager<_CharType>(info->m_mode), m_info(info) { }
741 
742 #if !defined(__cplusplus_winrt)
744  const utility::string_t &_Filename,
745  std::ios_base::openmode _Mode = std::ios_base::out,
746 #ifdef _WIN32
747  int _Prot = (int)std::ios_base::_Openprot
748 #else
749  int _Prot = 0 // unsupported on Linux, for now
750 #endif
751  )
752  {
754  auto callback = new _filestream_callback_open(result_tce);
755  _open_fsb_str(callback, _Filename.c_str(), _Mode, _Prot);
756  return pplx::create_task(result_tce);
757  }
758 
759 #else
761  ::Windows::Storage::StorageFile^ file,
762  std::ios_base::openmode _Mode = std::ios_base::out)
763  {
765  auto callback = new _filestream_callback_open(result_tce);
766  _open_fsb_stf_str(callback, file, _Mode, 0);
767  return pplx::create_task(result_tce);
768  }
769 #endif
770 
771  class _filestream_callback_open : public details::_filestream_callback
772  {
773  public:
774  _filestream_callback_open(const pplx::task_completion_event<std::shared_ptr<basic_streambuf<_CharType>>> &op) : m_op(op) { }
775 
776  virtual void on_opened(_In_ _file_info *info)
777  {
778  m_op.set(std::shared_ptr<basic_file_buffer<_CharType>>(new basic_file_buffer<_CharType>(info)));
779  delete this;
780  }
781 
782  virtual void on_error(const std::exception_ptr & e)
783  {
784  m_op.set_exception(e);
785  delete this;
786  }
787 
788  private:
790  };
791 
792  class _filestream_callback_close : public details::_filestream_callback
793  {
794  public:
795  _filestream_callback_close(const pplx::task_completion_event<void> &op) : m_op(op) { }
796 
797  virtual void on_closed()
798  {
799  m_op.set();
800  delete this;
801  }
802 
803  virtual void on_error(const std::exception_ptr & e)
804  {
805  m_op.set_exception(e);
806  delete this;
807  }
808 
809  private:
811  };
812 
813  template<typename ResultType>
814  class _filestream_callback_write : public details::_filestream_callback
815  {
816  public:
817  _filestream_callback_write(_In_ _file_info *info, const pplx::task_completion_event<ResultType> &op) : m_info(info), m_op(op) { }
818 
819  virtual void on_completed(size_t result)
820  {
821  m_op.set((ResultType)result / sizeof(_CharType));
822  delete this;
823  }
824 
825  virtual void on_error(const std::exception_ptr & e)
826  {
827  m_op.set_exception(e);
828  delete this;
829  }
830 
831  private:
832  _file_info *m_info;
834  };
835 
836  class _filestream_callback_write_b : public details::_filestream_callback
837  {
838  public:
839  _filestream_callback_write_b(_In_ _file_info *info, const pplx::task_completion_event<void> &op) : m_info(info), m_op(op) { }
840 
841  virtual void on_completed(size_t)
842  {
843  m_op.set();
844  delete this;
845  }
846 
847  virtual void on_error(const std::exception_ptr & e)
848  {
849  m_op.set_exception(e);
850  delete this;
851  }
852 
853  private:
854  _file_info *m_info;
856  };
857 
858 
859  class _filestream_callback_read : public details::_filestream_callback
860  {
861  public:
862  _filestream_callback_read(_In_ _file_info *info, const pplx::task_completion_event<size_t> &op) : m_info(info), m_op(op) { }
863 
864  virtual void on_completed(size_t result)
865  {
866  result = result / sizeof(_CharType);
867  m_info->m_rdpos += result;
868  m_op.set(result);
869  delete this;
870  }
871 
872  virtual void on_error(const std::exception_ptr & e)
873  {
874  m_op.set_exception(e);
875  delete this;
876  }
877 
878  private:
879  _file_info *m_info;
881  };
882 
883  class _filestream_callback_bumpc : public details::_filestream_callback
884  {
885  public:
886  _filestream_callback_bumpc(_In_ _file_info *info, const pplx::task_completion_event<int_type> &op) : m_ch(0), m_info(info), m_op(op) { }
887 
888  virtual void on_completed(size_t result)
889  {
890  if ( result == sizeof(_CharType) )
891  {
892  m_info->m_rdpos += 1;
893  m_op.set(m_ch);
894  }
895  else
896  {
897  m_op.set(traits::eof());
898  }
899  delete this;
900  }
901 
902  virtual void on_error(const std::exception_ptr & e)
903  {
904  m_op.set_exception(e);
905  delete this;
906  }
907 
908  int_type m_ch;
909 
910  private:
911  _file_info *m_info;
913  };
914 
915  class _filestream_callback_getc : public details::_filestream_callback
916  {
917  public:
918  _filestream_callback_getc(_In_ _file_info *info, const pplx::task_completion_event<int_type> &op) : m_ch(0), m_info(info), m_op(op) { }
919 
920  virtual void on_completed(size_t result)
921  {
922  if ( result == sizeof(_CharType) )
923  {
924  m_op.set(m_ch);
925  }
926  else
927  {
928  m_op.set(traits::eof());
929  }
930  delete this;
931  }
932 
933  int_type m_ch;
934 
935  virtual void on_error(const std::exception_ptr & e)
936  {
937  m_op.set_exception(e);
938  delete this;
939  }
940 
941  private:
942  _file_info *m_info;
944  };
945 
946  _file_info *m_info;
947  async_operation_queue m_readOps;
948  };
949 
950  } // namespace details
951 
958  template<typename _CharType>
959  class file_buffer
960  {
961  public:
962 #if !defined(__cplusplus_winrt)
971  const utility::string_t &file_name,
972  std::ios_base::openmode mode = std::ios_base::out,
973 #ifdef _WIN32
974  int prot = _SH_DENYRD
975 #else
976  int prot = 0 // unsupported on Linux
977 #endif
978  )
979  {
980  auto bfb = details::basic_file_buffer<_CharType>::open(file_name, mode, prot);
981  return bfb.then([](pplx::task<std::shared_ptr<details::basic_streambuf<_CharType>>> op) -> streambuf<_CharType>
982  {
983  return streambuf<_CharType>(op.get());
984  });
985  }
986 
987 #else
996  ::Windows::Storage::StorageFile^ file,
997  std::ios_base::openmode mode = std::ios_base::out)
998  {
999  auto bfb = details::basic_file_buffer<_CharType>::open(file, mode);
1000  return bfb.then([](pplx::task<std::shared_ptr<details::basic_streambuf<_CharType>>> op) -> streambuf<_CharType>
1001  {
1002  return streambuf<_CharType>(op.get());
1003  });
1004  }
1005 #endif
1006  };
1007 
1008 
1015  template<typename _CharType>
1017  {
1018  public:
1019 
1020 #if !defined(__cplusplus_winrt)
1030  const utility::string_t &file_name,
1031  std::ios_base::openmode mode = std::ios_base::in,
1032 #ifdef _WIN32
1033  int prot = (int) std::ios_base::_Openprot
1034 #else
1035  int prot = 0
1036 #endif
1037  )
1038  {
1039  mode |= std::ios_base::in;
1040  return streams::file_buffer<_CharType>::open(file_name, mode, prot)
1042  {
1043  return basic_istream<_CharType>(buf);
1044  });
1045  }
1046 
1057  const utility::string_t &file_name,
1058  std::ios_base::openmode mode = std::ios_base::out,
1059 #ifdef _WIN32
1060  int prot = (int) std::ios_base::_Openprot
1061 #else
1062  int prot = 0
1063 #endif
1064  )
1065  {
1066  mode |= std::ios_base::out;
1067  return streams::file_buffer<_CharType>::open(file_name, mode, prot)
1069  {
1070  return basic_ostream<_CharType>(buf);
1071  });
1072  }
1073 #else
1082  ::Windows::Storage::StorageFile^ file,
1083  std::ios_base::openmode mode = std::ios_base::in)
1084  {
1085  mode |= std::ios_base::in;
1086  return streams::file_buffer<_CharType>::open(file, mode)
1088  {
1089  return basic_istream<_CharType>(buf);
1090  });
1091  }
1092 
1102  ::Windows::Storage::StorageFile^ file,
1103  std::ios_base::openmode mode = std::ios_base::out)
1104  {
1105  mode |= std::ios_base::out;
1106  return streams::file_buffer<_CharType>::open(file, mode)
1107  .then([](streams::streambuf<_CharType> buf) -> basic_ostream<_CharType>
1108  {
1109  return basic_ostream<_CharType>(buf);
1110  });
1111  }
1112 #endif
1113  };
1114 
1115  typedef file_stream<uint8_t> fstream;
1116 }} // namespace concurrency::streams
1117 
1118 #endif
1119 
1120 
1121 
1122 
1123 
1124 
1125 
1126 
1127 
1128 
1129 
1130 
1131 
1132 
A generic RAII wrapper for locks that implements the critical_section interface cpprest_synchronizati...
Definition: pplxlinux.h:264
int_type _sgetc()
Reads a single byte from the stream without advancing the read position.
Definition: filestream.h:510
The task_completion_event class allows you to delay the execution of a task until a condition is sati...
Definition: pplxtasks.h:2934
virtual void set_buffer_size(size_t size, std::ios_base::openmode direction=std::ios_base::in)
Sets the stream buffer implementation to buffer or not buffer.
Definition: filestream.h:160
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: filestream.h:132
virtual bool is_open() const
Checks if the stream buffer is open.
Definition: astreambuf.h:390
Reference-counted stream buffer.
Definition: astreambuf.h:804
virtual bool can_seek() const
can_seek is used to determine whether a stream buffer supports seeking.
Definition: filestream.h:125
virtual size_t buffer_size(std::ios_base::openmode direction=std::ios_base::in) const
Gets the stream buffer size, if one has been set.
Definition: filestream.h:145
Base interface for all asynchronous output streams.
Definition: astreambuf.h:792
virtual pplx::task< bool > _sync()
For output streams, flush any internally buffered data to the underlying medium.
Definition: filestream.h:719
virtual pplx::task< int_type > _nextc()
Advances the read position, then return the next character without advancing again.
Definition: filestream.h:530
virtual pplx::task< size_t > _putn(const _CharType *ptr, size_t count)
Writes a number of characters to the stream.
Definition: filestream.h:368
size_t _sgetn(_Out_writes_(count) _CharType *ptr, _In_ size_t count)
Reads up to a given number of characters from the stream.
Definition: filestream.h:605
virtual pplx::task< int_type > _bumpc()
Reads a single byte from the stream and advance the read position.
Definition: filestream.h:405
virtual bool can_read() const
can_read is used to determine whether a stream buffer will support read operations (get)...
Definition: astreambuf.h:373
pplx::task< int_type > _getc()
Reads a single byte from the stream without advancing the read position.
Definition: filestream.h:498
void _commit(size_t)
Submits a block already allocated by the stream buffer.
Definition: filestream.h:327
virtual pplx::task< int_type > _ungetc()
Retreats the read position, then return the current character without advancing.
Definition: filestream.h:544
virtual pplx::task< int_type > _putc(_CharType ch)
Writes a single byte to an output stream.
Definition: filestream.h:284
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
File stream class containing factory functions for file streams.
Definition: filestream.h:1016
virtual bool acquire(_Out_ _CharType *&ptr, _Out_ size_t &count)
Gets a pointer to the next already allocated contiguous block of data.
Definition: filestream.h:344
pplx::task< void > _close_read()
The real read head close operation, implementation should override it if there is any resource to be ...
Definition: filestream.h:226
static pplx::task< streambuf< _CharType > > open(const utility::string_t &file_name, std::ios_base::openmode mode=std::ios_base::out, int prot=0)
Open a new stream buffer representing the given file.
Definition: filestream.h:970
Private stream buffer implementation for file streams. The class itself should not be used in applica...
Definition: filestream.h:99
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: filestream.h:560
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
virtual size_t in_avail() const
For any input stream, in_avail returns the number of characters that are immediately available to be ...
Definition: filestream.h:178
virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode)
Seeks to the given position.
Definition: filestream.h:657
virtual bool can_write() const
can_write is used to determine whether a stream buffer will support write operations (put)...
Definition: astreambuf.h:381
virtual void release(_Out_writes_(count) _CharType *, _In_ size_t count)
Releases a block of data acquired using ::acquire method. This frees the stream buffer to de-allocate...
Definition: filestream.h:357
virtual bool has_size() const
has_size is used to determine whether a stream buffer supports size().
Definition: filestream.h:130
The Parallel Patterns Library (PPL) task class. A task object represents work that can be executed as...
Definition: pplxtasks.h:176
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
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: filestream.h:680
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
virtual pos_type getpos(std::ios_base::openmode mode) const
Gets the current read or write position in the stream.
Definition: filestream.h:644
static pplx::task< streams::basic_ostream< _CharType > > open_ostream(const utility::string_t &file_name, std::ios_base::openmode mode=std::ios_base::out, int prot=0)
Open a new ouput stream representing the given file. If the file does not exist, it will be create un...
Definition: filestream.h:1056
virtual size_t _scopy(_CharType *, size_t)
Copies up to a given number of characters from the stream.
Definition: filestream.h:632
Definition: astreambuf.h:37
static pplx::task< streams::basic_istream< _CharType > > open_istream(const utility::string_t &file_name, std::ios_base::openmode mode=std::ios_base::in, int prot=0)
Open a new input stream representing the given file. The file should already exist on disk...
Definition: filestream.h:1029
pplx::task< void > _close_write()
The real write head close operation, implementation should override it if there is any resource to be...
Definition: filestream.h:247
Stream buffer for file streams.
Definition: filestream.h:48
virtual int_type _sbumpc()
Reads a single byte from the stream and advance the read position.
Definition: filestream.h:445
_CharType * _alloc(size_t)
Allocates a contiguous memory block and returns it.
Definition: filestream.h:318
Extending the standard char_traits type with one that adds values and types that are unique to "C++ R...
Definition: astreambuf.h:50
bool is_done() const
Determines if the task is completed.
Definition: pplxtasks.h:4454