[134] | 1 | // Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
|
---|
| 2 | // http://chaosforge.org/
|
---|
| 3 | //
|
---|
| 4 | // This file is part of NV Libraries.
|
---|
| 5 | // For conditions of distribution and use, see copyright notice in nv.hh
|
---|
[135] | 6 | //
|
---|
| 7 | // TODO: support for write operations, see http://www.mr-edd.co.uk/blog/beginners_guide_streambuf
|
---|
[134] | 8 |
|
---|
| 9 | #include "nv/io/std_stream.hh"
|
---|
| 10 | #include <algorithm>
|
---|
| 11 |
|
---|
| 12 | using namespace nv;
|
---|
| 13 |
|
---|
[138] | 14 | std_streambuf::std_streambuf( stream* source, bool owner /*= false*/, std::size_t bsize /*= 256*/, std::size_t put_back /*= 8 */ )
|
---|
[134] | 15 | : m_stream( source )
|
---|
| 16 | , m_owner( owner )
|
---|
| 17 | , m_put_back( std::max( put_back, std::size_t( 1 ) ) )
|
---|
| 18 | , m_buffer( std::max(bsize, put_back) + put_back )
|
---|
| 19 | {
|
---|
| 20 | char *end = &m_buffer.front() + m_buffer.size();
|
---|
| 21 | setg( end, end, end );
|
---|
| 22 | }
|
---|
| 23 |
|
---|
[138] | 24 | std_streambuf::~std_streambuf()
|
---|
[134] | 25 | {
|
---|
| 26 | if ( m_owner )
|
---|
| 27 | {
|
---|
| 28 | delete m_stream;
|
---|
| 29 | }
|
---|
| 30 | }
|
---|
| 31 |
|
---|
[138] | 32 | std_streambuf::int_type std_streambuf::underflow()
|
---|
[134] | 33 | {
|
---|
| 34 | if (gptr() < egptr())
|
---|
| 35 | {
|
---|
| 36 | // buffer not exhausted
|
---|
| 37 | return traits_type::to_int_type(*gptr());
|
---|
| 38 | }
|
---|
| 39 |
|
---|
| 40 | char *base = &m_buffer.front();
|
---|
| 41 | char *start = base;
|
---|
| 42 |
|
---|
| 43 | if (eback() == base) // true when this isn't the first fill
|
---|
| 44 | {
|
---|
| 45 | // Make arrangements for putback characters
|
---|
[138] | 46 | std::copy( egptr() - m_put_back, egptr(), base );
|
---|
[134] | 47 | start += m_put_back;
|
---|
| 48 | }
|
---|
| 49 |
|
---|
| 50 | // start is now the start of the buffer, proper.
|
---|
| 51 | size_t n = m_stream->read( start, 1, m_buffer.size() - (start - base) );
|
---|
| 52 | if (n == 0)
|
---|
| 53 | {
|
---|
| 54 | return traits_type::eof();
|
---|
| 55 | }
|
---|
| 56 |
|
---|
| 57 | // Set buffer pointers
|
---|
| 58 | setg(base, start, start + n);
|
---|
| 59 |
|
---|
| 60 | return traits_type::to_int_type(*gptr());
|
---|
| 61 | }
|
---|