1 //
2 // CountingStream.h
3 //
4 // Library: Foundation
5 // Package: Streams
6 // Module:  CountingStream
7 //
8 // Definition of the CountingStreamBuf, CountingInputStream and CountingOutputStream classes.
9 //
10 // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11 // and Contributors.
12 //
13 // SPDX-License-Identifier:	BSL-1.0
14 //
15 
16 
17 #ifndef Foundation_CountingStream_INCLUDED
18 #define Foundation_CountingStream_INCLUDED
19 
20 
21 #include "Poco/Foundation.h"
22 #include "Poco/UnbufferedStreamBuf.h"
23 #include <istream>
24 #include <ostream>
25 
26 
27 namespace Poco {
28 
29 
30 class Foundation_API CountingStreamBuf: public UnbufferedStreamBuf
31 	/// This stream buffer counts all characters and lines
32 	/// going through it.
33 {
34 public:
35 	CountingStreamBuf();
36 		/// Creates an unconnected CountingStreamBuf.
37 
38 	CountingStreamBuf(std::istream& istr);
39 		/// Creates the CountingStreamBuf and connects it
40 		/// to the given input stream.
41 
42 	CountingStreamBuf(std::ostream& ostr);
43 		/// Creates the CountingStreamBuf and connects it
44 		/// to the given output stream.
45 
46 	~CountingStreamBuf();
47 		/// Destroys the CountingStream.
48 
49 	std::streamsize chars() const;
50 		/// Returns the total number of characters.
51 
52 	std::streamsize lines() const;
53 		/// Returns the total number of lines.
54 
55 	std::streamsize pos() const;
56 		/// Returns the number of characters on the current line.
57 
58 	void reset();
59 		/// Resets all counters.
60 
61 	void setCurrentLineNumber(std::streamsize line);
62 		/// Sets the current line number.
63 		///
64 		/// This is mainly useful when parsing C/C++
65 		/// preprocessed source code containing #line directives.
66 
67 	std::streamsize getCurrentLineNumber() const;
68 		/// Returns the current line number (same as lines()).
69 
70 	void addChars(std::streamsize chars);
71 		/// Add to the total number of characters.
72 
73 	void addLines(std::streamsize lines);
74 		/// Add to the total number of lines.
75 
76 	void addPos(std::streamsize pos);
77 		/// Add to the number of characters on the current line.
78 
79 protected:
80 	int readFromDevice();
81 	int writeToDevice(char c);
82 
83 private:
84 	std::istream* _pIstr;
85 	std::ostream* _pOstr;
86 	std::streamsize _chars;
87 	std::streamsize _lines;
88 	std::streamsize _pos;
89 };
90 
91 
92 class Foundation_API CountingIOS: public virtual std::ios
93 	/// The base class for CountingInputStream and CountingOutputStream.
94 	///
95 	/// This class is needed to ensure the correct initialization
96 	/// order of the stream buffer and base classes.
97 {
98 public:
99 	CountingIOS();
100 		/// Creates the basic stream and leaves it unconnected.
101 
102 	CountingIOS(std::istream& istr);
103 		/// Creates the basic stream and connects it
104 		/// to the given input stream.
105 
106 	CountingIOS(std::ostream& ostr);
107 		/// Creates the basic stream and connects it
108 		/// to the given output stream.
109 
110 	~CountingIOS();
111 		/// Destroys the stream.
112 
113 	std::streamsize chars() const;
114 		/// Returns the total number of characters.
115 
116 	std::streamsize lines() const;
117 		/// Returns the total number of lines.
118 
119 	std::streamsize pos() const;
120 		/// Returns the number of characters on the current line.
121 
122 	void reset();
123 		/// Resets all counters.
124 
125 	void setCurrentLineNumber(std::streamsize line);
126 		/// Sets the current line number.
127 		///
128 		/// This is mainly useful when parsing C/C++
129 		/// preprocessed source code containing #line directives.
130 
131 	std::streamsize getCurrentLineNumber() const;
132 		/// Returns the current line number (same as lines()).
133 
134 	void addChars(std::streamsize chars);
135 		/// Add to the total number of characters.
136 
137 	void addLines(std::streamsize lines);
138 		/// Add to the total number of lines.
139 
140 	void addPos(std::streamsize pos);
141 		/// Add to the number of characters on the current line.
142 
143 	CountingStreamBuf* rdbuf();
144 		/// Returns a pointer to the underlying streambuf.
145 
146 protected:
147 	CountingStreamBuf _buf;
148 };
149 
150 
151 class Foundation_API CountingInputStream: public CountingIOS, public std::istream
152 	/// This stream counts all characters and lines
153 	/// going through it. This is useful for lexers and parsers
154 	/// that need to determine the current position in the stream.
155 {
156 public:
157 	CountingInputStream(std::istream& istr);
158 		/// Creates the CountingInputStream and connects it
159 		/// to the given input stream.
160 
161 	~CountingInputStream();
162 		/// Destroys the stream.
163 };
164 
165 
166 class Foundation_API CountingOutputStream: public CountingIOS, public std::ostream
167 	/// This stream counts all characters and lines
168 	/// going through it.
169 {
170 public:
171 	CountingOutputStream();
172 		/// Creates an unconnected CountingOutputStream.
173 
174 	CountingOutputStream(std::ostream& ostr);
175 		/// Creates the CountingOutputStream and connects it
176 		/// to the given output stream.
177 
178 	~CountingOutputStream();
179 		/// Destroys the CountingOutputStream.
180 };
181 
182 
183 //
184 // inlines
185 //
chars()186 inline std::streamsize CountingStreamBuf::chars() const
187 {
188 	return _chars;
189 }
190 
191 
lines()192 inline std::streamsize CountingStreamBuf::lines() const
193 {
194 	return _lines;
195 }
196 
197 
pos()198 inline std::streamsize CountingStreamBuf::pos() const
199 {
200 	return _pos;
201 }
202 
203 
getCurrentLineNumber()204 inline std::streamsize CountingStreamBuf::getCurrentLineNumber() const
205 {
206 	return _lines;
207 }
208 
209 
chars()210 inline std::streamsize CountingIOS::chars() const
211 {
212 	return _buf.chars();
213 }
214 
215 
lines()216 inline std::streamsize CountingIOS::lines() const
217 {
218 	return _buf.lines();
219 }
220 
221 
pos()222 inline std::streamsize CountingIOS::pos() const
223 {
224 	return _buf.pos();
225 }
226 
227 
getCurrentLineNumber()228 inline std::streamsize CountingIOS::getCurrentLineNumber() const
229 {
230 	return _buf.getCurrentLineNumber();
231 }
232 
233 
234 } // namespace Poco
235 
236 
237 #endif // Foundation_CountingStream_INCLUDED
238