[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 | #include <cstring> // TODO: remove, see below
|
---|
| 12 |
|
---|
| 13 | using namespace nv;
|
---|
| 14 |
|
---|
| 15 | std_stream::std_stream( stream* source, bool owner /*= false*/, std::size_t bsize /*= 256*/, std::size_t put_back /*= 8 */ )
|
---|
| 16 | : m_stream( source )
|
---|
| 17 | , m_owner( owner )
|
---|
| 18 | , m_put_back( std::max( put_back, std::size_t( 1 ) ) )
|
---|
| 19 | , m_buffer( std::max(bsize, put_back) + put_back )
|
---|
| 20 | {
|
---|
| 21 | char *end = &m_buffer.front() + m_buffer.size();
|
---|
| 22 | setg( end, end, end );
|
---|
| 23 | }
|
---|
| 24 |
|
---|
| 25 | std_stream::~std_stream()
|
---|
| 26 | {
|
---|
| 27 | if ( m_owner )
|
---|
| 28 | {
|
---|
| 29 | delete m_stream;
|
---|
| 30 | }
|
---|
| 31 | }
|
---|
| 32 |
|
---|
| 33 | std_stream::int_type std_stream::underflow()
|
---|
| 34 | {
|
---|
| 35 | if (gptr() < egptr())
|
---|
| 36 | {
|
---|
| 37 | // buffer not exhausted
|
---|
| 38 | return traits_type::to_int_type(*gptr());
|
---|
| 39 | }
|
---|
| 40 |
|
---|
| 41 | char *base = &m_buffer.front();
|
---|
| 42 | char *start = base;
|
---|
| 43 |
|
---|
| 44 | if (eback() == base) // true when this isn't the first fill
|
---|
| 45 | {
|
---|
| 46 | // Make arrangements for putback characters
|
---|
| 47 | // TODO: std::copy( egptr() - m_put_back, egptr(), base ); instead?
|
---|
| 48 | std::memmove(base, egptr() - m_put_back, m_put_back);
|
---|
| 49 | start += m_put_back;
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 | // start is now the start of the buffer, proper.
|
---|
| 53 | size_t n = m_stream->read( start, 1, m_buffer.size() - (start - base) );
|
---|
| 54 | if (n == 0)
|
---|
| 55 | {
|
---|
| 56 | return traits_type::eof();
|
---|
| 57 | }
|
---|
| 58 |
|
---|
| 59 | // Set buffer pointers
|
---|
| 60 | setg(base, start, start + n);
|
---|
| 61 |
|
---|
| 62 | return traits_type::to_int_type(*gptr());
|
---|
| 63 | }
|
---|