33 void copy(std::istream &input, std::ostream &output, std::uint64_t count);
34 void callbackCopy(std::istream &input, std::ostream &output, std::uint64_t count,
const std::function<
bool(
void)> &isAborted,
35 const std::function<
void(
double)> &callback);
38 const std::function<
void(
double)> &callback);
42 char m_buffer[bufferSize];
80 const std::function<
void(
double)> &callback)
82 const auto totalBytes = count;
83 while (count > bufferSize) {
84 input.read(m_buffer, bufferSize);
85 output.write(m_buffer, bufferSize);
90 callback(
static_cast<double>(totalBytes - count) /
static_cast<double>(totalBytes));
92 input.read(m_buffer,
static_cast<std::streamsize
>(count));
93 output.write(m_buffer,
static_cast<std::streamsize
>(count));
106#ifdef CPP_UTILITIES_USE_SEND_FILE
107 if (output.fileDescriptor() != -1 && input.fileDescriptor() != -1 && output.fileDescriptor() != input.fileDescriptor()) {
108 const auto inputTellg = output.tellg();
109 const auto inputTellp = output.tellp();
110 const auto outputTellg = output.tellg();
111 const auto outputTellp = output.tellp();
114 const auto totalBytes =
static_cast<std::streamoff
>(count);
116 const auto bytesCopied = ::sendfile64(output.fileDescriptor(), input.fileDescriptor(),
nullptr, count);
117 if (bytesCopied < 0) {
118 if ((errno == EINVAL || errno == ENOSYS) &&
static_cast<std::uint64_t
>(totalBytes) == count) {
120 goto unoptimized_version;
122 throw std::ios_base::failure(
argsToString(
"sendfile64() failed: ", std::strerror(errno)));
124 count -=
static_cast<std::uint64_t
>(bytesCopied);
128 output.seekg(outputTellg + totalBytes);
129 output.seekp(outputTellp + totalBytes);
130 input.seekg(inputTellg + totalBytes);
131 input.seekp(inputTellp + totalBytes);
136 copy(
static_cast<std::istream &
>(input),
static_cast<std::ostream &
>(output), count);
152 const std::function<
bool(
void)> &isAborted,
const std::function<
void(
double)> &callback)
154#ifdef CPP_UTILITIES_USE_SEND_FILE
155 if (output.fileDescriptor() != -1 && input.fileDescriptor() != -1 && output.fileDescriptor() != input.fileDescriptor()) {
156 const auto inputTellg = output.tellg();
157 const auto inputTellp = output.tellp();
158 const auto outputTellg = output.tellg();
159 const auto outputTellp = output.tellp();
162 const auto totalBytes =
static_cast<std::streamoff
>(count);
164 const auto bytesToCopy =
static_cast<std::size_t
>(std::min(count,
static_cast<std::uint64_t
>(bufferSize)));
165 const auto bytesCopied = ::sendfile64(output.fileDescriptor(), input.fileDescriptor(),
nullptr, bytesToCopy);
166 if (bytesCopied < 0) {
167 if ((errno == EINVAL || errno == ENOSYS) &&
static_cast<std::uint64_t
>(totalBytes) == count) {
169 goto unoptimized_version;
171 throw std::ios_base::failure(
argsToString(
"sendfile64() failed: ", std::strerror(errno)));
173 count -=
static_cast<std::uint64_t
>(bytesCopied);
177 callback(
static_cast<double>(totalBytes -
static_cast<std::streamoff
>(count)) /
static_cast<double>(totalBytes));
181 output.seekg(outputTellg + totalBytes);
182 output.seekp(outputTellp + totalBytes);
183 input.seekg(inputTellg + totalBytes);
184 input.seekp(inputTellp + totalBytes);
190 callbackCopy(
static_cast<std::istream &
>(input),
static_cast<std::ostream &
>(output), count, isAborted, callback);
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.