Skip to content

Commit

Permalink
Merge pull request #191 from grrtrr/issue_190
Browse files Browse the repository at this point in the history
vectorstream: support file sizes larger than INT_MAX
  • Loading branch information
igaztanaga authored Jul 6, 2024
2 parents 4a1f284 + 12ecde4 commit 480bd01
Showing 1 changed file with 21 additions and 10 deletions.
31 changes: 21 additions & 10 deletions include/boost/interprocess/streams/vectorstream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include <istream>
#include <ostream>
#include <string> // char traits
#include <climits> // INT_MAX
#include <cstddef> // ptrdiff_t
#include <boost/interprocess/interprocess_fwd.hpp>
#include <boost/assert.hpp>
Expand Down Expand Up @@ -138,9 +139,9 @@ class basic_vectorbuf
if(m_vect.size() > high_pos){
m_vect.resize(high_pos);
//But we must update end write pointer because vector size is now shorter
int old_pos = (int)(base_t::pptr() - base_t::pbase());
off_type old_pos = base_t::pptr() - base_t::pbase();
const_cast<basic_vectorbuf*>(this)->base_t::setp(old_ptr, old_ptr + high_pos);
const_cast<basic_vectorbuf*>(this)->base_t::pbump(old_pos);
const_cast<basic_vectorbuf*>(this)->pbump(old_pos);
}
}
return m_vect;
Expand All @@ -152,14 +153,14 @@ class basic_vectorbuf
void reserve(typename vector_type::size_type size)
{
if (this->m_mode & std::ios_base::out && size > m_vect.size()){
typename vector_type::difference_type write_pos = base_t::pptr() - base_t::pbase();
typename vector_type::difference_type read_pos = base_t::gptr() - base_t::eback();
off_type write_pos = base_t::pptr() - base_t::pbase();
off_type read_pos = base_t::gptr() - base_t::eback();
//Now update pointer data
m_vect.reserve(size);
this->initialize_pointers();
base_t::pbump((int)write_pos);
this->pbump(write_pos);
if(this->m_mode & std::ios_base::in){
base_t::gbump((int)read_pos);
base_t::setg(base_t::eback(), base_t::eback() + read_pos, base_t::egptr());
}
}
}
Expand Down Expand Up @@ -189,7 +190,7 @@ class basic_vectorbuf
// The initial write position is the beginning of the vector.
if(m_mode & std::ios_base::out){
//First get real size
int real_size = (int)m_vect.size();
off_type real_size = m_vect.size();
//Then maximize size for high watermarking
m_vect.resize(m_vect.capacity());
BOOST_ASSERT(m_vect.size() == m_vect.capacity());
Expand All @@ -208,11 +209,21 @@ class basic_vectorbuf
this->setg(p, p, p + real_size);
}
if (m_mode & (std::ios_base::app | std::ios_base::ate)){
base_t::pbump((int)real_size);
this->pbump(real_size);
}
}
}

// LWG255-inspired variant of base_t::pbump that takes a streamoff instead of an int.
void pbump(off_type delta) {
if (delta > INT_MAX) {
for (off_type d = delta / INT_MAX; d > 0; d--)
base_t::pbump(INT_MAX);
delta %= INT_MAX;
}
base_t::pbump((int)delta);
}

protected:
virtual int_type underflow() BOOST_OVERRIDE
{
Expand Down Expand Up @@ -277,7 +288,7 @@ class basic_vectorbuf
if (m_mode & std::ios_base::in)
base_t::setg(p, p + (base_t::gptr() - base_t::eback()), mp_high_water);
//Update write position to the old position + 1
base_t::pbump((int)new_outpos);
this->pbump((off_type)new_outpos);
return c;
}
else // c is EOF, so we don't have to do anything
Expand Down Expand Up @@ -351,7 +362,7 @@ class basic_vectorbuf
base_t::setg(base_t::eback(), base_t::eback() + newoff, base_t::egptr());
if (out){
base_t::setp(base_t::pbase(), base_t::epptr());
base_t::pbump(static_cast<int>(newoff));
this->pbump(newoff);
}
return pos_type(newoff);
}
Expand Down

0 comments on commit 480bd01

Please sign in to comment.