summaryrefslogtreecommitdiffstats
path: root/src/osd/modules/file/stdfile.cpp
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2016-03-13 13:54:57 +1100
committer Vas Crabb <vas@vastheman.com>2016-03-14 18:55:00 +1100
commit42fbb9c3967fcda37f2d9ae17d5796a79cf027b9 (patch)
treea43047ee00431e5e22bfc5f8f612ff775586e415 /src/osd/modules/file/stdfile.cpp
parent5fc27747031b6ed6f6c0582502098ebfb960be67 (diff)
Make osd_file a polymorphic class that's held with smart pointers
Make avi_file a class that's held with smart pointers, encapsulate various AVI I/O structures Make zip_file and _7z_file classes rather than having free functions everywhere Hide zip/7z class implementation behind an interface, no longer need to call close() to send back to the cache Don't dump as much crap in global namespace Add solaris PTY implementation Improve variable expansion for SDL OSD - supports ~/$FOO/${BAR} syntax Rearrange stuff so the same things are in file module for all OSDs Move file stuff into its own module 7z/zip open and destruct are still not thread-safe due to lack of interlocks around cache access Directory functions still need to be moved to file module SDL OSD may not initialise WinSock on Windows
Diffstat (limited to 'src/osd/modules/file/stdfile.cpp')
-rw-r--r--src/osd/modules/file/stdfile.cpp251
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;
+}