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
18namespace Poco {
19
20
21const std::string LineEnding::NEWLINE_DEFAULT(POCO_DEFAULT_NEWLINE_CHARS);
22const std::string LineEnding::NEWLINE_CR("\r");
23const std::string LineEnding::NEWLINE_CRLF("\r\n");
24const std::string LineEnding::NEWLINE_LF("\n");
25
26
27LineEndingConverterStreamBuf::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
37LineEndingConverterStreamBuf::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
47LineEndingConverterStreamBuf::~LineEndingConverterStreamBuf()
48{
49}
50
51
52void LineEndingConverterStreamBuf::setNewLine(const std::string& newLineCharacters)
53{
54 _newLine = newLineCharacters;
55 _it = _newLine.end();
56}
57
58
59const std::string& LineEndingConverterStreamBuf::getNewLine() const
60{
61 return _newLine;
62}
63
64
65int 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
87int 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
100LineEndingConverterIOS::LineEndingConverterIOS(std::istream& istr): _buf(istr)
101{
102 poco_ios_init(&_buf);
103}
104
105
106LineEndingConverterIOS::LineEndingConverterIOS(std::ostream& ostr): _buf(ostr)
107{
108 poco_ios_init(&_buf);
109}
110
111
112LineEndingConverterIOS::~LineEndingConverterIOS()
113{
114}
115
116
117void LineEndingConverterIOS::setNewLine(const std::string& newLineCharacters)
118{
119 _buf.setNewLine(newLineCharacters);
120}
121
122
123const std::string& LineEndingConverterIOS::getNewLine() const
124{
125 return _buf.getNewLine();
126}
127
128
129LineEndingConverterStreamBuf* LineEndingConverterIOS::rdbuf()
130{
131 return &_buf;
132}
133
134
135InputLineEndingConverter::InputLineEndingConverter(std::istream& istr):
136 LineEndingConverterIOS(istr),
137 std::istream(&_buf)
138{
139}
140
141
142InputLineEndingConverter::InputLineEndingConverter(std::istream& istr, const std::string& newLineCharacters):
143 LineEndingConverterIOS(istr),
144 std::istream(&_buf)
145{
146 setNewLine(newLineCharacters);
147}
148
149
150InputLineEndingConverter::~InputLineEndingConverter()
151{
152}
153
154
155OutputLineEndingConverter::OutputLineEndingConverter(std::ostream& ostr):
156 LineEndingConverterIOS(ostr),
157 std::ostream(&_buf)
158{
159}
160
161
162OutputLineEndingConverter::OutputLineEndingConverter(std::ostream& ostr, const std::string& newLineCharacters):
163 LineEndingConverterIOS(ostr),
164 std::ostream(&_buf)
165{
166 setNewLine(newLineCharacters);
167}
168
169
170OutputLineEndingConverter::~OutputLineEndingConverter()
171{
172}
173
174
175} // namespace Poco
176