Skip to content

Commit

Permalink
windows/serialInterface: Switched to a nicer (block-wise) way of gett…
Browse files Browse the repository at this point in the history
…ing data between the Windows I/O buffer and the packet buffer
  • Loading branch information
dragonmux committed Jan 16, 2024
1 parent f6b140d commit e437bf2
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 15 deletions.
1 change: 0 additions & 1 deletion src/include/windows/serialInterface.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ private:

void handleDeviceError(std::string_view operation) noexcept;
void refillBuffer() const;
[[nodiscard]] char nextByte() const;

public:
serialInterface_t() noexcept = default;
Expand Down
37 changes: 23 additions & 14 deletions src/windows/serialInterface.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
#include <array>
#include <string>
#include <string_view>
#include <algorithm>
#include <memory>
#include <fmt/format.h>
#include <substrate/console>
#include <substrate/index_sequence>
#include "windows/serialInterface.hxx"
#include "usbDevice.hxx"
#include "bmp.hxx"
Expand Down Expand Up @@ -292,26 +293,34 @@ void serialInterface_t::refillBuffer() const
readBufferOffset = 0U;
}

// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
[[gnu::noinline]] char serialInterface_t::nextByte() const
{
// Check if we need more data or should use what's in the buffer already
while (readBufferOffset == readBufferFullness)
refillBuffer();
return readBuffer[readBufferOffset++];
}

// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
std::string serialInterface_t::readPacket() const
{
std::array<char, bmp_t::maxPacketSize> packet{};
size_t length{0U};
for (; length < packet.size(); ++length)
// Try gathering a '#' terminated response
while (length < packet.size())
{
const auto byte{nextByte()};
if (byte == '#')
// Check if we need more data or should use what's in the buffer already
while (readBufferOffset == readBufferFullness)
refillBuffer();

const auto *const bufferBegin{readBuffer.data() + readBufferOffset};
const auto *const bufferEnd{readBuffer.data() + readBufferFullness};

// Look for an end of message marker
const auto *const eomMarker{std::find(bufferBegin, bufferEnd, static_cast<uint8_t>('#'))};
// We now either have a remote end of message marker, or need all the data from the buffer
std::uninitialized_copy(bufferBegin, eomMarker, packet.data() + length);
const auto responseLength{static_cast<size_t>(std::distance(bufferBegin, eomMarker))};
readBufferOffset += responseLength;
length += responseLength;
// If it's a remote end of message marker, break out the loop
if (responseLength != readBufferFullness)
{
++readBufferOffset;
break;
packet[length] = byte;
}
}

// Make a new std::string of an appropriate length, copying the data in to return it
Expand Down

0 comments on commit e437bf2

Please sign in to comment.