Coverage Report

Created: 2025-09-05 06:24

/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