///////////////////////////////////////////////////////
| 1136 | |
| 1137 | //////////////////////////////////////////////////////////// |
| 1138 | Sftp::Result Sftp::download(const std::filesystem::path& remotePath, |
| 1139 | const std::function<bool(const void* data, std::size_t size)>& callback, |
| 1140 | std::uint64_t offset, |
| 1141 | const TimeoutWithPredicate& timeout) |
| 1142 | { |
| 1143 | if (!callback) |
| 1144 | return Result(Result::Value::Error); |
| 1145 | |
| 1146 | LIBSSH2_SFTP_HANDLE* handle{}; |
| 1147 | |
| 1148 | // Open the file for reading |
| 1149 | { |
| 1150 | const auto pathString = pathToUtf8(remotePath); |
| 1151 | const auto result = m_impl->waitForOperationComplete( |
| 1152 | [&] |
| 1153 | { |
| 1154 | if (handle = libssh2_sftp_open_ex(m_impl->sftpSession.get(), |
| 1155 | pathString.data(), |
| 1156 | static_cast<unsigned int>(pathString.size()), |
| 1157 | LIBSSH2_FXF_READ, |
| 1158 | 0, |
| 1159 | LIBSSH2_SFTP_OPENFILE); |
| 1160 | handle) |
| 1161 | return LIBSSH2_ERROR_NONE; |
| 1162 | |
| 1163 | return libssh2_session_last_errno(m_impl->ssh2Session.get()); |
| 1164 | }, |
| 1165 | timeout); |
| 1166 | |
| 1167 | if (result == LIBSSH2_ERROR_EAGAIN) |
| 1168 | return Result(Result::Value::Timeout); |
| 1169 | |
| 1170 | if (!handle) |
| 1171 | return makeError(m_impl->ssh2Session.get(), m_impl->sftpSession.get()); |
| 1172 | } |
| 1173 | |
| 1174 | // Seek to the offset if one was specified |
| 1175 | if (offset > 0) |
| 1176 | libssh2_sftp_seek64(handle, offset); |
| 1177 | |
| 1178 | // Read from the file |
| 1179 | { |
| 1180 | static constexpr auto bufferSizeStart = std::size_t{4 * 1024}; |
| 1181 | static constexpr auto bufferSizeMax = std::size_t{1024 * 1024}; |
| 1182 | auto bufferSize = bufferSizeStart; |
| 1183 | auto buffer = std::make_unique<char[]>(bufferSize); // NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays) |
| 1184 | |
| 1185 | while (true) |
| 1186 | { |
| 1187 | std::size_t length = bufferSize; |
| 1188 | auto* ptr = buffer.get(); |
| 1189 | int read{}; |
| 1190 | std::size_t totalRead{}; |
| 1191 | |
| 1192 | while (length > 0) |
| 1193 | { |
| 1194 | read = m_impl->waitForOperationComplete( |
| 1195 | [&] { return static_cast<int>(libssh2_sftp_read(handle, ptr, length)); }, |
nothing calls this directly
no test coverage detected