// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz // http://chaosforge.org/ // // This file is part of NV Libraries. // For conditions of distribution and use, see copyright notice in nv.hh #include "nv/io/std_stream.hh" #include #include // TODO: remove, see below using namespace nv; std_stream::std_stream( stream* source, bool owner /*= false*/, std::size_t bsize /*= 256*/, std::size_t put_back /*= 8 */ ) : m_stream( source ) , m_owner( owner ) , m_put_back( std::max( put_back, std::size_t( 1 ) ) ) , m_buffer( std::max(bsize, put_back) + put_back ) { char *end = &m_buffer.front() + m_buffer.size(); setg( end, end, end ); } std_stream::~std_stream() { if ( m_owner ) { delete m_stream; } } std_stream::int_type std_stream::underflow() { if (gptr() < egptr()) { // buffer not exhausted return traits_type::to_int_type(*gptr()); } char *base = &m_buffer.front(); char *start = base; if (eback() == base) // true when this isn't the first fill { // Make arrangements for putback characters // TODO: std::copy( egptr() - m_put_back, egptr(), base ); instead? std::memmove(base, egptr() - m_put_back, m_put_back); start += m_put_back; } // start is now the start of the buffer, proper. size_t n = m_stream->read( start, 1, m_buffer.size() - (start - base) ); if (n == 0) { return traits_type::eof(); } // Set buffer pointers setg(base, start, start + n); return traits_type::to_int_type(*gptr()); }