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