32 m_current(m_vectors.begin()) ,
33 m_end(m_vectors.end()) ,
34 m_size(imagebuffer::size_of(m_vectors))
36 if( m_current != m_end )
37 setg_imp( cbuf_head() , cbuf_head() , cbuf_tail() ) ;
46 if( m_vectors.empty() || m_current == m_end )
49 if( gptr() == egptr() )
52 setg_imp( cbuf_head() , cbuf_head() , cbuf_tail() ) ;
55 return m_current == m_end ? EOF :
static_cast<int>(
static_cast<unsigned char>(*gptr())) ;
58 const char * Gr::imp::vectors_streambuf::cbuf_head()
const
60 return m_current == m_vectors.end() ?
nullptr : &(*m_current)[0] ;
63 const char * Gr::imp::vectors_streambuf::cbuf_tail()
const
65 return m_current == m_vectors.end() ?
nullptr : ( &(*m_current)[0] + (*m_current).size() ) ;
68 size_t Gr::imp::vectors_streambuf::cbuf_available()
const
70 return cbuf_available( gptr() ) ;
73 size_t Gr::imp::vectors_streambuf::cbuf_available(
const char * g )
const
75 G_ASSERT( g ==
nullptr || ( g >= cbuf_head() && g <= cbuf_tail() ) ) ;
76 return ( g >= cbuf_head() && g < cbuf_tail() ) ? (cbuf_tail()-g) : 0U ;
79 size_t Gr::imp::vectors_streambuf::cbuf_offset(
const char * g )
const
81 G_ASSERT( g ==
nullptr || ( g >= cbuf_head() && g <= cbuf_tail() ) ) ;
82 return ( g >= cbuf_head() && g < cbuf_tail() ) ? (g-cbuf_head()) : 0U ;
85 size_t Gr::imp::vectors_streambuf::cbuf_offset()
const
87 return cbuf_offset( gptr() ) ;
90 bool Gr::imp::vectors_streambuf::next_buf()
92 for( ++m_current ; m_current != m_end && (*m_current).empty() ; )
94 return m_current != m_end ;
101 return std::streambuf::xsgetn( p , n ) ;
104 G_ASSERT( gptr() >= cbuf_head() && gptr() <= cbuf_tail() ) ;
106 const char * g = gptr() ;
107 if( n > 0 && g == cbuf_tail() )
113 std::streamsize rc = 0U ;
115 size_t co = cbuf_offset( g ) ;
116 size_t a = cbuf_available( g ) ;
118 while( n > 0 && a > 0 )
120 x = std::min( static_cast<size_t>(n) , a ) ;
121 std::memcpy( p , g , x ) ;
128 if( !next_buf() ) break ;
129 g = &(*m_current)[0] ;
130 a = (*m_current).size() ;
136 G_ASSERT( m_current == m_end ) ;
137 setg_imp(
nullptr ,
nullptr ,
nullptr ) ;
141 G_ASSERT( m_current != m_end ) ;
142 G_ASSERT( (x+co) <= (*m_current).size() ) ;
143 setg_imp( cbuf_head() , cbuf_head()+co+x , cbuf_tail() ) ;
149 void Gr::imp::vectors_streambuf::setg_imp(
const char * start ,
const char *
get ,
const char * end )
151 setg( const_cast<char*>(start) , const_cast<char*>(
get) , const_cast<char*>(end) ) ;
156 return seekoff( pos , std::ios_base::beg , which ) ;
161 if( which == std::ios_base::in )
163 if( way == std::ios_base::beg && off >= 0 )
167 else if( way == std::ios_base::end && off <= 0 && -off <= m_size )
169 return seek( m_size + off ) ;
171 else if( way == std::ios_base::cur )
173 return seek( pos() + off ) ;
179 std::streampos Gr::imp::vectors_streambuf::pos()
const
181 std::streampos n = 0 ;
182 for( Vectors::const_iterator p = m_vectors.begin() ; p != m_current && p != m_vectors.end() ; ++p )
186 return n + gptr() - eback() ;
189 std::streampos Gr::imp::vectors_streambuf::seek( std::streamoff off )
197 setg_imp(
nullptr ,
nullptr ,
nullptr ) ;
206 Vectors::const_iterator p = m_vectors.begin() ;
207 for( ; p != m_end && off >=
static_cast<std::streamoff
>((*p).size()) ; ++p )
213 setg_imp(
nullptr ,
nullptr ,
nullptr ) ;
219 G_ASSERT(
size_t(off) < (*m_current).size() ) ;
220 setg_imp( cbuf_head() , cbuf_head()+off , cbuf_tail() ) ;
230 template <
typename T>
231 size_t to_sizet( T n ,
bool do_throw =
true ,
size_t default_ = 0U )
236 size_t s =
static_cast<size_t>(n) ;
238 bool failed = false ;
242 const size_t top_bit = size_t(1U) << (
sizeof(size_t)*8-1) ;
243 if( (s+1U) & top_bit )
246 if(
sizeof(T) >
sizeof(n) )
248 const T nn =
static_cast<T
>(s) ;
256 throw std::runtime_error(
"numeric overflow" ) ;
265 std::istream & operator>>( std::istream & stream ,
Gr::Vectors & vectors )
267 size_t buffer_size =
static_cast<size_t>( G::limits::file_buffer ) ;
269 buffer_size =
size_t(10U) ;
272 size_t stream_size = 0U ;
273 if( vectors.empty() )
275 std::streampos pos = stream.tellg() ;
278 stream.seekg( 0 , std::ios_base::end ) ;
279 std::streampos endpos = stream.tellg() ;
280 if( endpos >= 0 && endpos > pos )
282 std::streamoff diff = endpos - pos ;
283 stream_size = to_sizet( diff ,
false ) ;
285 stream.seekg( pos ) ;
286 if( stream.tellg() != pos )
287 throw std::runtime_error(
"Gr::Vectors::operator>>: stream repositioning error" ) ;
292 if( stream_size > 0U )
294 const size_t reservation = (stream_size+buffer_size-1U) / buffer_size ;
295 const size_t sanity = 100000U ;
296 if( reservation < sanity )
297 vectors.reserve( std::min(vectors.max_size(),reservation) ) ;
304 G_ASSERT( (stream_size+1U) != 0U ) ;
306 size_t n = stream_size ;
307 bool over_n = false ;
308 for( ; stream.good() ; i++ )
310 if( i >= vectors.size() )
312 vectors.push_back( std::vector<char>() ) ;
313 std::vector<char> & buffer = vectors.back() ;
314 if( n > 0U && !over_n )
315 buffer.resize( std::min(buffer_size,n+1U) ) ;
317 buffer.resize( buffer_size ) ;
320 if( !vectors[i].empty() )
322 stream.read( &(vectors[i])[0] , vectors[i].size() ) ;
323 std::streamsize stream_gcount = stream.gcount() ;
324 if( stream_gcount <= 0 )
327 size_t gcount = to_sizet( stream_gcount ) ;
328 vectors[i].resize( gcount ) ;
331 n = 0U , over_n = true ;
336 vectors.resize( i ) ;
340 if( stream.eof() && stream.fail() && !stream.bad() )
341 stream.clear( std::ios_base::eofbit ) ;
346 std::ostream & operator<<( std::ostream & stream ,
const Gr::Vectors & vectors )
348 Gr::Vectors::const_iterator
const end = vectors.end() ;
349 for( Gr::Vectors::const_iterator p = vectors.begin() ; p != end ; ++p )
350 stream.write( &(*p)[0] , (*p).size() ) ;
std::vector< std::vector< char > > Vectors
A candidate for Gr::ImageBuffer that uses nested std::vectors.
virtual std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which) override
Override from std::streambuf.
virtual std::streampos seekpos(std::streampos pos, std::ios_base::openmode which) override
Override from std::streambuf.
static bool enabled()
Returns true if test features are enabled.
virtual std::streamsize xsgetn(char *s, std::streamsize n) override
Override from std::streambuf.
virtual int underflow() override
Override from std::streambuf.
virtual ~vectors_streambuf()
Destructor.
vectors_streambuf(const Vectors &)
Constructor.