Refactored UsbInterface::writeBulk member function to use std::span instead of std::vector
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user