Refactored UsbInterface::writeBulk member function to use std::span instead of std::vector

This commit is contained in:
Nav
2024-11-16 19:58:07 +00:00
parent a7ee6cbae2
commit 0118306e30
2 changed files with 43 additions and 21 deletions

View File

@@ -1,5 +1,6 @@
#include "UsbInterface.hpp" #include "UsbInterface.hpp"
#include <cassert>
#include <limits> #include <limits>
#include "src/Logger/Logger.hpp" #include "src/Logger/Logger.hpp"
@@ -84,29 +85,45 @@ namespace Usb
return output; return output;
} }
void UsbInterface::writeBulk(std::uint8_t endpointAddress, std::vector<unsigned char>&& buffer) { void UsbInterface::writeBulk(
if (buffer.size() > std::numeric_limits<int>::max()) { std::uint8_t endpointAddress,
throw DeviceCommunicationFailure{"Attempted to send too much data to bulk endpoint"}; std::span<const unsigned char> buffer,
} std::uint16_t maxPacketSize
) {
assert(buffer.size() <= std::numeric_limits<int>::max());
const auto length = static_cast<int>(buffer.size()); const auto bufferSize = buffer.size();
auto bytesTransferred = int{0}; auto totalBytesTransferred = std::size_t{0};
const auto statusCode = ::libusb_bulk_transfer( while (totalBytesTransferred < bufferSize) {
this->deviceHandle, auto bytesTransferred = int{0};
endpointAddress, const auto length = std::min(
buffer.data(), static_cast<int>(bufferSize - totalBytesTransferred),
length, static_cast<int>(maxPacketSize)
&bytesTransferred,
0
);
if (statusCode != 0 || bytesTransferred != length) {
Logger::debug(
"Attempted to write " + std::to_string(length) + " bytes to USB bulk endpoint. Bytes written: "
+ std::to_string(bytesTransferred) + ". Status code: " + std::to_string(statusCode)
); );
throw DeviceCommunicationFailure{"Failed to write data to bulk endpoint"};
const auto statusCode = ::libusb_bulk_transfer(
this->deviceHandle,
endpointAddress,
/*
* I know, I know...this is horrible. I'm effectively lying about the constness of `buffer`. But libusb
* *shouldn't* write to `buffer` here, because we're not reading from the device.
*/
const_cast<unsigned char*>(buffer.data()) + totalBytesTransferred,
length,
&bytesTransferred,
0
);
if (statusCode != 0 || bytesTransferred != length) {
Logger::debug(
"Attempted to write " + std::to_string(length) + " bytes to USB bulk endpoint. Bytes written: "
+ std::to_string(bytesTransferred) + ". Status code: " + std::to_string(statusCode)
);
throw DeviceCommunicationFailure{"Failed to write data to bulk endpoint"};
}
totalBytesTransferred += static_cast<std::size_t>(bytesTransferred);
} }
} }
} }

View File

@@ -2,6 +2,7 @@
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
#include <span>
#include <optional> #include <optional>
#include <chrono> #include <chrono>
@@ -43,7 +44,11 @@ namespace Usb
std::optional<std::chrono::milliseconds> timeout = std::nullopt std::optional<std::chrono::milliseconds> timeout = std::nullopt
); );
void writeBulk(std::uint8_t endpointAddress, std::vector<unsigned char>&& buffer); void writeBulk(
std::uint8_t endpointAddress,
std::span<const unsigned char> buffer,
std::uint16_t maxPacketSize
);
private: private:
::libusb_device_handle* deviceHandle; ::libusb_device_handle* deviceHandle;