/src/poco/Foundation/include/Poco/StreamCopier.h
Line | Count | Source (jump to first uncovered line) |
1 | | // |
2 | | // StreamCopier.h |
3 | | // |
4 | | // Library: Foundation |
5 | | // Package: Streams |
6 | | // Module: StreamCopier |
7 | | // |
8 | | // Definition of class StreamCopier. |
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_StreamCopier_INCLUDED |
18 | | #define Foundation_StreamCopier_INCLUDED |
19 | | |
20 | | |
21 | | #include "Poco/Foundation.h" |
22 | | #include "Poco/Buffer.h" |
23 | | #include <istream> |
24 | | #include <ostream> |
25 | | #include <cstddef> |
26 | | |
27 | | |
28 | | namespace Poco { |
29 | | |
30 | | |
31 | | class Foundation_API StreamCopier |
32 | | /// This class provides static methods to copy the contents from one stream |
33 | | /// into another. |
34 | | { |
35 | | public: |
36 | | static std::streamsize copyStream(std::istream& istr, std::ostream& ostr, std::size_t bufferSize = 8192); |
37 | | /// Writes all bytes readable from istr to ostr, using an internal buffer. |
38 | | /// |
39 | | /// Returns the number of bytes copied. |
40 | | |
41 | | #if defined(POCO_HAVE_INT64) |
42 | | static Poco::UInt64 copyStream64(std::istream& istr, std::ostream& ostr, std::size_t bufferSize = 8192); |
43 | | /// Writes all bytes readable from istr to ostr, using an internal buffer. |
44 | | /// |
45 | | /// Returns the number of bytes copied as a 64-bit unsigned integer. |
46 | | /// |
47 | | /// Note: the only difference to copyStream() is that a 64-bit unsigned |
48 | | /// integer is used to count the number of bytes copied. |
49 | | #endif |
50 | | |
51 | | static std::streamsize copyStreamRange(std::istream& istr, std::ostream& ostr, std::streampos rangeStart, std::streamsize rangeLength, std::size_t bufferSize = 8192); |
52 | | /// Writes range of bytes readable from istr to ostr, using an internal buffer. |
53 | | /// |
54 | | /// Returns the number of bytes copied. |
55 | | |
56 | | #if defined(POCO_HAVE_INT64) |
57 | | static Poco::UInt64 copyStreamRange64(std::istream& istr, std::ostream& ostr, std::streampos rangeStart, std::streamsize rangeLength, std::size_t bufferSize = 8192); |
58 | | /// Writes range of bytes readable from istr to ostr, using an internal buffer. |
59 | | /// |
60 | | /// Returns the number of bytes copied as a 64-bit unsigned integer. |
61 | | /// |
62 | | /// Note: the only difference to copyStreamRange() is that a 64-bit unsigned |
63 | | /// integer is used to count the number of bytes copied. |
64 | | #endif |
65 | | |
66 | | static std::streamsize copyStreamUnbuffered(std::istream& istr, std::ostream& ostr); |
67 | | /// Writes all bytes readable from istr to ostr. |
68 | | /// |
69 | | /// Returns the number of bytes copied. |
70 | | |
71 | | #if defined(POCO_HAVE_INT64) |
72 | | static Poco::UInt64 copyStreamUnbuffered64(std::istream& istr, std::ostream& ostr); |
73 | | /// Writes all bytes readable from istr to ostr. |
74 | | /// |
75 | | /// Returns the number of bytes copied as a 64-bit unsigned integer. |
76 | | /// |
77 | | /// Note: the only difference to copyStreamUnbuffered() is that a 64-bit unsigned |
78 | | /// integer is used to count the number of bytes copied. |
79 | | #endif |
80 | | |
81 | | static std::streamsize copyStreamRangeUnbuffered(std::istream& istr, std::ostream& ostr, std::streampos rangeStart, std::streamsize rangeLength); |
82 | | /// Writes range of bytes readable from istr to ostr. |
83 | | /// |
84 | | /// Returns the number of bytes copied. |
85 | | |
86 | | #if defined(POCO_HAVE_INT64) |
87 | | static Poco::UInt64 copyStreamRangeUnbuffered64(std::istream& istr, std::ostream& ostr, std::streampos rangeStart, std::streamsize rangeLength); |
88 | | /// Writes range of bytes readable from istr to ostr. |
89 | | /// |
90 | | /// Returns the number of bytes copied as a 64-bit unsigned integer. |
91 | | /// |
92 | | /// Note: the only difference to copyStreamRangeUnbuffered() is that a 64-bit unsigned |
93 | | /// integer is used to count the number of bytes copied. |
94 | | #endif |
95 | | |
96 | | static std::streamsize copyToString(std::istream& istr, std::string& str, std::size_t bufferSize = 8192); |
97 | | /// Appends all bytes readable from istr to the given string, using an internal buffer. |
98 | | /// |
99 | | /// Returns the number of bytes copied. |
100 | | |
101 | | #if defined(POCO_HAVE_INT64) |
102 | | static Poco::UInt64 copyToString64(std::istream& istr, std::string& str, std::size_t bufferSize = 8192); |
103 | | /// Appends all bytes readable from istr to the given string, using an internal buffer. |
104 | | /// |
105 | | /// Returns the number of bytes copied as a 64-bit unsigned integer. |
106 | | /// |
107 | | /// Note: the only difference to copyToString() is that a 64-bit unsigned |
108 | | /// integer is used to count the number of bytes copied. |
109 | | #endif |
110 | | |
111 | | private: |
112 | | template <typename T> |
113 | | static T copyStreamImpl(std::istream& istr, std::ostream& ostr, std::size_t bufferSize) |
114 | 118k | { |
115 | 118k | poco_assert (bufferSize > 0); |
116 | | |
117 | 118k | Buffer<char> buffer(bufferSize); |
118 | 118k | T len = 0; |
119 | 118k | istr.read(buffer.begin(), bufferSize); |
120 | 118k | std::streamsize n = istr.gcount(); |
121 | 128k | while (n > 0) |
122 | 9.57k | { |
123 | 9.57k | len += n; |
124 | 9.57k | ostr.write(buffer.begin(), n); |
125 | 9.57k | if (istr && ostr) |
126 | 2.36k | { |
127 | 2.36k | istr.read(buffer.begin(), bufferSize); |
128 | 2.36k | n = istr.gcount(); |
129 | 2.36k | } |
130 | 7.20k | else n = 0; |
131 | 9.57k | } |
132 | 118k | return len; |
133 | 118k | } long Poco::StreamCopier::copyStreamImpl<long>(std::__1::basic_istream<char, std::__1::char_traits<char> >&, std::__1::basic_ostream<char, std::__1::char_traits<char> >&, unsigned long) Line | Count | Source | 114 | 118k | { | 115 | 118k | poco_assert (bufferSize > 0); | 116 | | | 117 | 118k | Buffer<char> buffer(bufferSize); | 118 | 118k | T len = 0; | 119 | 118k | istr.read(buffer.begin(), bufferSize); | 120 | 118k | std::streamsize n = istr.gcount(); | 121 | 128k | while (n > 0) | 122 | 9.57k | { | 123 | 9.57k | len += n; | 124 | 9.57k | ostr.write(buffer.begin(), n); | 125 | 9.57k | if (istr && ostr) | 126 | 2.36k | { | 127 | 2.36k | istr.read(buffer.begin(), bufferSize); | 128 | 2.36k | n = istr.gcount(); | 129 | 2.36k | } | 130 | 7.20k | else n = 0; | 131 | 9.57k | } | 132 | 118k | return len; | 133 | 118k | } |
Unexecuted instantiation: unsigned long Poco::StreamCopier::copyStreamImpl<unsigned long>(std::__1::basic_istream<char, std::__1::char_traits<char> >&, std::__1::basic_ostream<char, std::__1::char_traits<char> >&, unsigned long) |
134 | | |
135 | | template <typename T> |
136 | | static T copyStreamRangeImpl(std::istream& istr, std::ostream& ostr, std::streampos rangeStart, std::streamsize rangeLength, std::size_t bufferSize) |
137 | 0 | { |
138 | 0 | poco_assert (bufferSize > 0); |
139 | |
|
140 | 0 | if (bufferSize > static_cast<std::size_t>(rangeLength)) |
141 | 0 | bufferSize = rangeLength; |
142 | |
|
143 | 0 | Buffer<char> buffer(bufferSize); |
144 | 0 | T len = 0; |
145 | 0 | if (istr) |
146 | 0 | { |
147 | 0 | istr.seekg(rangeStart, std::ios_base::beg); |
148 | 0 | istr.read(buffer.begin(), bufferSize); |
149 | 0 | std::streamsize n = istr.gcount(); |
150 | 0 | while (n > 0) |
151 | 0 | { |
152 | 0 | len += n; |
153 | 0 | ostr.write(buffer.begin(), n); |
154 | 0 | if ((len < rangeLength) && istr && ostr) |
155 | 0 | { |
156 | 0 | const std::size_t inputLen = rangeLength - len; |
157 | 0 | if (bufferSize > inputLen) |
158 | 0 | bufferSize = inputLen; |
159 | 0 | istr.read(buffer.begin(), bufferSize); |
160 | 0 | n = istr.gcount(); |
161 | 0 | } |
162 | 0 | else n = 0; |
163 | 0 | } |
164 | 0 | } |
165 | 0 | return len; |
166 | 0 | } Unexecuted instantiation: long Poco::StreamCopier::copyStreamRangeImpl<long>(std::__1::basic_istream<char, std::__1::char_traits<char> >&, std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::fpos<__mbstate_t>, long, unsigned long) Unexecuted instantiation: unsigned long Poco::StreamCopier::copyStreamRangeImpl<unsigned long>(std::__1::basic_istream<char, std::__1::char_traits<char> >&, std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::fpos<__mbstate_t>, long, unsigned long) |
167 | | |
168 | | template <typename T> |
169 | | static T copyToStringImpl(std::istream& istr, std::string& str, std::size_t bufferSize) |
170 | 135k | { |
171 | 135k | poco_assert (bufferSize > 0); |
172 | | |
173 | 135k | Buffer<char> buffer(bufferSize); |
174 | 135k | T len = 0; |
175 | 135k | istr.read(buffer.begin(), bufferSize); |
176 | 135k | std::streamsize n = istr.gcount(); |
177 | 145k | while (n > 0) |
178 | 9.40k | { |
179 | 9.40k | len += n; |
180 | 9.40k | str.append(buffer.begin(), static_cast<std::string::size_type>(n)); |
181 | 9.40k | if (istr) |
182 | 2.23k | { |
183 | 2.23k | istr.read(buffer.begin(), bufferSize); |
184 | 2.23k | n = istr.gcount(); |
185 | 2.23k | } |
186 | 7.17k | else n = 0; |
187 | 9.40k | } |
188 | 135k | return len; |
189 | 135k | } long Poco::StreamCopier::copyToStringImpl<long>(std::__1::basic_istream<char, std::__1::char_traits<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned long) Line | Count | Source | 170 | 135k | { | 171 | 135k | poco_assert (bufferSize > 0); | 172 | | | 173 | 135k | Buffer<char> buffer(bufferSize); | 174 | 135k | T len = 0; | 175 | 135k | istr.read(buffer.begin(), bufferSize); | 176 | 135k | std::streamsize n = istr.gcount(); | 177 | 145k | while (n > 0) | 178 | 9.40k | { | 179 | 9.40k | len += n; | 180 | 9.40k | str.append(buffer.begin(), static_cast<std::string::size_type>(n)); | 181 | 9.40k | if (istr) | 182 | 2.23k | { | 183 | 2.23k | istr.read(buffer.begin(), bufferSize); | 184 | 2.23k | n = istr.gcount(); | 185 | 2.23k | } | 186 | 7.17k | else n = 0; | 187 | 9.40k | } | 188 | 135k | return len; | 189 | 135k | } |
Unexecuted instantiation: unsigned long Poco::StreamCopier::copyToStringImpl<unsigned long>(std::__1::basic_istream<char, std::__1::char_traits<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, unsigned long) |
190 | | |
191 | | template <typename T> |
192 | | static T copyStreamUnbufferedImpl(std::istream& istr, std::ostream& ostr) |
193 | 0 | { |
194 | 0 | char c = 0; |
195 | 0 | T len = 0; |
196 | 0 | istr.get(c); |
197 | 0 | while (istr && ostr) |
198 | 0 | { |
199 | 0 | ++len; |
200 | 0 | ostr.put(c); |
201 | 0 | istr.get(c); |
202 | 0 | } |
203 | 0 | return len; |
204 | 0 | } Unexecuted instantiation: long Poco::StreamCopier::copyStreamUnbufferedImpl<long>(std::__1::basic_istream<char, std::__1::char_traits<char> >&, std::__1::basic_ostream<char, std::__1::char_traits<char> >&) Unexecuted instantiation: unsigned long Poco::StreamCopier::copyStreamUnbufferedImpl<unsigned long>(std::__1::basic_istream<char, std::__1::char_traits<char> >&, std::__1::basic_ostream<char, std::__1::char_traits<char> >&) |
205 | | |
206 | | template <typename T> |
207 | | static T copyStreamRangeUnbufferedImpl(std::istream& istr, std::ostream& ostr, std::streampos rangeStart, std::streamsize rangeLength) |
208 | 0 | { |
209 | 0 | T len = 0; |
210 | 0 | char c = 0; |
211 | 0 | if (istr) |
212 | 0 | { |
213 | 0 | istr.seekg(rangeStart, std::ios_base::beg); |
214 | 0 | istr.get(c); |
215 | 0 | while (istr && ostr && (static_cast<std::streamsize>(len) < rangeLength)) |
216 | 0 | { |
217 | 0 | ostr.put(c); |
218 | 0 | ++len; |
219 | 0 | istr.get(c); |
220 | 0 | } |
221 | 0 | } |
222 | 0 | return len; |
223 | 0 | } Unexecuted instantiation: long Poco::StreamCopier::copyStreamRangeUnbufferedImpl<long>(std::__1::basic_istream<char, std::__1::char_traits<char> >&, std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::fpos<__mbstate_t>, long) Unexecuted instantiation: unsigned long Poco::StreamCopier::copyStreamRangeUnbufferedImpl<unsigned long>(std::__1::basic_istream<char, std::__1::char_traits<char> >&, std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::fpos<__mbstate_t>, long) |
224 | | }; |
225 | | |
226 | | |
227 | | } // namespace Poco |
228 | | |
229 | | |
230 | | #endif // Foundation_StreamCopier_INCLUDED |