-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstreambuf_capitalization_writer.cpp
85 lines (67 loc) · 2.03 KB
/
streambuf_capitalization_writer.cpp
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <cctype>
#include <iostream>
#include <streambuf>
#include <vector>
#include <functional>
#include <cassert>
class capitalization_writer_streambuf : public std::streambuf {
public:
explicit capitalization_writer_streambuf(std::ostream& sink, std::size_t buffer_size=256);
protected:
bool capitalize_and_flush();
private:
int_type overflow(int_type ch) override;
int sync() override;
// copy ctor and assignment not implemented; copying not allowed
capitalization_writer_streambuf(const capitalization_writer_streambuf&);
capitalization_writer_streambuf& operator=(const capitalization_writer_streambuf&);
private:
bool cap_next_;
std::ostream& sink_;
std::vector<char> buffer_;
};
capitalization_writer_streambuf::capitalization_writer_streambuf(std::ostream& sink, std::size_t buffer_size) :
cap_next_(true),
sink_(sink),
buffer_(buffer_size+1)
{
sink_.clear();
char* base = &buffer_.front();
setp(base, base + buffer_.size() - 1);
}
capitalization_writer_streambuf::int_type capitalization_writer_streambuf::overflow(int_type ch)
{
if (sink_ && ch != traits_type::eof()) {
assert(std::less_equal<char*>()(pptr(), epptr()));
*pptr() = char(ch);
pbump(1);
if (capitalize_and_flush())
return ch;
}
return traits_type::eof();
}
int capitalization_writer_streambuf::sync()
{
return capitalize_and_flush() ? 0 : -1;
}
bool capitalization_writer_streambuf::capitalize_and_flush()
{
for (char *p=pbase(), *e=pptr(); p!=e; ++p) {
if (*p == '.') {
cap_next_ = true;
} else if (std::isalpha(*p)) {
if (cap_next_)
*p = char(std::toupper(*p));
cap_next_ = false;
}
}
std::ptrdiff_t n = pptr() - pbase();
pbump(static_cast<int>(-n));
return bool(sink_.write(pbase(), n));
}
int main()
{
capitalization_writer_streambuf cwsb(std::cout);
std::ostream out(&cwsb);
out << "dies ist ein test. ein kurzer satz. noch einer." << std::endl;
}