1#ifndef IOUTILITIES_COPY_H
2#define IOUTILITIES_COPY_H
5#if defined(CPP_UTILITIES_USE_NATIVE_FILE_BUFFER) && defined(PLATFORM_LINUX)
6#define CPP_UTILITIES_USE_SEND_FILE
7#include "../conversion/stringbuilder.h"
10#ifdef CPP_UTILITIES_USE_SEND_FILE
12#include <sys/sendfile.h>
17#ifdef CPP_UTILITIES_USE_SEND_FILE
32 void copy(std::istream &input, std::ostream &output, std::uint64_t count);
33 void callbackCopy(std::istream &input, std::ostream &output, std::uint64_t count,
const std::function<
bool(
void)> &isAborted,
34 const std::function<
void(
double)> &callback);
37 const std::function<
void(
double)> &callback);
41 char m_buffer[bufferSize];
58 while (count > bufferSize) {
59 input.read(m_buffer, bufferSize);
60 output.write(m_buffer, bufferSize);
63 input.read(m_buffer,
static_cast<std::streamsize
>(count));
64 output.write(m_buffer,
static_cast<std::streamsize
>(count));
77template <std::
size_t bufferSize>
79 const std::function<
void(
double)> &callback)
81 const auto totalBytes = count;
82 while (count > bufferSize) {
83 input.read(m_buffer, bufferSize);
84 output.write(m_buffer, bufferSize);
89 callback(
static_cast<double>(totalBytes - count) /
static_cast<double>(totalBytes));
91 input.read(m_buffer,
static_cast<std::streamsize
>(count));
92 output.write(m_buffer,
static_cast<std::streamsize
>(count));
105#ifdef CPP_UTILITIES_USE_SEND_FILE
106 if (output.fileDescriptor() != -1 && input.fileDescriptor() != -1) {
107 const auto inputTellg = output.tellg();
108 const auto inputTellp = output.tellp();
109 const auto outputTellg = output.tellg();
110 const auto outputTellp = output.tellp();
113 const auto totalBytes =
static_cast<std::streamoff
>(count);
115 const auto bytesCopied = ::sendfile64(output.fileDescriptor(), input.fileDescriptor(),
nullptr, count);
116 if (bytesCopied < 0) {
117 throw std::ios_base::failure(
argsToString(
"sendfile64() failed: ", std::strerror(errno)));
119 count -=
static_cast<std::size_t
>(bytesCopied);
123 output.seekg(outputTellg + totalBytes);
124 output.seekp(outputTellp + totalBytes);
125 input.seekg(inputTellg + totalBytes);
126 input.seekp(inputTellp + totalBytes);
130 copy(
static_cast<std::istream &
>(input),
static_cast<std::ostream &
>(output), count);
144template <std::
size_t bufferSize>
146 const std::function<
bool(
void)> &isAborted,
const std::function<
void(
double)> &callback)
148#ifdef CPP_UTILITIES_USE_SEND_FILE
149 if (output.fileDescriptor() != -1 && input.fileDescriptor() != -1) {
150 const auto inputTellg = output.tellg();
151 const auto inputTellp = output.tellp();
152 const auto outputTellg = output.tellg();
153 const auto outputTellp = output.tellp();
156 const auto totalBytes =
static_cast<std::streamoff
>(count);
158 const auto bytesCopied = ::sendfile64(output.fileDescriptor(), input.fileDescriptor(),
nullptr, std::min(count, bufferSize));
159 if (bytesCopied < 0) {
160 throw std::ios_base::failure(
argsToString(
"sendfile64() failed: ", std::strerror(errno)));
162 count -=
static_cast<std::uint64_t
>(bytesCopied);
166 callback(
static_cast<double>(totalBytes -
static_cast<std::streamoff
>(count)) /
static_cast<double>(totalBytes));
170 output.seekg(outputTellg + totalBytes);
171 output.seekp(outputTellp + totalBytes);
172 input.seekg(inputTellg + totalBytes);
173 input.seekp(inputTellp + totalBytes);
178 callbackCopy(
static_cast<std::istream &
>(input),
static_cast<std::ostream &
>(output), count, isAborted, callback);
The CopyHelper class helps to copy bytes from one stream to another.
char * buffer()
Returns the internal buffer.
void copy(std::istream &input, std::ostream &output, std::uint64_t count)
Copies count bytes from input to output.
void callbackCopy(std::istream &input, std::ostream &output, std::uint64_t count, const std::function< bool(void)> &isAborted, const std::function< void(double)> &callback)
Copies count bytes from input to output.
CopyHelper()
Constructs a new copy helper.
#define CPP_UTILITIES_EXPORT
Marks the symbol to be exported by the c++utilities library.
Contains all utilities provides by the c++utilities library.
StringType argsToString(Args &&...args)
std::fstream NativeFileStream