cpp-utilities/io/copy.h

123 lines
4.3 KiB
C
Raw Normal View History

2015-04-22 18:36:40 +02:00
#ifndef IOUTILITIES_COPY_H
#define IOUTILITIES_COPY_H
#include "./nativefilestream.h"
2015-04-22 18:36:40 +02:00
#include <functional>
2017-05-01 03:13:11 +02:00
#include <iostream>
2015-04-22 18:36:40 +02:00
namespace CppUtilities {
2015-04-22 18:36:40 +02:00
/*!
* \class IoUtilities::CopyHelper
2016-09-17 11:44:49 +02:00
* \brief The CopyHelper class helps to copy bytes from one stream to another.
2015-04-22 18:36:40 +02:00
* \tparam Specifies the buffer size.
*/
2017-05-01 03:13:11 +02:00
template <std::size_t bufferSize> class CPP_UTILITIES_EXPORT CopyHelper {
2015-04-22 18:36:40 +02:00
public:
CopyHelper();
void copy(std::istream &input, std::ostream &output, std::size_t count);
2017-05-01 03:13:11 +02:00
void callbackCopy(std::istream &input, std::ostream &output, std::size_t count, const std::function<bool(void)> &isAborted,
const std::function<void(double)> &callback);
void copy(NativeFileStream &input, NativeFileStream &output, std::size_t count);
void callbackCopy(NativeFileStream &input, NativeFileStream &output, std::size_t count, const std::function<bool(void)> &isAborted,
const std::function<void(double)> &callback);
2016-01-18 23:41:30 +01:00
char *buffer();
2017-05-01 03:13:11 +02:00
2015-04-22 18:36:40 +02:00
private:
char m_buffer[bufferSize];
};
/*!
* \brief Constructs a new copy helper.
*/
2017-05-01 03:13:11 +02:00
template <std::size_t bufferSize> CopyHelper<bufferSize>::CopyHelper()
{
}
2015-04-22 18:36:40 +02:00
/*!
* \brief Copies \a count bytes from \a input to \a output.
2017-02-03 00:54:44 +01:00
* \remarks Set an exception mask using std::ios::exceptions() to get a std::ios_base::failure exception
* when an IO error occurs.
2015-04-22 18:36:40 +02:00
*/
2017-05-01 03:13:11 +02:00
template <std::size_t bufferSize> void CopyHelper<bufferSize>::copy(std::istream &input, std::ostream &output, std::size_t count)
2015-04-22 18:36:40 +02:00
{
2017-05-01 03:13:11 +02:00
while (count > bufferSize) {
2015-04-22 18:36:40 +02:00
input.read(m_buffer, bufferSize);
output.write(m_buffer, bufferSize);
count -= bufferSize;
}
input.read(m_buffer, count);
output.write(m_buffer, count);
}
/*!
2017-02-03 00:54:44 +01:00
* \brief Copies \a count bytes from \a input to \a output. The procedure might be aborted and
* progress updates will be reported.
2015-04-22 18:36:40 +02:00
*
2017-02-03 00:54:44 +01:00
* Copying is aborted when \a isAborted returns true. The current progress is reported by calling
* the specified \a callback function.
2015-04-22 18:36:40 +02:00
*
2017-02-03 00:54:44 +01:00
* \remarks Set an exception mask using std::ios::exceptions() to get a std::ios_base::failure exception
* when an IO error occurs.
2015-04-22 18:36:40 +02:00
*/
2017-05-01 03:13:11 +02:00
template <std::size_t bufferSize>
void CopyHelper<bufferSize>::callbackCopy(std::istream &input, std::ostream &output, std::size_t count, const std::function<bool(void)> &isAborted,
const std::function<void(double)> &callback)
2015-04-22 18:36:40 +02:00
{
2017-02-03 00:54:44 +01:00
const std::size_t totalBytes = count;
2017-05-01 03:13:11 +02:00
while (count > bufferSize) {
2015-04-22 18:36:40 +02:00
input.read(m_buffer, bufferSize);
output.write(m_buffer, bufferSize);
count -= bufferSize;
2017-05-01 03:13:11 +02:00
if (isAborted()) {
2015-04-22 18:36:40 +02:00
return;
}
callback(static_cast<double>(totalBytes - count) / totalBytes);
}
input.read(m_buffer, count);
output.write(m_buffer, count);
callback(1.0);
}
/*!
* \brief Copies \a count bytes from \a input to \a output.
* \remarks
* - Set an exception mask using std::ios::exceptions() to get a std::ios_base::failure exception
* when an IO error occurs.
* - Possibly uses native APIs such as POSIX sendfile() to improve the speed (not implemented yet).
*/
template <std::size_t bufferSize> void CopyHelper<bufferSize>::copy(NativeFileStream &input, NativeFileStream &output, std::size_t count)
{
copy(static_cast<std::istream &>(input), static_cast<std::ostream &>(output), count);
}
/*!
* \brief Copies \a count bytes from \a input to \a output. The procedure might be aborted and
* progress updates will be reported.
*
* Copying is aborted when \a isAborted returns true. The current progress is reported by calling
* the specified \a callback function.
*
* - Set an exception mask using std::ios::exceptions() to get a std::ios_base::failure exception
* when an IO error occurs.
* - Possibly uses native APIs such as POSIX sendfile() to improve the speed (not implemented yet).
*/
template <std::size_t bufferSize>
void CopyHelper<bufferSize>::callbackCopy(NativeFileStream &input, NativeFileStream &output, std::size_t count,
const std::function<bool(void)> &isAborted, const std::function<void(double)> &callback)
{
callbackCopy(static_cast<std::istream &>(input), static_cast<std::ostream &>(output), count, isAborted, callback);
}
2016-01-18 23:41:30 +01:00
/*!
* \brief Returns the internal buffer.
*/
2017-05-01 03:13:11 +02:00
template <std::size_t bufferSize> char *CopyHelper<bufferSize>::buffer()
2016-01-18 23:41:30 +01:00
{
return m_buffer;
}
} // namespace CppUtilities
2015-04-22 18:36:40 +02:00
#endif // IOUTILITIES_COPY_H