File indexing completed on 2025-01-18 09:38:31
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
0036 #ifndef BOOST_INTERPROCESS_VECTORSTREAM_HPP
0037 #define BOOST_INTERPROCESS_VECTORSTREAM_HPP
0038
0039 #ifndef BOOST_CONFIG_HPP
0040 # include <boost/config.hpp>
0041 #endif
0042 #
0043 #if defined(BOOST_HAS_PRAGMA_ONCE)
0044 # pragma once
0045 #endif
0046
0047 #include <boost/interprocess/detail/config_begin.hpp>
0048 #include <boost/interprocess/detail/workaround.hpp>
0049
0050 #include <iosfwd>
0051 #include <ios>
0052 #include <istream>
0053 #include <ostream>
0054 #include <string> // char traits
0055 #include <cstddef> // ptrdiff_t
0056 #include <boost/interprocess/interprocess_fwd.hpp>
0057 #include <boost/assert.hpp>
0058
0059 namespace boost { namespace interprocess {
0060
0061
0062
0063
0064
0065
0066 template <class CharVector, class CharTraits>
0067 class basic_vectorbuf
0068 : public std::basic_streambuf<typename CharVector::value_type, CharTraits>
0069 {
0070 public:
0071 typedef CharVector vector_type;
0072 typedef typename CharVector::value_type char_type;
0073 typedef typename CharTraits::int_type int_type;
0074 typedef typename CharTraits::pos_type pos_type;
0075 typedef typename CharTraits::off_type off_type;
0076 typedef CharTraits traits_type;
0077
0078 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0079 private:
0080 typedef std::basic_streambuf<char_type, traits_type> base_t;
0081
0082 basic_vectorbuf(const basic_vectorbuf&);
0083 basic_vectorbuf & operator =(const basic_vectorbuf&);
0084 #endif
0085
0086 public:
0087
0088
0089 explicit basic_vectorbuf(std::ios_base::openmode mode
0090 = std::ios_base::in | std::ios_base::out)
0091 : base_t(), m_mode(mode)
0092 { this->initialize_pointers(); }
0093
0094
0095
0096 template<class VectorParameter>
0097 explicit basic_vectorbuf(const VectorParameter ¶m,
0098 std::ios_base::openmode mode
0099 = std::ios_base::in | std::ios_base::out)
0100 : base_t(), m_mode(mode), m_vect(param)
0101 { this->initialize_pointers(); }
0102
0103 public:
0104
0105
0106
0107
0108 void swap_vector(vector_type &vect)
0109 {
0110 if (this->m_mode & std::ios_base::out){
0111
0112
0113 if (mp_high_water < base_t::pptr()){
0114
0115 mp_high_water = base_t::pptr();
0116 }
0117
0118 m_vect.resize(std::size_t(mp_high_water - (m_vect.size() ? &m_vect[0] : 0)));
0119 }
0120
0121 m_vect.swap(vect);
0122 this->initialize_pointers();
0123 }
0124
0125
0126
0127 const vector_type &vector() const
0128 {
0129 if (this->m_mode & std::ios_base::out){
0130 if (mp_high_water < base_t::pptr()){
0131
0132 mp_high_water = base_t::pptr();
0133 }
0134
0135 typedef typename vector_type::size_type size_type;
0136 char_type *old_ptr = base_t::pbase();
0137 size_type high_pos = size_type(mp_high_water-old_ptr);
0138 if(m_vect.size() > high_pos){
0139 m_vect.resize(high_pos);
0140
0141 int old_pos = (int)(base_t::pptr() - base_t::pbase());
0142 const_cast<basic_vectorbuf*>(this)->base_t::setp(old_ptr, old_ptr + high_pos);
0143 const_cast<basic_vectorbuf*>(this)->base_t::pbump(old_pos);
0144 }
0145 }
0146 return m_vect;
0147 }
0148
0149
0150
0151
0152 void reserve(typename vector_type::size_type size)
0153 {
0154 if (this->m_mode & std::ios_base::out && size > m_vect.size()){
0155 typename vector_type::difference_type write_pos = base_t::pptr() - base_t::pbase();
0156 typename vector_type::difference_type read_pos = base_t::gptr() - base_t::eback();
0157
0158 m_vect.reserve(size);
0159 this->initialize_pointers();
0160 base_t::pbump((int)write_pos);
0161 if(this->m_mode & std::ios_base::in){
0162 base_t::gbump((int)read_pos);
0163 }
0164 }
0165 }
0166
0167
0168
0169 void clear()
0170 { m_vect.clear(); this->initialize_pointers(); }
0171
0172 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0173 private:
0174
0175
0176
0177 void initialize_pointers()
0178 {
0179
0180 if(!(m_mode & std::ios_base::out)){
0181 if(m_vect.empty()){
0182 this->setg(0, 0, 0);
0183 }
0184 else{
0185 this->setg(&m_vect[0], &m_vect[0], &m_vect[0] + m_vect.size());
0186 }
0187 }
0188
0189
0190 if(m_mode & std::ios_base::out){
0191
0192 int real_size = (int)m_vect.size();
0193
0194 m_vect.resize(m_vect.capacity());
0195 BOOST_ASSERT(m_vect.size() == m_vect.capacity());
0196
0197 mp_high_water = m_vect.size() ? (&m_vect[0] + real_size) : 0;
0198
0199 if(m_vect.empty()){
0200 this->setp(0, 0);
0201 if(m_mode & std::ios_base::in)
0202 this->setg(0, 0, 0);
0203 }
0204 else{
0205 char_type *p = &m_vect[0];
0206 this->setp(p, p + m_vect.size());
0207 if(m_mode & std::ios_base::in)
0208 this->setg(p, p, p + real_size);
0209 }
0210 if (m_mode & (std::ios_base::app | std::ios_base::ate)){
0211 base_t::pbump((int)real_size);
0212 }
0213 }
0214 }
0215
0216 protected:
0217 virtual int_type underflow() BOOST_OVERRIDE
0218 {
0219 if (base_t::gptr() == 0)
0220 return CharTraits::eof();
0221 if(m_mode & std::ios_base::out){
0222 if (mp_high_water < base_t::pptr())
0223 mp_high_water = base_t::pptr();
0224 if (base_t::egptr() < mp_high_water)
0225 base_t::setg(base_t::eback(), base_t::gptr(), mp_high_water);
0226 }
0227 if (base_t::gptr() < base_t::egptr())
0228 return CharTraits::to_int_type(*base_t::gptr());
0229 return CharTraits::eof();
0230 }
0231
0232 virtual int_type pbackfail(int_type c = CharTraits::eof()) BOOST_OVERRIDE
0233 {
0234 if(this->gptr() != this->eback()) {
0235 if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
0236 if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) {
0237 this->gbump(-1);
0238 return c;
0239 }
0240 else if(m_mode & std::ios_base::out) {
0241 this->gbump(-1);
0242 *this->gptr() = CharTraits::to_char_type(c);
0243 return c;
0244 }
0245 else
0246 return CharTraits::eof();
0247 }
0248 else {
0249 this->gbump(-1);
0250 return CharTraits::not_eof(c);
0251 }
0252 }
0253 else
0254 return CharTraits::eof();
0255 }
0256
0257 virtual int_type overflow(int_type c = CharTraits::eof()) BOOST_OVERRIDE
0258 {
0259 if(m_mode & std::ios_base::out) {
0260 if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
0261 typedef typename vector_type::difference_type dif_t;
0262
0263
0264 dif_t new_outpos = base_t::pptr() - base_t::pbase() + 1;
0265
0266 dif_t hipos = mp_high_water - base_t::pbase();
0267 if (hipos < new_outpos)
0268 hipos = new_outpos;
0269
0270 m_vect.push_back(CharTraits::to_char_type(c));
0271 m_vect.resize(m_vect.capacity());
0272 BOOST_ASSERT(m_vect.size() == m_vect.capacity());
0273 char_type* p = const_cast<char_type*>(&m_vect[0]);
0274
0275 base_t::setp(p, p + (dif_t)m_vect.size());
0276 mp_high_water = p + hipos;
0277 if (m_mode & std::ios_base::in)
0278 base_t::setg(p, p + (base_t::gptr() - base_t::eback()), mp_high_water);
0279
0280 base_t::pbump((int)new_outpos);
0281 return c;
0282 }
0283 else
0284 return CharTraits::not_eof(c);
0285 }
0286 else
0287 return CharTraits::eof();
0288 }
0289
0290 virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir,
0291 std::ios_base::openmode mode
0292 = std::ios_base::in | std::ios_base::out) BOOST_OVERRIDE
0293 {
0294
0295 bool in(0 != (mode & std::ios_base::in)), out(0 != (mode & std::ios_base::out));
0296
0297 if(!in & !out)
0298 return pos_type(off_type(-1));
0299 else if((in && out) && (dir == std::ios_base::cur))
0300 return pos_type(off_type(-1));
0301 else if((in && (!(m_mode & std::ios_base::in) || (off != 0 && this->gptr() == 0) )) ||
0302 (out && (!(m_mode & std::ios_base::out) || (off != 0 && this->pptr() == 0))))
0303 return pos_type(off_type(-1));
0304
0305 off_type newoff;
0306
0307
0308
0309 off_type limit;
0310 if(m_mode & std::ios_base::out){
0311
0312
0313 if(mp_high_water < base_t::pptr())
0314 mp_high_water = base_t::pptr();
0315
0316 if(m_mode & std::ios_base::in){
0317 if (base_t::egptr() < mp_high_water)
0318 base_t::setg(base_t::eback(), base_t::gptr(), mp_high_water);
0319 }
0320 limit = static_cast<off_type>(mp_high_water - base_t::pbase());
0321 }
0322 else{
0323 limit = static_cast<off_type>(m_vect.size());
0324 }
0325
0326 switch(dir) {
0327 case std::ios_base::beg:
0328 newoff = 0;
0329 break;
0330 case std::ios_base::end:
0331 newoff = limit;
0332 break;
0333 case std::ios_base::cur:
0334 newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())
0335 : static_cast<std::streamoff>(this->pptr() - this->pbase());
0336 break;
0337 default:
0338 return pos_type(off_type(-1));
0339 }
0340
0341 newoff += off;
0342
0343 if (newoff < 0 || newoff > limit)
0344 return pos_type(-1);
0345 if (m_mode & std::ios_base::app && mode & std::ios_base::out && newoff != limit)
0346 return pos_type(-1);
0347
0348
0349
0350 if (in)
0351 base_t::setg(base_t::eback(), base_t::eback() + newoff, base_t::egptr());
0352 if (out){
0353 base_t::setp(base_t::pbase(), base_t::epptr());
0354 base_t::pbump(static_cast<int>(newoff));
0355 }
0356 return pos_type(newoff);
0357 }
0358
0359 virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode
0360 = std::ios_base::in | std::ios_base::out) BOOST_OVERRIDE
0361 { return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode); }
0362
0363 private:
0364 std::ios_base::openmode m_mode;
0365 mutable vector_type m_vect;
0366 mutable char_type* mp_high_water;
0367 #endif
0368 };
0369
0370
0371
0372
0373
0374 template <class CharVector, class CharTraits>
0375 class basic_ivectorstream
0376 : public std::basic_istream<typename CharVector::value_type, CharTraits>
0377 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0378 , private basic_vectorbuf<CharVector, CharTraits>
0379 #endif
0380 {
0381 public:
0382 typedef CharVector vector_type;
0383 typedef typename std::basic_ios
0384 <typename CharVector::value_type, CharTraits>::char_type char_type;
0385 typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
0386 typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
0387 typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
0388 typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
0389
0390 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0391 private:
0392 typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t;
0393 typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
0394 typedef std::basic_istream<char_type, CharTraits> base_t;
0395
0396 vectorbuf_t & get_buf() { return *this; }
0397 const vectorbuf_t & get_buf() const{ return *this; }
0398 #endif
0399
0400 public:
0401
0402
0403
0404 basic_ivectorstream(std::ios_base::openmode mode = std::ios_base::in)
0405 : base_t(0)
0406
0407
0408 , vectorbuf_t(mode | std::ios_base::in)
0409 { this->base_t::rdbuf(&get_buf()); }
0410
0411
0412
0413 template<class VectorParameter>
0414 basic_ivectorstream(const VectorParameter ¶m,
0415 std::ios_base::openmode mode = std::ios_base::in)
0416 : vectorbuf_t(param, mode | std::ios_base::in)
0417
0418
0419 , base_t(&get_buf())
0420 {}
0421
0422 public:
0423
0424
0425 basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
0426 { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); }
0427
0428
0429
0430
0431 void swap_vector(vector_type &vect)
0432 { get_buf().swap_vector(vect); }
0433
0434
0435
0436 const vector_type &vector() const
0437 { return get_buf().vector(); }
0438
0439
0440
0441
0442 void reserve(typename vector_type::size_type size)
0443 { get_buf().reserve(size); }
0444
0445
0446
0447 void clear()
0448 { get_buf().clear(); }
0449 };
0450
0451
0452
0453
0454
0455 template <class CharVector, class CharTraits>
0456 class basic_ovectorstream
0457 : public std::basic_ostream<typename CharVector::value_type, CharTraits>
0458 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0459 , private basic_vectorbuf<CharVector, CharTraits>
0460 #endif
0461 {
0462 public:
0463 typedef CharVector vector_type;
0464 typedef typename std::basic_ios
0465 <typename CharVector::value_type, CharTraits>::char_type char_type;
0466 typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
0467 typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
0468 typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
0469 typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
0470
0471 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0472 private:
0473 typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t;
0474 typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
0475 typedef std::basic_ostream<char_type, CharTraits> base_t;
0476
0477 vectorbuf_t & get_buf() { return *this; }
0478 const vectorbuf_t & get_buf()const { return *this; }
0479 #endif
0480
0481 public:
0482
0483
0484 basic_ovectorstream(std::ios_base::openmode mode = std::ios_base::out)
0485 : base_t(0)
0486
0487
0488 , vectorbuf_t(mode | std::ios_base::out)
0489 { this->base_t::rdbuf(&get_buf()); }
0490
0491
0492
0493 template<class VectorParameter>
0494 basic_ovectorstream(const VectorParameter ¶m,
0495 std::ios_base::openmode mode = std::ios_base::out)
0496 : base_t(0)
0497
0498
0499 , vectorbuf_t(param, mode | std::ios_base::out)
0500 { this->base_t::rdbuf(&get_buf()); }
0501
0502 public:
0503
0504
0505 basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
0506 { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); }
0507
0508
0509
0510
0511 void swap_vector(vector_type &vect)
0512 { get_buf().swap_vector(vect); }
0513
0514
0515
0516 const vector_type &vector() const
0517 { return get_buf().vector(); }
0518
0519
0520
0521
0522 void reserve(typename vector_type::size_type size)
0523 { get_buf().reserve(size); }
0524 };
0525
0526
0527
0528
0529
0530 template <class CharVector, class CharTraits>
0531 class basic_vectorstream
0532 : public std::basic_iostream<typename CharVector::value_type, CharTraits>
0533 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0534 , private basic_vectorbuf<CharVector, CharTraits>
0535 #endif
0536 {
0537 public:
0538 typedef CharVector vector_type;
0539 typedef typename std::basic_ios
0540 <typename CharVector::value_type, CharTraits>::char_type char_type;
0541 typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
0542 typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
0543 typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
0544 typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
0545
0546 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0547 private:
0548 typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t;
0549 typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
0550 typedef std::basic_iostream<char_type, CharTraits> base_t;
0551
0552 vectorbuf_t & get_buf() { return *this; }
0553 const vectorbuf_t & get_buf() const{ return *this; }
0554 #endif
0555
0556 public:
0557
0558
0559 basic_vectorstream(std::ios_base::openmode mode
0560 = std::ios_base::in | std::ios_base::out)
0561 : base_t(0)
0562
0563
0564 , vectorbuf_t(mode)
0565 { this->base_t::rdbuf(&get_buf()); }
0566
0567
0568
0569 template<class VectorParameter>
0570 basic_vectorstream(const VectorParameter ¶m, std::ios_base::openmode mode
0571 = std::ios_base::in | std::ios_base::out)
0572 : base_t(0)
0573
0574
0575 , vectorbuf_t(param, mode)
0576 { this->base_t::rdbuf(&get_buf()); }
0577
0578 public:
0579
0580 basic_vectorbuf<CharVector, CharTraits>* rdbuf() const
0581 { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); }
0582
0583
0584
0585
0586 void swap_vector(vector_type &vect)
0587 { get_buf().swap_vector(vect); }
0588
0589
0590
0591 const vector_type &vector() const
0592 { return get_buf().vector(); }
0593
0594
0595
0596
0597 void reserve(typename vector_type::size_type size)
0598 { get_buf().reserve(size); }
0599
0600
0601
0602 void clear()
0603 { get_buf().clear(); }
0604 };
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618 }}
0619
0620 #include <boost/interprocess/detail/config_end.hpp>
0621
0622 #endif