mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-26 18:42:41 +01:00
Add copyStreamRange to StreamCopier (#4474)
* feat(Foundation): StreamCopier copyStreamRange #4413 * chore(ci): disable instalation of unused databases in odbc job --------- Co-authored-by: Pavle <pavle@debian-gnu-linux-11.localdomain> Co-authored-by: Alex Fabijanic <alex@pocoproject.org>
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
#include "Poco/Buffer.h"
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <cstddef>
|
||||
@@ -47,6 +48,21 @@ public:
|
||||
/// 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.
|
||||
///
|
||||
@@ -62,6 +78,21 @@ public:
|
||||
/// 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.
|
||||
///
|
||||
@@ -76,6 +107,119 @@ public:
|
||||
/// 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 > rangeLength)
|
||||
bufferSize = rangeLength;
|
||||
|
||||
Buffer<char> buffer(bufferSize);
|
||||
T len = 0;
|
||||
if (istr)
|
||||
{
|
||||
istr.seekg(rangeStart);
|
||||
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)
|
||||
{
|
||||
if (bufferSize > (rangeLength - len))
|
||||
bufferSize = rangeLength - len;
|
||||
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);
|
||||
istr.get(c);
|
||||
while (istr && ostr && (len < rangeLength))
|
||||
{
|
||||
ostr.put(c);
|
||||
++len;
|
||||
istr.get(c);
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user