diff options
Diffstat (limited to 'src/osd/modules/file/stdfile.cpp')
-rw-r--r-- | src/osd/modules/file/stdfile.cpp | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/src/osd/modules/file/stdfile.cpp b/src/osd/modules/file/stdfile.cpp new file mode 100644 index 00000000000..92920bba495 --- /dev/null +++ b/src/osd/modules/file/stdfile.cpp @@ -0,0 +1,251 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +//============================================================ +// +// minifile.c - Minimal core file access functions +// +//============================================================ + +#include "osdcore.h" + +#include <cassert> +#include <cstdint> +#include <cstdio> +#include <cstdlib> +#include <string> + +#include <stdio.h> // for fileno +#include <unistd.h> // for ftruncate + + +namespace { +class std_osd_file : public osd_file +{ +public: + + std_osd_file(FILE *f) : m_file(f) { assert(m_file); } + + //============================================================ + // osd_close + //============================================================ + + virtual ~std_osd_file() override + { + // close the file handle + if (m_file) std::fclose(m_file); + } + + //============================================================ + // osd_read + //============================================================ + + virtual error read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override + { + // seek to the new location; note that most fseek implementations are limited to 32 bits + if (std::fseek(m_file, offset, SEEK_SET) < 0) + return error::FAILURE; + + // perform the read + std::size_t const count = std::fread(buffer, 1, length, m_file); + actual = count; + + return error::NONE; + } + + //============================================================ + // osd_write + //============================================================ + + virtual error write(const void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override + { + // seek to the new location; note that most fseek implementations are limited to 32 bits + if (std::fseek(m_file, offset, SEEK_SET) < 0) + return error::FAILURE; + + // perform the write + std::size_t const count = std::fwrite(buffer, 1, length, m_file); + actual = count; + + return error::NONE; + } + + //============================================================ + // osd_truncate + //============================================================ + + error truncate(std::uint64_t offset) override + { + return (ftruncate(fileno(m_file), offset) < 0) ? error::FAILURE : error::NONE; + } + + //============================================================ + // osd_fflush + //============================================================ + + virtual error flush() override + { + return (std::fflush(m_file) == EOF) ? error::FAILURE : error::NONE; + } + +private: + FILE *m_file; +}; + +} // anonymous namespace + + +//============================================================ +// osd_open +//============================================================ + +osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags, ptr &file, std::uint64_t &filesize) +{ + // based on the flags, choose a mode + const char *mode; + if (openflags & OPEN_FLAG_WRITE) + { + if (openflags & OPEN_FLAG_READ) + mode = (openflags & OPEN_FLAG_CREATE) ? "w+b" : "r+b"; + else + mode = "wb"; + } + else if (openflags & OPEN_FLAG_READ) + mode = "rb"; + else + return error::INVALID_ACCESS; + + // open the file + FILE *const fileptr = std::fopen(path.c_str(), mode); + if (!fileptr) + return error::NOT_FOUND; + + // get the size -- note that most fseek/ftell implementations are limited to 32 bits + long length; + if ((std::fseek(fileptr, 0, SEEK_END) < 0) || + ((length = std::ftell(fileptr)) < 0) || + (std::fseek(fileptr, 0, SEEK_SET) < 0)) + { + std::fclose(fileptr); + return error::FAILURE; + } + + try + { + file = std::make_unique<std_osd_file>(fileptr); + filesize = std::int64_t(length); + return error::NONE; + } + catch (...) + { + std::fclose(fileptr); + return error::OUT_OF_MEMORY; + } +} + + +//============================================================ +// osd_openpty +//============================================================ + +osd_file::error osd_file::openpty(ptr &file, std::string &name) +{ + return error::FAILURE; +} + + +//============================================================ +// osd_rmfile +//============================================================ + +osd_file::error osd_file::remove(std::string const &filename) +{ + return (std::remove(filename.c_str()) < 0) ? error::FAILURE : error::NONE; +} + + +//============================================================ +// osd_get_physical_drive_geometry +//============================================================ + +int osd_get_physical_drive_geometry(const char *filename, UINT32 *cylinders, UINT32 *heads, UINT32 *sectors, UINT32 *bps) +{ + // there is no standard way of doing this, so we always return FALSE, indicating + // that a given path is not a physical drive + return FALSE; +} + + +//============================================================ +// osd_uchar_from_osdchar +//============================================================ + +int osd_uchar_from_osdchar(UINT32 /* unicode_char */ *uchar, const char *osdchar, size_t count) +{ + // we assume a standard 1:1 mapping of characters to the first 256 unicode characters + *uchar = (UINT8)*osdchar; + return 1; +} + + +//============================================================ +// osd_stat +//============================================================ + +osd_directory_entry *osd_stat(const std::string &path) +{ + osd_directory_entry *result = nullptr; + + // create an osd_directory_entry; be sure to make sure that the caller can + // free all resources by just freeing the resulting osd_directory_entry + result = (osd_directory_entry *)osd_malloc_array(sizeof(*result) + path.length() + 1); + strcpy((char *)(result + 1), path.c_str()); + result->name = (char *)(result + 1); + result->type = ENTTYPE_NONE; + result->size = 0; + + FILE *f = std::fopen(path.c_str(), "rb"); + if (f != nullptr) + { + std::fseek(f, 0, SEEK_END); + result->type = ENTTYPE_FILE; + result->size = std::ftell(f); + std::fclose(f); + } + return result; +} + + +//============================================================ +// osd_get_full_path +//============================================================ + +osd_file::error osd_get_full_path(std::string &dst, std::string const &path) +{ + // derive the full path of the file in an allocated string + // for now just fake it since we don't presume any underlying file system + dst = path; + + return osd_file::error::NONE; +} + + +//============================================================ +// osd_is_absolute_path +//============================================================ + +bool osd_is_absolute_path(std::string const &path) +{ + // assume no for everything + return false; +} + + +//============================================================ +// osd_get_volume_name +//============================================================ + +const char *osd_get_volume_name(int idx) +{ + // we don't expose volumes + return nullptr; +} |