File: StreamCopier.h

package info (click to toggle)
poco 1.14.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 56,460 kB
  • sloc: cpp: 340,542; ansic: 245,601; makefile: 1,742; yacc: 1,005; sh: 698; sql: 312; lex: 282; xml: 128; perl: 29; python: 24
file content (230 lines) | stat: -rw-r--r-- 6,663 bytes parent folder | download
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
//
// StreamCopier.h
//
// Library: Foundation
// Package: Streams
// Module:  StreamCopier
//
// Definition of class StreamCopier.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier:	BSL-1.0
//


#ifndef Foundation_StreamCopier_INCLUDED
#define Foundation_StreamCopier_INCLUDED


#include "Poco/Foundation.h"
#include "Poco/Buffer.h"
#include <istream>
#include <ostream>
#include <cstddef>


namespace Poco {


class Foundation_API StreamCopier
	/// This class provides static methods to copy the contents from one stream
	/// into another.
{
public:
	static std::streamsize copyStream(std::istream& istr, std::ostream& ostr, std::size_t bufferSize = 8192);
		/// Writes all bytes readable from istr to ostr, using an internal buffer.
		///
		/// Returns the number of bytes copied.

#if defined(POCO_HAVE_INT64)
	static Poco::UInt64 copyStream64(std::istream& istr, std::ostream& ostr, std::size_t bufferSize = 8192);
		/// Writes all bytes readable from istr to ostr, using an internal buffer.
		///
		/// Returns the number of bytes copied as a 64-bit unsigned integer.
		///
		/// Note: the only difference to copyStream() is that a 64-bit unsigned
		/// integer is used to count the number of bytes copied.
#endif

	static std::streamsize copyStreamRange(std::istream& istr, std::ostream& ostr, std::streampos rangeStart, std::streamsize rangeLength, std::size_t bufferSize = 8192);
		/// Writes range of bytes readable from istr to ostr, using an internal buffer.
		///
		/// Returns the number of bytes copied.

#if defined(POCO_HAVE_INT64)
	static Poco::UInt64 copyStreamRange64(std::istream& istr, std::ostream& ostr, std::streampos rangeStart, std::streamsize rangeLength, std::size_t bufferSize = 8192);
		/// Writes range of bytes readable from istr to ostr, using an internal buffer.
		///
		/// Returns the number of bytes copied as a 64-bit unsigned integer.
		///
		/// Note: the only difference to copyStreamRange() is that a 64-bit unsigned
		/// integer is used to count the number of bytes copied.
#endif

	static std::streamsize copyStreamUnbuffered(std::istream& istr, std::ostream& ostr);
		/// Writes all bytes readable from istr to ostr.
		///
		/// Returns the number of bytes copied.

#if defined(POCO_HAVE_INT64)
	static Poco::UInt64 copyStreamUnbuffered64(std::istream& istr, std::ostream& ostr);
		/// Writes all bytes readable from istr to ostr.
		///
		/// Returns the number of bytes copied as a 64-bit unsigned integer.
		///
		/// Note: the only difference to copyStreamUnbuffered() is that a 64-bit unsigned
		/// integer is used to count the number of bytes copied.
#endif

static std::streamsize copyStreamRangeUnbuffered(std::istream& istr, std::ostream& ostr, std::streampos rangeStart, std::streamsize rangeLength);
		/// Writes range of bytes readable from istr to ostr.
		///
		/// Returns the number of bytes copied.

#if defined(POCO_HAVE_INT64)
	static Poco::UInt64 copyStreamRangeUnbuffered64(std::istream& istr, std::ostream& ostr, std::streampos rangeStart, std::streamsize rangeLength);
		/// Writes range of bytes readable from istr to ostr.
		///
		/// Returns the number of bytes copied as a 64-bit unsigned integer.
		///
		/// Note: the only difference to copyStreamRangeUnbuffered() is that a 64-bit unsigned
		/// integer is used to count the number of bytes copied.
#endif

	static std::streamsize copyToString(std::istream& istr, std::string& str, std::size_t bufferSize = 8192);
		/// Appends all bytes readable from istr to the given string, using an internal buffer.
		///
		/// Returns the number of bytes copied.

#if defined(POCO_HAVE_INT64)
	static Poco::UInt64 copyToString64(std::istream& istr, std::string& str, std::size_t bufferSize = 8192);
		/// Appends all bytes readable from istr to the given string, using an internal buffer.
		///
		/// Returns the number of bytes copied as a 64-bit unsigned integer.
		///
		/// Note: the only difference to copyToString() is that a 64-bit unsigned
		/// integer is used to count the number of bytes copied.
#endif

private:
	template <typename T>
	static T copyStreamImpl(std::istream& istr, std::ostream& ostr, std::size_t bufferSize)
	{
		poco_assert (bufferSize > 0);

		Buffer<char> buffer(bufferSize);
		T len = 0;
		istr.read(buffer.begin(), bufferSize);
		std::streamsize n = istr.gcount();
		while (n > 0)
		{
			len += n;
			ostr.write(buffer.begin(), n);
			if (istr && ostr)
			{
				istr.read(buffer.begin(), bufferSize);
				n = istr.gcount();
			}
			else n = 0;
		}
		return len;
	}

	template <typename T>
	static T copyStreamRangeImpl(std::istream& istr, std::ostream& ostr, std::streampos rangeStart, std::streamsize rangeLength, std::size_t bufferSize)
	{
		poco_assert (bufferSize > 0);

		if (bufferSize > static_cast<std::size_t>(rangeLength))
			bufferSize = rangeLength;

		Buffer<char> buffer(bufferSize);
		T len = 0;
		if (istr)
		{
			istr.seekg(rangeStart, std::ios_base::beg);
			istr.read(buffer.begin(), bufferSize);
			std::streamsize n = istr.gcount();
			while (n > 0)
			{
				len += n;
				ostr.write(buffer.begin(), n);
				if ((len < rangeLength) && istr && ostr)
				{
					const std::size_t inputLen = rangeLength - len;
					if (bufferSize > inputLen)
						bufferSize = inputLen;
					istr.read(buffer.begin(), bufferSize);
					n = istr.gcount();
				}
				else n = 0;
			}
		}
		return len;
	}

	template <typename T>
	static T copyToStringImpl(std::istream& istr, std::string& str, std::size_t bufferSize)
	{
		poco_assert (bufferSize > 0);

		Buffer<char> buffer(bufferSize);
		T len = 0;
		istr.read(buffer.begin(), bufferSize);
		std::streamsize n = istr.gcount();
		while (n > 0)
		{
			len += n;
			str.append(buffer.begin(), static_cast<std::string::size_type>(n));
			if (istr)
			{
				istr.read(buffer.begin(), bufferSize);
				n = istr.gcount();
			}
			else n = 0;
		}
		return len;
	}

	template <typename T>
	static T copyStreamUnbufferedImpl(std::istream& istr, std::ostream& ostr)
	{
		char c = 0;
		T len = 0;
		istr.get(c);
		while (istr && ostr)
		{
			++len;
			ostr.put(c);
			istr.get(c);
		}
		return len;
	}

	template <typename T>
	static T copyStreamRangeUnbufferedImpl(std::istream& istr, std::ostream& ostr, std::streampos rangeStart, std::streamsize rangeLength)
	{
		T len = 0;
		char c = 0;
		if (istr)
		{
			istr.seekg(rangeStart, std::ios_base::beg);
			istr.get(c);
			while (istr && ostr && (static_cast<std::streamsize>(len) < rangeLength))
			{
				ostr.put(c);
				++len;
				istr.get(c);
			}
		}
		return len;
	}
};


} // namespace Poco


#endif // Foundation_StreamCopier_INCLUDED