poco/Foundation/include/Poco/StreamCopier.h

231 lines
6.5 KiB
C
Raw Normal View History

2012-04-29 20:52:25 +02:00
//
// 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
2012-04-29 20:52:25 +02:00
//
#ifndef Foundation_StreamCopier_INCLUDED
#define Foundation_StreamCopier_INCLUDED
#include "Poco/Foundation.h"
#include "Poco/Buffer.h"
2012-04-29 20:52:25 +02:00
#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);
2012-04-29 20:52:25 +02:00
/// 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);
2012-04-29 20:52:25 +02:00
/// 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);
2012-04-29 20:52:25 +02:00
/// 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);
2012-04-29 20:52:25 +02:00
/// 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);
2012-04-29 20:52:25 +02:00
/// 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);
2012-04-29 20:52:25 +02:00
/// 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;
}
2012-04-29 20:52:25 +02:00
};
} // namespace Poco
#endif // Foundation_StreamCopier_INCLUDED