diff --git a/src/FileReader.cc b/src/FileReader.cc new file mode 100644 index 0000000..3d0b568 --- /dev/null +++ b/src/FileReader.cc @@ -0,0 +1,74 @@ +#include "FileReader.h" +#include +#include +#include +#include + +#ifdef _WIN32 +#define JES_O_BINARY O_BINARY +#else +#define JES_O_BINARY 0 +#endif + +/** + * Load a file into memory. + * + * @param[in] fname File name. + * @param[out] buf Pointer to memory buffer containing file. Must be freed by + * caller with delete[]. + * @param[out] size Set to length of the file. If the return value is true + * and *size is 0, then no buffer was allocated and *buf should not be used. + * + * @retval false The file failed to load. In this case the output parameter + * values *buf and *size should not be used. + * @retval true The file was loaded successfully. + */ +bool FileReader::load(const char * fname, uint8_t ** buf, size_t * size) +{ + struct stat st; + if (stat(fname, &st) != 0) + { + return false; + } + + if (st.st_size < 0) + { + return false; + } + + *size = st.st_size; + if (st.st_size == 0) + { + return true; + } + + int fd = open(fname, O_RDONLY | JES_O_BINARY); + if (fd < 0) + { + return false; + } + + *buf = new uint8_t[st.st_size]; + + off_t n_bytes_read = 0u; + for (;;) + { + off_t rd_size = read(fd, &(*buf)[n_bytes_read], st.st_size - n_bytes_read); + if (rd_size <= 0) + break; + n_bytes_read += rd_size; + if (n_bytes_read >= st.st_size) + break; + } + if (n_bytes_read != st.st_size) + { + delete[] *buf; + *buf = NULL; + close(fd); + return false; + } + + close(fd); + + return true; +} diff --git a/src/FileReader.h b/src/FileReader.h new file mode 100644 index 0000000..b961206 --- /dev/null +++ b/src/FileReader.h @@ -0,0 +1,13 @@ +#ifndef JES_FILEREADER_H +#define JES_FILEREADER_H + +#include +#include + +class FileReader +{ +public: + static bool load(const char * fname, uint8_t ** buf, size_t * size); +}; + +#endif