Skip to content

Commit

Permalink
Custom Filebuf: Also use it for writing
Browse files Browse the repository at this point in the history
Has the same performance issues
  • Loading branch information
Ghabry committed Jun 5, 2024
1 parent b2f2981 commit ac0a661
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 21 deletions.
21 changes: 18 additions & 3 deletions src/filesystem_native.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include "output.h"
#include "platform.h"

#ifdef USE_CUSTOM_FILE_READBUF
#ifdef USE_CUSTOM_FILEBUF
# include <sys/stat.h>
# include <fcntl.h>
#endif
Expand All @@ -55,14 +55,14 @@ int64_t NativeFilesystem::GetFilesize(StringView path) const {
}

std::streambuf* NativeFilesystem::CreateInputStreambuffer(StringView path, std::ios_base::openmode mode) const {
#ifdef USE_CUSTOM_FILE_READBUF
#ifdef USE_CUSTOM_FILEBUF
(void)mode;
int fd = open(ToString(path).c_str(), O_RDONLY);
if (fd < 0) {
return nullptr;
}

return new Filesystem_Stream::FdStreamBuf(fd);
return new Filesystem_Stream::FdStreamBuf(fd, true);
#else
auto buf = new std::filebuf();

Expand All @@ -84,6 +84,20 @@ std::streambuf* NativeFilesystem::CreateInputStreambuffer(StringView path, std::
}

std::streambuf* NativeFilesystem::CreateOutputStreambuffer(StringView path, std::ios_base::openmode mode) const {
#ifdef USE_CUSTOM_FILEBUF
int flags = O_TRUNC;

if ((mode & std::ios_base::app) == std::ios_base::app) {
flags = O_APPEND;
}

int fd = open(ToString(path).c_str(), O_WRONLY | O_CREAT | flags, S_IRUSR | S_IWUSR);
if (fd < 0) {
return nullptr;
}

return new Filesystem_Stream::FdStreamBuf(fd, false);
#else
auto* buf = new std::filebuf();
buf->open(
#ifdef _MSC_VER
Expand All @@ -99,6 +113,7 @@ std::streambuf* NativeFilesystem::CreateOutputStreambuffer(StringView path, std:
}

return buf;
#endif
}

bool NativeFilesystem::GetDirectoryContent(StringView path, std::vector<DirectoryTree::Entry>& entries) const {
Expand Down
50 changes: 44 additions & 6 deletions src/filesystem_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#include <utility>

#ifdef USE_CUSTOM_FILE_READBUF
#ifdef USE_CUSTOM_FILEBUF
# include <unistd.h>
#endif

Expand Down Expand Up @@ -127,14 +127,21 @@ Filesystem_Stream::InputMemoryStreamBuf::InputMemoryStreamBuf(std::vector<uint8_

}

#ifdef USE_CUSTOM_FILEBUF

#ifdef USE_CUSTOM_FILE_READBUF

Filesystem_Stream::FdStreamBuf::FdStreamBuf(int fd) : fd(fd) {
clear_buffer();
Filesystem_Stream::FdStreamBuf::FdStreamBuf(int fd, bool is_read) : fd(fd), is_read(is_read) {
if (is_read) {
clear_buffer();
} else {
setp(buffer.end(), buffer.end());
}
}

Filesystem_Stream::FdStreamBuf::~FdStreamBuf() {
if (!is_read) {
sync();
}

close(fd);
}

Expand All @@ -152,7 +159,10 @@ Filesystem_Stream::FdStreamBuf::int_type Filesystem_Stream::FdStreamBuf::underfl
return traits_type::to_int_type(*gptr());
}

std::streambuf::pos_type Filesystem_Stream::FdStreamBuf::seekoff(std::streambuf::off_type offset, std::ios_base::seekdir dir, std::ios_base::openmode) {
std::streambuf::pos_type Filesystem_Stream::FdStreamBuf::seekoff(std::streambuf::off_type offset, std::ios_base::seekdir dir, std::ios_base::openmode mode) {
// Not implemented for writing
assert(is_read);

if (dir == std::ios_base::beg) {
offset = offset - file_offset + bytes_remaining();
dir = std::ios_base::cur;
Expand Down Expand Up @@ -199,6 +209,34 @@ std::streambuf::pos_type Filesystem_Stream::FdStreamBuf::seekpos(std::streambuf:
return seekoff(pos, std::ios_base::beg, mode);
}


Filesystem_Stream::FdStreamBuf::int_type Filesystem_Stream::FdStreamBuf::overflow(int c) {
assert(pptr() == epptr());

if (c == traits_type::eof() || sync() == -1) {
return traits_type::eof();
}

*pptr() = traits_type::to_char_type(c);

pbump(1);
return c;
}

int Filesystem_Stream::FdStreamBuf::sync() {
char *p = pbase();
while (p < pptr()) {
int written = write(fd, p, pptr() - p);
if (written <= 0) {
return -1;
}
p += written;
}

setp(buffer.begin(), buffer.end());
return 0;
}

void Filesystem_Stream::FdStreamBuf::clear_buffer() {
setg(buffer.begin(), buffer.end(), buffer.end());
}
Expand Down
21 changes: 14 additions & 7 deletions src/filesystem_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,26 +97,33 @@ namespace Filesystem_Stream {
std::vector<uint8_t> buffer;
};

#ifdef USE_CUSTOM_FILE_READBUF
#ifdef USE_CUSTOM_FILEBUF
class FdStreamBuf : public std::streambuf {
public:
FdStreamBuf(int fd);
FdStreamBuf(int fd, bool is_read);
FdStreamBuf(FdStreamBuf const& other) = delete;
FdStreamBuf const& operator=(FdStreamBuf const& other) = delete;
~FdStreamBuf();

protected:
int_type underflow();
std::streambuf::pos_type seekoff(std::streambuf::off_type offset, std::ios_base::seekdir dir, std::ios_base::openmode mode);
std::streambuf::pos_type seekpos(std::streambuf::pos_type pos, std::ios_base::openmode);
// Reading
int_type underflow() override;
std::streambuf::pos_type seekoff(std::streambuf::off_type offset, std::ios_base::seekdir dir, std::ios_base::openmode mode) override;
std::streambuf::pos_type seekpos(std::streambuf::pos_type pos, std::ios_base::openmode) override;

// Writing
int_type overflow(int c = EOF) override;
int sync() override;
private:
// Reading
void clear_buffer();
ssize_t bytes_remaining() const;
off_t file_offset = 0;

// Both
int fd;
off_t file_offset = 0;
std::array<char, USE_CUSTOM_FILE_READBUF> buffer;
bool is_read; // Streams can be read and write but we only always use one mode
std::array<char, USE_CUSTOM_FILEBUF> buffer;
};
#endif

Expand Down
10 changes: 5 additions & 5 deletions src/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,21 @@
#elif defined(__3DS__)
# define SUPPORT_JOYSTICK
# define SUPPORT_JOYSTICK_AXIS
# define USE_CUSTOM_FILE_READBUF 4 * 1024
# define USE_CUSTOM_FILEBUF 4 * 1024
#elif defined(__vita__)
# define SUPPORT_JOYSTICK
# define SUPPORT_JOYSTICK_AXIS
# define USE_CUSTOM_FILE_READBUF 4 * 1024
# define USE_CUSTOM_FILEBUF 4 * 1024
#elif defined(__wii__)
# include <cstdint>
# define SUPPORT_JOYSTICK
# define SUPPORT_JOYSTICK_AXIS
# define USE_CUSTOM_FILE_READBUF 4 * 1024
# define USE_CUSTOM_FILEBUF 4 * 1024
#elif defined(__WIIU__)
# define SUPPORT_JOYSTICK
# define SUPPORT_JOYSTICK_AXIS
# define SUPPORT_TOUCH
# define USE_CUSTOM_FILE_READBUF 16 * 1024
# define USE_CUSTOM_FILEBUF 16 * 1024
#elif defined(_WIN32)
# define SUPPORT_ZOOM
# define SUPPORT_MOUSE
Expand All @@ -84,7 +84,7 @@
#elif defined(__SWITCH__)
# define SUPPORT_JOYSTICK
# define SUPPORT_JOYSTICK_AXIS
# define USE_CUSTOM_FILE_READBUF 16 * 1024
# define USE_CUSTOM_FILEBUF 16 * 1024
#elif defined(PLAYER_AMIGA) && !defined(__AROS__)
# define SUPPORT_ZOOM
# define SUPPORT_MOUSE
Expand Down

0 comments on commit ac0a661

Please sign in to comment.