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