UnbufferedStreamBuf.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. //
  2. // UnufferedStreamBuf.h
  3. //
  4. // $Id: //poco/1.4/Foundation/include/Poco/UnbufferedStreamBuf.h#1 $
  5. //
  6. // Library: Foundation
  7. // Package: Streams
  8. // Module: StreamBuf
  9. //
  10. // Definition of template BasicUnbufferedStreamBuf and class UnbufferedStreamBuf.
  11. //
  12. // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
  13. // and Contributors.
  14. //
  15. // SPDX-License-Identifier: BSL-1.0
  16. //
  17. #ifndef Foundation_UnbufferedStreamBuf_INCLUDED
  18. #define Foundation_UnbufferedStreamBuf_INCLUDED
  19. #include "Poco/Foundation.h"
  20. #include "Poco/StreamUtil.h"
  21. #include <streambuf>
  22. #include <iosfwd>
  23. #include <ios>
  24. namespace Poco {
  25. template <typename ch, typename tr>
  26. class BasicUnbufferedStreamBuf: public std::basic_streambuf<ch, tr>
  27. /// This is an implementation of an unbuffered streambuf
  28. /// that greatly simplifies the implementation of
  29. /// custom streambufs of various kinds.
  30. /// Derived classes only have to override the methods
  31. /// readFromDevice() or writeToDevice().
  32. {
  33. protected:
  34. typedef std::basic_streambuf<ch, tr> Base;
  35. typedef std::basic_ios<ch, tr> IOS;
  36. typedef ch char_type;
  37. typedef tr char_traits;
  38. typedef typename Base::int_type int_type;
  39. typedef typename Base::pos_type pos_type;
  40. typedef typename Base::off_type off_type;
  41. typedef typename IOS::openmode openmode;
  42. public:
  43. BasicUnbufferedStreamBuf():
  44. _pb(char_traits::eof()),
  45. _ispb(false)
  46. {
  47. this->setg(0, 0, 0);
  48. this->setp(0, 0);
  49. }
  50. ~BasicUnbufferedStreamBuf()
  51. {
  52. }
  53. virtual int_type overflow(int_type c)
  54. {
  55. if (c != char_traits::eof())
  56. return writeToDevice(char_traits::to_char_type(c));
  57. else
  58. return c;
  59. }
  60. virtual int_type underflow()
  61. {
  62. if (_ispb)
  63. {
  64. return _pb;
  65. }
  66. else
  67. {
  68. int_type c = readFromDevice();
  69. if (c != char_traits::eof())
  70. {
  71. _ispb = true;
  72. _pb = c;
  73. }
  74. return c;
  75. }
  76. }
  77. virtual int_type uflow()
  78. {
  79. if (_ispb)
  80. {
  81. _ispb = false;
  82. return _pb;
  83. }
  84. else
  85. {
  86. int_type c = readFromDevice();
  87. if (c != char_traits::eof())
  88. {
  89. _pb = c;
  90. }
  91. return c;
  92. }
  93. }
  94. virtual int_type pbackfail(int_type c)
  95. {
  96. if (_ispb)
  97. {
  98. return char_traits::eof();
  99. }
  100. else
  101. {
  102. _ispb = true;
  103. _pb = c;
  104. return c;
  105. }
  106. }
  107. virtual std::streamsize xsgetn(char_type* p, std::streamsize count)
  108. /// Some platforms (for example, Compaq C++) have buggy implementations of
  109. /// xsgetn that handle null buffers incorrectly.
  110. /// Anyway, it does not hurt to provide an optimized implementation
  111. /// of xsgetn for this streambuf implementation.
  112. {
  113. std::streamsize copied = 0;
  114. while (count > 0)
  115. {
  116. int_type c = uflow();
  117. if (c == char_traits::eof()) break;
  118. *p++ = char_traits::to_char_type(c);
  119. ++copied;
  120. --count;
  121. }
  122. return copied;
  123. }
  124. protected:
  125. static int_type charToInt(char_type c)
  126. {
  127. return char_traits::to_int_type(c);
  128. }
  129. private:
  130. virtual int_type readFromDevice()
  131. {
  132. return char_traits::eof();
  133. }
  134. virtual int_type writeToDevice(char_type)
  135. {
  136. return char_traits::eof();
  137. }
  138. int_type _pb;
  139. bool _ispb;
  140. BasicUnbufferedStreamBuf(const BasicUnbufferedStreamBuf&);
  141. BasicUnbufferedStreamBuf& operator = (const BasicUnbufferedStreamBuf&);
  142. };
  143. //
  144. // We provide an instantiation for char
  145. //
  146. typedef BasicUnbufferedStreamBuf<char, std::char_traits<char> > UnbufferedStreamBuf;
  147. } // namespace Poco
  148. #endif // Foundation_UnbufferedStreamBuf_INCLUDED