File indexing completed on 2025-01-18 09:38:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #ifndef BOOST_INTERPROCESS_BUFFERSTREAM_HPP
0036 #define BOOST_INTERPROCESS_BUFFERSTREAM_HPP
0037
0038 #ifndef BOOST_CONFIG_HPP
0039 # include <boost/config.hpp>
0040 #endif
0041 #
0042 #if defined(BOOST_HAS_PRAGMA_ONCE)
0043 # pragma once
0044 #endif
0045
0046 #include <boost/interprocess/detail/config_begin.hpp>
0047 #include <boost/interprocess/detail/workaround.hpp>
0048
0049 #include <iosfwd>
0050 #include <ios>
0051 #include <istream>
0052 #include <ostream>
0053 #include <string> // char traits
0054 #include <cstddef> // ptrdiff_t
0055 #include <boost/assert.hpp>
0056 #include <boost/interprocess/interprocess_fwd.hpp>
0057
0058 namespace boost { namespace interprocess {
0059
0060
0061
0062
0063 template <class CharT, class CharTraits>
0064 class basic_bufferbuf
0065 : public std::basic_streambuf<CharT, CharTraits>
0066 {
0067 public:
0068 typedef CharT char_type;
0069 typedef typename CharTraits::int_type int_type;
0070 typedef typename CharTraits::pos_type pos_type;
0071 typedef typename CharTraits::off_type off_type;
0072 typedef CharTraits traits_type;
0073 typedef std::basic_streambuf<char_type, traits_type> basic_streambuf_t;
0074
0075 public:
0076
0077
0078 explicit basic_bufferbuf(std::ios_base::openmode mode
0079 = std::ios_base::in | std::ios_base::out)
0080 : basic_streambuf_t(), m_mode(mode), m_buffer(0), m_length(0)
0081 {}
0082
0083
0084
0085 explicit basic_bufferbuf(CharT *buf, std::size_t length,
0086 std::ios_base::openmode mode
0087 = std::ios_base::in | std::ios_base::out)
0088 : basic_streambuf_t(), m_mode(mode), m_buffer(buf), m_length(length)
0089 { this->set_pointers(); }
0090
0091 virtual ~basic_bufferbuf() BOOST_OVERRIDE {}
0092
0093 public:
0094
0095
0096 std::pair<CharT *, std::size_t> buffer() const
0097 { return std::pair<CharT *, std::size_t>(m_buffer, m_length); }
0098
0099
0100
0101 void buffer(CharT *buf, std::size_t length)
0102 { m_buffer = buf; m_length = length; this->set_pointers(); }
0103
0104 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0105 private:
0106 void set_pointers()
0107 {
0108
0109 if(m_mode & std::ios_base::in)
0110 this->setg(m_buffer, m_buffer, m_buffer + m_length);
0111
0112
0113 if(m_mode & std::ios_base::out)
0114 this->setp(m_buffer, m_buffer + m_length);
0115 }
0116
0117 protected:
0118 virtual int_type underflow() BOOST_OVERRIDE
0119 {
0120
0121 return this->gptr() != this->egptr() ?
0122 CharTraits::to_int_type(*this->gptr()) : CharTraits::eof();
0123 }
0124
0125 virtual int_type pbackfail(int_type c = CharTraits::eof()) BOOST_OVERRIDE
0126 {
0127 if(this->gptr() != this->eback()) {
0128 if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
0129 if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) {
0130 this->gbump(-1);
0131 return c;
0132 }
0133 else if(m_mode & std::ios_base::out) {
0134 this->gbump(-1);
0135 *this->gptr() = CharTraits::to_char_type(c);
0136 return c;
0137 }
0138 else
0139 return CharTraits::eof();
0140 }
0141 else {
0142 this->gbump(-1);
0143 return CharTraits::not_eof(c);
0144 }
0145 }
0146 else
0147 return CharTraits::eof();
0148 }
0149
0150 virtual int_type overflow(int_type c = CharTraits::eof()) BOOST_OVERRIDE
0151 {
0152 if(m_mode & std::ios_base::out) {
0153 if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164 if(this->pptr() == this->epptr()) {
0165
0166 return CharTraits::eof();
0167 }
0168 else {
0169 *this->pptr() = CharTraits::to_char_type(c);
0170 this->pbump(1);
0171 return c;
0172 }
0173
0174 }
0175 else
0176 return CharTraits::not_eof(c);
0177 }
0178 else
0179 return CharTraits::eof();
0180 }
0181
0182 virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir,
0183 std::ios_base::openmode mode
0184 = std::ios_base::in | std::ios_base::out) BOOST_OVERRIDE
0185 {
0186 bool in = false;
0187 bool out = false;
0188
0189 const std::ios_base::openmode inout =
0190 std::ios_base::in | std::ios_base::out;
0191
0192 if((mode & inout) == inout) {
0193 if(dir == std::ios_base::beg || dir == std::ios_base::end)
0194 in = out = true;
0195 }
0196 else if(mode & std::ios_base::in)
0197 in = true;
0198 else if(mode & std::ios_base::out)
0199 out = true;
0200
0201 if(!in && !out)
0202 return pos_type(off_type(-1));
0203 else if((in && (!(m_mode & std::ios_base::in) || (off != 0 && this->gptr() == 0) )) ||
0204 (out && (!(m_mode & std::ios_base::out) || (off != 0 && this->pptr() == 0))))
0205 return pos_type(off_type(-1));
0206
0207 std::streamoff newoff;
0208 switch(dir) {
0209 case std::ios_base::beg:
0210 newoff = 0;
0211 break;
0212 case std::ios_base::end:
0213 newoff = static_cast<std::streamoff>(m_length);
0214 break;
0215 case std::ios_base::cur:
0216 newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())
0217 : static_cast<std::streamoff>(this->pptr() - this->pbase());
0218 break;
0219 default:
0220 return pos_type(off_type(-1));
0221 }
0222
0223 off += newoff;
0224
0225 if(in) {
0226 std::ptrdiff_t n = this->egptr() - this->eback();
0227
0228 if(off < 0 || off > n)
0229 return pos_type(off_type(-1));
0230 else
0231 this->setg(this->eback(), this->eback() + off, this->eback() + n);
0232 }
0233
0234 if(out) {
0235 std::ptrdiff_t n = this->epptr() - this->pbase();
0236
0237 if(off < 0 || off > n)
0238 return pos_type(off_type(-1));
0239 else {
0240 this->setp(this->pbase(), this->pbase() + n);
0241 this->pbump(static_cast<int>(off));
0242 }
0243 }
0244
0245 return pos_type(off);
0246 }
0247
0248 virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode
0249 = std::ios_base::in | std::ios_base::out) BOOST_OVERRIDE
0250 { return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode); }
0251
0252 private:
0253 std::ios_base::openmode m_mode;
0254 CharT * m_buffer;
0255 std::size_t m_length;
0256 #endif
0257 };
0258
0259
0260
0261 template <class CharT, class CharTraits>
0262 class basic_ibufferstream :
0263 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0264 private basic_bufferbuf<CharT, CharTraits>,
0265 #endif
0266 public std::basic_istream<CharT, CharTraits>
0267 {
0268 public:
0269 typedef typename std::basic_ios
0270 <CharT, CharTraits>::char_type char_type;
0271 typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
0272 typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
0273 typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
0274 typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
0275
0276 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0277 private:
0278 typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t;
0279 typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
0280 typedef std::basic_istream<char_type, CharTraits> basic_streambuf_t;
0281 bufferbuf_t & get_buf() { return *this; }
0282 const bufferbuf_t & get_buf() const{ return *this; }
0283 #endif
0284
0285 public:
0286
0287
0288 basic_ibufferstream(std::ios_base::openmode mode = std::ios_base::in)
0289 :
0290
0291
0292
0293
0294 bufferbuf_t(mode | std::ios_base::in)
0295 , basic_streambuf_t(this)
0296 {}
0297
0298
0299
0300 basic_ibufferstream(const CharT *buf, std::size_t length,
0301 std::ios_base::openmode mode = std::ios_base::in)
0302 :
0303
0304
0305
0306
0307 bufferbuf_t(const_cast<CharT*>(buf), length, mode | std::ios_base::in)
0308 , basic_streambuf_t(this)
0309 {}
0310
0311 ~basic_ibufferstream(){}
0312
0313 public:
0314
0315
0316 basic_bufferbuf<CharT, CharTraits>* rdbuf() const
0317 { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
0318
0319
0320
0321 std::pair<const CharT *, std::size_t> buffer() const
0322 { return get_buf().buffer(); }
0323
0324
0325
0326 void buffer(const CharT *buf, std::size_t length)
0327 { get_buf().buffer(const_cast<CharT*>(buf), length); }
0328 };
0329
0330
0331
0332 template <class CharT, class CharTraits>
0333 class basic_obufferstream :
0334 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0335 private basic_bufferbuf<CharT, CharTraits>,
0336 #endif
0337 public std::basic_ostream<CharT, CharTraits>
0338 {
0339 public:
0340 typedef typename std::basic_ios
0341 <CharT, CharTraits>::char_type char_type;
0342 typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
0343 typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
0344 typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
0345 typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
0346
0347 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0348 private:
0349 typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t;
0350 typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
0351 typedef std::basic_ostream<char_type, CharTraits> basic_ostream_t;
0352 bufferbuf_t & get_buf() { return *this; }
0353 const bufferbuf_t & get_buf() const{ return *this; }
0354 #endif
0355
0356 public:
0357
0358
0359 basic_obufferstream(std::ios_base::openmode mode = std::ios_base::out)
0360 :
0361
0362
0363
0364
0365 bufferbuf_t(mode | std::ios_base::out)
0366 , basic_ostream_t(this)
0367 {}
0368
0369
0370
0371 basic_obufferstream(CharT *buf, std::size_t length,
0372 std::ios_base::openmode mode = std::ios_base::out)
0373 :
0374
0375
0376
0377
0378 bufferbuf_t(buf, length, mode | std::ios_base::out)
0379 , basic_ostream_t(this)
0380 {}
0381
0382 ~basic_obufferstream(){}
0383
0384 public:
0385
0386
0387 basic_bufferbuf<CharT, CharTraits>* rdbuf() const
0388 { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
0389
0390
0391
0392 std::pair<CharT *, std::size_t> buffer() const
0393 { return get_buf().buffer(); }
0394
0395
0396
0397 void buffer(CharT *buf, std::size_t length)
0398 { get_buf().buffer(buf, length); }
0399 };
0400
0401
0402
0403
0404 template <class CharT, class CharTraits>
0405 class basic_bufferstream :
0406 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0407 private basic_bufferbuf<CharT, CharTraits>,
0408 #endif
0409 public std::basic_iostream<CharT, CharTraits>
0410 {
0411 public:
0412 typedef typename std::basic_ios
0413 <CharT, CharTraits>::char_type char_type;
0414 typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
0415 typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
0416 typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
0417 typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
0418
0419 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0420 private:
0421 typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t;
0422 typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
0423 typedef std::basic_iostream<char_type, CharTraits> basic_iostream_t;
0424 bufferbuf_t & get_buf() { return *this; }
0425 const bufferbuf_t & get_buf() const{ return *this; }
0426 #endif
0427
0428 public:
0429
0430
0431 basic_bufferstream(std::ios_base::openmode mode
0432 = std::ios_base::in | std::ios_base::out)
0433 :
0434
0435
0436
0437
0438 bufferbuf_t(mode)
0439 , basic_iostream_t(this)
0440 {}
0441
0442
0443
0444 basic_bufferstream(CharT *buf, std::size_t length,
0445 std::ios_base::openmode mode
0446 = std::ios_base::in | std::ios_base::out)
0447 :
0448
0449
0450
0451
0452 bufferbuf_t(buf, length, mode)
0453 , basic_iostream_t(this)
0454 {}
0455
0456 ~basic_bufferstream(){}
0457
0458 public:
0459
0460
0461 basic_bufferbuf<CharT, CharTraits>* rdbuf() const
0462 { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
0463
0464
0465
0466 std::pair<CharT *, std::size_t> buffer() const
0467 { return get_buf().buffer(); }
0468
0469
0470
0471 void buffer(CharT *buf, std::size_t length)
0472 { get_buf().buffer(buf, length); }
0473 };
0474
0475
0476 typedef basic_bufferbuf<char> bufferbuf;
0477 typedef basic_bufferstream<char> bufferstream;
0478 typedef basic_ibufferstream<char> ibufferstream;
0479 typedef basic_obufferstream<char> obufferstream;
0480
0481 typedef basic_bufferbuf<wchar_t> wbufferbuf;
0482 typedef basic_bufferstream<wchar_t> wbufferstream;
0483 typedef basic_ibufferstream<wchar_t> wibufferstream;
0484 typedef basic_obufferstream<wchar_t> wobufferstream;
0485
0486
0487 }}
0488
0489 #include <boost/interprocess/detail/config_end.hpp>
0490
0491 #endif