11 #include <type_traits>
15 #include <experimental/type_traits>
35 template<std::
size_t BufSize>
41 static constexpr std::size_t
buf_size = BufSize;
145 template<
typename Sink,
typename Buffering,
typename CharT,
typename Traits,
typename Category =
void>
148 template<
typename Sink,
typename Buffering,
typename CharT,
typename Traits,
typename Category>
149 class basic_outbuf :
public std::basic_streambuf<CharT, Traits>
152 typedef CharT char_type;
153 typedef Traits traits_type;
154 typedef typename Traits::int_type int_type;
155 typedef typename Traits::pos_type pos_type;
156 typedef typename Traits::off_type off_type;
158 typedef std::basic_ostream<char_type, traits_type> _super_type;
160 template<
class... Args>
161 basic_outbuf(Args &&... args) : _sink{std::forward<Args>(args)...}, _buffer{
new CharT[Buffering::buf_size]}
163 this->setp(_buffer, _buffer + Buffering::buf_size - 1);
166 basic_outbuf(
const basic_outbuf& other) =
delete;
167 basic_outbuf(basic_outbuf&& ) =
delete;
169 ~basic_outbuf() noexcept
override { sync();
delete[] _buffer; }
171 basic_outbuf& operator=(
const basic_outbuf& ) =
delete;
172 basic_outbuf& operator=(basic_outbuf&& ) =
delete;
174 Sink& operator*() {
return _sink; }
175 Sink* operator->() {
return &_sink; }
177 const Sink& operator*()
const {
return _sink; }
178 const Sink* operator->()
const {
return &_sink; }
180 void reset() { this->setp(_buffer, _buffer + Buffering::buf_size - 1); }
183 int_type overflow(int_type ch)
override
185 _buffer[Buffering::buf_size-1] =
static_cast<char>(ch);
186 this->setp(_buffer, _buffer + Buffering::buf_size - 1);
187 return _sink.write(_buffer, Buffering::buf_size) < Buffering::buf_size ? traits_type::eof() : ch;
192 std::size_t size = this->pptr() - _buffer;
195 if (_sink.write(_buffer, static_cast<std::streamsize>(size)) < size)
return -1;
198 this->setp(_buffer, _buffer + Buffering::buf_size - 1);
207 template<
typename Sink,
typename CharT,
typename Traits>
208 class basic_outbuf<Sink, non_buffered, CharT, Traits,
209 typename std::enable_if_t<std::is_same<typename Sink::category, buffer_provider>::value>> :
210 public std::basic_streambuf<CharT, Traits>
213 typedef CharT char_type;
214 typedef Traits traits_type;
215 typedef typename Traits::int_type int_type;
216 typedef typename Traits::pos_type pos_type;
217 typedef typename Traits::off_type off_type;
219 typedef std::basic_ostream<char_type, traits_type> _super_type;
221 template<
class... Args>
222 basic_outbuf(Args &&... args) : _sink{std::forward<Args>(args)...} {}
224 basic_outbuf(
const basic_outbuf& other) =
delete;
225 basic_outbuf(basic_outbuf&& ) =
delete;
227 ~basic_outbuf() noexcept
override { sync(); }
229 basic_outbuf& operator=(
const basic_outbuf& ) =
delete;
230 basic_outbuf& operator=(basic_outbuf&& ) =
delete;
232 Sink& operator*() {
return _sink; }
233 Sink* operator->() {
return &_sink; }
235 const Sink& operator*()
const {
return _sink; }
236 const Sink* operator->()
const {
return &_sink; }
238 void reset() { this->setp(this->pbase(), this->epptr()); }
241 int_type overflow(int_type ch)
override
243 *this->pptr() =
static_cast<char>(ch);
244 std::pair<CharT*, std::size_t> buffer = _sink.get_buffer();
245 if (!buffer.first || buffer.second <= 0)
return traits_type::eof();
246 this->setp(buffer.first, buffer.first + buffer.second - 1);
252 _sink.flush(this->pptr() - this->pbase());
260 template<
typename Sink,
typename CharT,
typename Traits,
typename Category>
261 class basic_outbuf<Sink, non_buffered, CharT, Traits, Category> :
public std::basic_streambuf<CharT, Traits>
264 typedef CharT char_type;
265 typedef Traits traits_type;
266 typedef typename Traits::int_type int_type;
267 typedef typename Traits::pos_type pos_type;
268 typedef typename Traits::off_type off_type;
270 template <
class... Args>
271 basic_outbuf(Args&&... args) : _sink{std::forward<Args>(args)...} {}
273 basic_outbuf(
const basic_outbuf& ) =
default;
274 basic_outbuf(basic_outbuf&& ) =
default;
276 basic_outbuf& operator=(
const basic_outbuf& ) =
default;
277 basic_outbuf& operator=(basic_outbuf&& ) =
default;
281 Sink& operator*() {
return _sink; }
282 Sink* operator->() {
return &_sink; }
284 const Sink& operator*()
const {
return _sink; }
285 const Sink* operator->()
const {
return &_sink; }
288 int_type overflow(int_type ch)
override
290 char_type tmp_ch =
static_cast<char_type
>(ch);
291 return _sink.write(&tmp_ch, 1) == 1 ? ch : traits_type::eof();
294 int sync()
override { _sink.flush();
return 0; }
296 std::streamsize xsputn(
const char_type* s, std::streamsize n)
override {
return _sink.write(s, n); }
321 template<
typename Sink,
typename Buffering,
typename CharT,
typename Traits = std::
char_traits<CharT>>
324 typedef basic_outbuf<Sink, Buffering, CharT, Traits> _outbuf_type;
325 typedef std::basic_ostream<CharT, Traits> _ostream_type;
357 template <
class... Args>
360 this->rdbuf(
new _outbuf_type{std::forward<Args>(args)...});
369 this->rdbuf(other.rdbuf());
370 other.rdbuf(
nullptr);
380 this->rdbuf(other.rdbuf());
381 other.rdbuf(
nullptr);
408 const Sink&
operator*()
const {
return buf()->operator*(); }
414 const Sink*
operator->()
const {
return buf()->operator->(); }
419 inline _outbuf_type *buf() {
return static_cast<_outbuf_type*
>(this->rdbuf()); }
420 inline const _outbuf_type *buf()
const {
return static_cast<const _outbuf_type*
>(this->rdbuf()); }
423 template<
typename Source,
typename Buffering,
typename CharT,
typename Traits,
typename Enable =
void>
426 template<
typename Source,
typename Buffering,
typename CharT,
typename Traits,
typename Enable>
427 class basic_inbuf :
public std::basic_streambuf<CharT, Traits>
430 typedef CharT char_type;
431 typedef Traits traits_type;
432 typedef typename Traits::int_type int_type;
433 typedef typename Traits::pos_type pos_type;
434 typedef typename Traits::off_type off_type;
436 template <
class... Args>
437 basic_inbuf(Args&&... args) : _source{std::forward<Args>(args)...}, _buffer{
new char_type[Buffering::buf_size]} {}
439 ~basic_inbuf() noexcept
override {
delete[] _buffer; }
441 basic_inbuf(
const basic_inbuf& ) =
delete;
442 basic_inbuf(basic_inbuf&& other) =
delete;
444 basic_inbuf& operator=(
const basic_inbuf& ) =
delete;
445 basic_inbuf& operator=(basic_inbuf&& ) =
delete;
447 Source& operator*() {
return _source; }
448 Source* operator->() {
return &_source; }
450 const Source& operator*()
const {
return _source; }
451 const Source* operator->()
const {
return &_source; }
456 int_type underflow()
override
458 std::streamsize new_size = _source.read(_buffer, Buffering::buf_size);
459 if (new_size == 0)
return traits_type::eof();
460 this->setg(_buffer, _buffer, _buffer + new_size);
461 return traits_type::to_int_type(*_buffer);
464 int_type pbackfail(int_type ch)
override
466 if (this->egptr() <= this->eback())
return traits_type::eof();
476 template<
typename Source,
typename CharT,
typename Traits>
477 class basic_inbuf<Source, non_buffered, CharT, Traits,
478 typename std::enable_if_t<std::is_same<typename Source::category, buffer_provider>::value>> :
479 public std::basic_streambuf<CharT, Traits>
482 typedef CharT char_type;
483 typedef Traits traits_type;
484 typedef typename Traits::int_type int_type;
485 typedef typename Traits::pos_type pos_type;
486 typedef typename Traits::off_type off_type;
488 template <
class... Args>
489 basic_inbuf(Args&&... args) : _source{std::forward<Args>(args)...} {}
491 ~basic_inbuf() noexcept = default;
493 basic_inbuf(const basic_inbuf& ) = delete;
494 basic_inbuf(basic_inbuf&& other) = delete;
496 basic_inbuf& operator=(const basic_inbuf& ) = delete;
497 basic_inbuf& operator=(basic_inbuf&& ) = delete;
499 Source& operator*() {
return _source; }
500 Source* operator->() {
return &_source; }
502 const Source& operator*()
const {
return _source; }
503 const Source* operator->()
const {
return &_source; }
505 void reset() { this->setg(this->eback(), this->eback(), this->egptr()); }
508 int_type underflow()
override
510 std::pair<CharT*, std::size_t> buffer = _source.get_buffer();
511 if (!buffer.first || buffer.second <= 0)
return traits_type::eof();
512 this->setg(buffer.first, buffer.first, buffer.first + buffer.second);
513 return traits_type::to_int_type(*this->eback());
516 int_type pbackfail(int_type ch)
override
518 if (this->egptr() <= this->eback())
return traits_type::eof();
545 template<
typename Source,
typename Buffering,
typename CharT,
typename Traits = std::
char_traits<CharT>>
548 typedef basic_inbuf<Source, Buffering, CharT, Traits> _inbuf_type;
549 typedef std::basic_istream<CharT, Traits> _istream_type;
581 template <
typename... Args>
584 this->rdbuf(
new _inbuf_type{std::forward<Args>(args)...});
589 basic_instream(
const basic_instream& ) =
delete;
597 this->rdbuf(other.rdbuf());
598 other.rdbuf(
nullptr);
609 this->rdbuf(other.rdbuf());
610 other.rdbuf(
nullptr);
637 const Source&
operator*()
const {
return buf()->operator*(); }
643 const Source*
operator->()
const {
return buf()->operator->(); }
647 inline _inbuf_type* buf() {
return static_cast<_inbuf_type*
>(this->rdbuf()); }
648 inline const _inbuf_type* buf()
const {
return static_cast<const _inbuf_type*
>(this->rdbuf()); }
654 template <
typename Sink,
typename Buffering = non_buffered>
655 using outstream = basic_outstream<Sink, Buffering, char>;
659 template <
typename Source,
typename Buffering = non_buffered>
660 using instream = basic_instream<Source, Buffering, char>;
664 #endif // SERVLET_IO_H
traits_type::int_type int_type
traits_type::int_type
Definition: io.h:338
Source & operator*()
Provides access to the reference to the Source instance associated with this stream.
Definition: io.h:624
Implementation of output stream object.
Definition: io.h:322
Sink * operator->()
Provides access to the pointer to the Sink instance associated with this stream.
Definition: io.h:401
Traits traits_type
Type of character traits class to be used by this stream.
Definition: io.h:558
static constexpr std::size_t buf_size
Size of buffer as constant expression.
Definition: io.h:41
traits_type::pos_type pos_type
traits_type::pos_type
Definition: io.h:566
~basic_outstream() noexceptoverride
Destructor.
Definition: io.h:388
traits_type::off_type off_type
traits_type::off_type
Definition: io.h:570
traits_type::int_type int_type
traits_type::int_type
Definition: io.h:562
basic_outstream(basic_outstream &&other)
Move constructor.
Definition: io.h:367
Source tag.
Definition: io.h:143
const Sink & operator*() const
Provides access to the constant reference to the Sink instance associated with this stream...
Definition: io.h:408
Source tag.
Definition: io.h:114
basic_instream(basic_instream &&other)
Move constructor.
Definition: io.h:595
const Source * operator->() const
Provides access to the constant pointer to the Source instance associated with this stream...
Definition: io.h:643
const Source & operator*() const
Provides access to the constant reference to the Source instance associated with this stream...
Definition: io.h:637
Traits traits_type
Type of character traits class to be used by this stream.
Definition: io.h:334
~basic_instream() noexceptoverride
Destructor.
Definition: io.h:617
Implementation of input stream object.
Definition: io.h:546
Template class holder of the buffer size.
Definition: io.h:36
CharT char_type
Cacracter type to be used by this stream.
Definition: io.h:330
basic_outstream & operator=(basic_outstream &&other)
Move assignment operator.
Definition: io.h:378
Sink & operator*()
Provides access to the reference to the Sink instance associated with this stream.
Definition: io.h:395
traits_type::off_type off_type
traits_type::off_type
Definition: io.h:346
traits_type::pos_type pos_type
traits_type::pos_type
Definition: io.h:342
Sink tag.
Definition: io.h:91
basic_instream & operator=(basic_instream &&other)
Move assignment operator.
Definition: io.h:607
CharT char_type
Cacracter type to be used by this stream.
Definition: io.h:554
basic_outstream(Args &&...args)
Main constructor.
Definition: io.h:358
basic_instream(Args &&...args)
Main constructor.
Definition: io.h:582
const Sink * operator->() const
Provides access to the constant pointer to the Sink instance associated with this stream...
Definition: io.h:414
Source * operator->()
Provides access to the pointer to the Source instance associated with this stream.
Definition: io.h:630