buffer: Implement "readEntry"
readEntry reads the entryHeader to figure out how much of the buffer to
read for the entry.
Tested: Unit tested
Signed-off-by: Brandon Kim <brandonkim@google.com>
Change-Id: I390e77c088439c74d100ef4b4cb35e746facd495
diff --git a/src/buffer.cpp b/src/buffer.cpp
index 87d9fa2..fca8837 100644
--- a/src/buffer.cpp
+++ b/src/buffer.cpp
@@ -12,6 +12,7 @@
#include <cstddef>
#include <cstdint>
#include <memory>
+#include <numeric>
#include <span>
#include <vector>
@@ -170,4 +171,31 @@
return *reinterpret_cast<struct QueueEntryHeader*>(bytesRead.data());
}
+EntryPair BufferImpl::readEntry(size_t offset)
+{
+ struct QueueEntryHeader entryHeader = readEntryHeader(offset);
+
+ size_t entrySize = entryHeader.entrySize;
+
+ // wraparonudRead may throw if entrySize was bigger than the buffer or if it
+ // was not able to read all bytes, let it propagate up the stack
+ // - Use additionalBoundaryCheck parameter to tighten the boundary check
+ std::vector<uint8_t> entry =
+ wraparoundRead(offset + sizeof(struct QueueEntryHeader), entrySize,
+ sizeof(struct QueueEntryHeader));
+
+ // Calculate the checksum
+ uint8_t* entryHeaderPtr = reinterpret_cast<uint8_t*>(&entryHeader);
+ uint8_t checksum = std::accumulate(
+ entryHeaderPtr, entryHeaderPtr + sizeof(struct QueueEntryHeader), 0);
+ checksum = std::accumulate(std::begin(entry), std::end(entry), checksum);
+ if (checksum != 0)
+ {
+ throw std::runtime_error(fmt::format(
+ "[readEntry] Checksum was '{}', expected '0'", checksum));
+ }
+
+ return {entryHeader, entry};
+}
+
} // namespace bios_bmc_smm_error_logger