1 | // |
2 | // LineEndingConverter.cpp |
3 | // |
4 | // Library: Foundation |
5 | // Package: Streams |
6 | // Module: LineEndingConverter |
7 | // |
8 | // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. |
9 | // and Contributors. |
10 | // |
11 | // SPDX-License-Identifier: BSL-1.0 |
12 | // |
13 | |
14 | |
15 | #include "Poco/LineEndingConverter.h" |
16 | |
17 | |
18 | namespace Poco { |
19 | |
20 | |
21 | const std::string LineEnding::NEWLINE_DEFAULT(POCO_DEFAULT_NEWLINE_CHARS); |
22 | const std::string LineEnding::NEWLINE_CR("\r" ); |
23 | const std::string LineEnding::NEWLINE_CRLF("\r\n" ); |
24 | const std::string LineEnding::NEWLINE_LF("\n" ); |
25 | |
26 | |
27 | LineEndingConverterStreamBuf::LineEndingConverterStreamBuf(std::istream& istr): |
28 | _pIstr(&istr), |
29 | _pOstr(0), |
30 | _newLine(LineEnding::NEWLINE_DEFAULT), |
31 | _lastChar(0) |
32 | { |
33 | _it = _newLine.end(); |
34 | } |
35 | |
36 | |
37 | LineEndingConverterStreamBuf::LineEndingConverterStreamBuf(std::ostream& ostr): |
38 | _pIstr(0), |
39 | _pOstr(&ostr), |
40 | _newLine(LineEnding::NEWLINE_DEFAULT), |
41 | _lastChar(0) |
42 | { |
43 | _it = _newLine.end(); |
44 | } |
45 | |
46 | |
47 | LineEndingConverterStreamBuf::~LineEndingConverterStreamBuf() |
48 | { |
49 | } |
50 | |
51 | |
52 | void LineEndingConverterStreamBuf::setNewLine(const std::string& newLineCharacters) |
53 | { |
54 | _newLine = newLineCharacters; |
55 | _it = _newLine.end(); |
56 | } |
57 | |
58 | |
59 | const std::string& LineEndingConverterStreamBuf::getNewLine() const |
60 | { |
61 | return _newLine; |
62 | } |
63 | |
64 | |
65 | int LineEndingConverterStreamBuf::readFromDevice() |
66 | { |
67 | poco_assert_dbg (_pIstr); |
68 | |
69 | while (_it == _newLine.end()) |
70 | { |
71 | int c = _pIstr->get(); |
72 | if (c == '\r') |
73 | { |
74 | if (_pIstr->peek() == '\n') _pIstr->get(); |
75 | _it = _newLine.begin(); |
76 | } |
77 | else if (c == '\n') |
78 | { |
79 | _it = _newLine.begin(); |
80 | } |
81 | else return c; |
82 | } |
83 | return *_it++; |
84 | } |
85 | |
86 | |
87 | int LineEndingConverterStreamBuf::writeToDevice(char c) |
88 | { |
89 | poco_assert_dbg (_pOstr); |
90 | |
91 | if (c == '\r' || (c == '\n' && _lastChar != '\r')) |
92 | _pOstr->write(_newLine.data(), (std::streamsize) _newLine.length()); |
93 | if (c != '\n' && c != '\r') |
94 | _pOstr->put(c); |
95 | _lastChar = c; |
96 | return charToInt(c); |
97 | } |
98 | |
99 | |
100 | LineEndingConverterIOS::LineEndingConverterIOS(std::istream& istr): _buf(istr) |
101 | { |
102 | poco_ios_init(&_buf); |
103 | } |
104 | |
105 | |
106 | LineEndingConverterIOS::LineEndingConverterIOS(std::ostream& ostr): _buf(ostr) |
107 | { |
108 | poco_ios_init(&_buf); |
109 | } |
110 | |
111 | |
112 | LineEndingConverterIOS::~LineEndingConverterIOS() |
113 | { |
114 | } |
115 | |
116 | |
117 | void LineEndingConverterIOS::setNewLine(const std::string& newLineCharacters) |
118 | { |
119 | _buf.setNewLine(newLineCharacters); |
120 | } |
121 | |
122 | |
123 | const std::string& LineEndingConverterIOS::getNewLine() const |
124 | { |
125 | return _buf.getNewLine(); |
126 | } |
127 | |
128 | |
129 | LineEndingConverterStreamBuf* LineEndingConverterIOS::rdbuf() |
130 | { |
131 | return &_buf; |
132 | } |
133 | |
134 | |
135 | InputLineEndingConverter::InputLineEndingConverter(std::istream& istr): |
136 | LineEndingConverterIOS(istr), |
137 | std::istream(&_buf) |
138 | { |
139 | } |
140 | |
141 | |
142 | InputLineEndingConverter::InputLineEndingConverter(std::istream& istr, const std::string& newLineCharacters): |
143 | LineEndingConverterIOS(istr), |
144 | std::istream(&_buf) |
145 | { |
146 | setNewLine(newLineCharacters); |
147 | } |
148 | |
149 | |
150 | InputLineEndingConverter::~InputLineEndingConverter() |
151 | { |
152 | } |
153 | |
154 | |
155 | OutputLineEndingConverter::OutputLineEndingConverter(std::ostream& ostr): |
156 | LineEndingConverterIOS(ostr), |
157 | std::ostream(&_buf) |
158 | { |
159 | } |
160 | |
161 | |
162 | OutputLineEndingConverter::OutputLineEndingConverter(std::ostream& ostr, const std::string& newLineCharacters): |
163 | LineEndingConverterIOS(ostr), |
164 | std::ostream(&_buf) |
165 | { |
166 | setNewLine(newLineCharacters); |
167 | } |
168 | |
169 | |
170 | OutputLineEndingConverter::~OutputLineEndingConverter() |
171 | { |
172 | } |
173 | |
174 | |
175 | } // namespace Poco |
176 | |