1 | // Copyright (C) 2012-2014 ChaosForge Ltd
|
---|
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
|
---|
6 | //
|
---|
7 | // TODO: support for write operations, see http://www.mr-edd.co.uk/blog/beginners_guide_streambuf
|
---|
8 |
|
---|
9 | #include "nv/io/std_stream.hh"
|
---|
10 | #include <algorithm>
|
---|
11 |
|
---|
12 | using namespace nv;
|
---|
13 |
|
---|
14 | std_streambuf::std_streambuf( stream* source, bool owner /*= false*/, std::size_t bsize /*= 256*/, std::size_t put_back /*= 8 */ )
|
---|
15 | : m_stream( source )
|
---|
16 | , m_owner( owner )
|
---|
17 | , m_buffer( std::max(bsize, put_back) + put_back )
|
---|
18 | , m_put_back( std::max( put_back, std::size_t( 1 ) ) )
|
---|
19 | {
|
---|
20 | char *end = &m_buffer.front() + m_buffer.size();
|
---|
21 | setg( end, end, end );
|
---|
22 | }
|
---|
23 |
|
---|
24 | std_streambuf::~std_streambuf()
|
---|
25 | {
|
---|
26 | if ( m_owner )
|
---|
27 | {
|
---|
28 | delete m_stream;
|
---|
29 | }
|
---|
30 | }
|
---|
31 |
|
---|
32 | std_streambuf::int_type std_streambuf::underflow()
|
---|
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
|
---|
46 | std::copy( egptr() - m_put_back, egptr(), base );
|
---|
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() - static_cast<size_t>(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 | }
|
---|