extend file_handler to support reads
Problem: the upcomming version handler will need to read from files.
Currently file hander (image handler) does not support reads.
Solution: Add read support by providing an optional mode parameter.
Tests added:
FileHanderTest added to
- Test out open for reads
- Test out reading out bytes and verifying size and content
- Test out trying to read beyond EOF
- Test out offset reads that go beyond EOF
Tested:
Existing unit tests pass
New unit tests for reading all pass
Signed-off-by: Jason Ling <jasonling@google.com>
Change-Id: Ie416a6b4b452d8d04fa158bd55989d07a891896f
diff --git a/bmc/file_handler.cpp b/bmc/file_handler.cpp
index f7878ea..dacca19 100644
--- a/bmc/file_handler.cpp
+++ b/bmc/file_handler.cpp
@@ -18,6 +18,7 @@
#include <cstdint>
#include <filesystem>
+#include <ios>
#include <memory>
#include <string>
#include <vector>
@@ -26,8 +27,10 @@
{
namespace fs = std::filesystem;
-bool FileHandler::open(const std::string& path)
+bool FileHandler::open(const std::string& path, std::ios_base::openmode mode)
{
+ /* force binary mode */
+ mode |= std::ios::binary;
this->path = path;
if (file.is_open())
@@ -38,9 +41,8 @@
return false;
}
- /* using ofstream no need to set out */
- file.open(filename, std::ios::binary);
- if (file.bad())
+ file.open(filename, mode);
+ if (!file.good()) /* on success goodbit is set */
{
/* TODO: Oh no! Care about this. */
return false;
@@ -90,6 +92,46 @@
return true;
}
+std::optional<std::vector<uint8_t>> FileHandler::read(std::uint32_t offset,
+ std::uint32_t size)
+{
+ if (!file.is_open())
+ {
+ return std::nullopt;
+ }
+
+ /* determine size of file */
+ file.seekg(0, std::ios_base::end);
+ uint32_t filesize = file.tellg();
+ uint32_t bytesToRead = size;
+
+ /* make sure to not read past the end of file */
+ if (offset + size > filesize)
+ {
+ bytesToRead = filesize - offset;
+ }
+
+ /* if no bytes can be read, fail */
+ if (0 == bytesToRead)
+ {
+ return std::nullopt;
+ }
+
+ /* seek to offset then read */
+ file.seekg(offset);
+ std::vector<uint8_t> fileData(bytesToRead);
+ file.read(reinterpret_cast<char*>(fileData.data()), bytesToRead);
+
+ /* if any sort of failure happened during all the seeks
+ * and reads then fail the entire operation
+ */
+ if (!file.good())
+ {
+ return std::nullopt;
+ }
+ return fileData;
+}
+
int FileHandler::getSize()
{
try