1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
#include "coding/reader_streambuf.hpp"
#include "coding/reader.hpp"
#include "coding/file_writer.hpp"
#include <algorithm>
using namespace std;
ReaderStreamBuf::ReaderStreamBuf(unique_ptr<Reader> && p)
: m_p(move(p)), m_pos(0), m_size(m_p->Size())
{
}
// Define destructor in .cpp due to using unique_ptr with incomplete type.
ReaderStreamBuf::~ReaderStreamBuf() = default;
streamsize ReaderStreamBuf::xsgetn(char_type * s, streamsize n)
{
streamsize const count = min(n, static_cast<streamsize>(m_size - m_pos));
if (count > 0)
{
m_p->Read(m_pos, s, count);
m_pos += count;
}
return count;
}
ReaderStreamBuf::int_type ReaderStreamBuf::underflow()
{
streamsize s = xsgetn(m_buf, sizeof(m_buf));
if (s > 0)
{
setg(m_buf, m_buf, m_buf + s);
return traits_type::to_int_type(m_buf[0]);
}
else
{
return traits_type::eof();
}
}
WriterStreamBuf::~WriterStreamBuf()
{
delete m_writer;
}
streamsize WriterStreamBuf::xsputn(char_type const * s, streamsize n)
{
m_writer->Write(s, n);
return n;
}
WriterStreamBuf::int_type WriterStreamBuf::overflow(int_type c)
{
if (!traits_type::eq_int_type(c, traits_type::eof()))
{
char_type const t = traits_type::to_char_type(c);
xsputn(&t, 1);
}
return !traits_type::eof();
}
int WriterStreamBuf::sync()
{
FileWriter * p = dynamic_cast<FileWriter *>(m_writer);
if (p)
p->Flush();
return 0;
}
|