made a win32 and posix impl

This commit is contained in:
Joud Kandeel
2026-03-12 03:31:39 +01:00
parent f677746795
commit f7ba29ff79
2 changed files with 197 additions and 20 deletions

View File

@@ -1,18 +1,137 @@
#include "..\..\Common\Platform.hpp"
#ifdef MCE_PLATFORM_WINDOWS
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include "FileOutputStream.hpp"
namespace mce {
void FileOutputStream::flush() {
bool FileOutputStream::open(const std::string& file) {
FileOutputStream::hFile = CreateFile(file.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
return (FileOutputStream::hFile != INVALID_HANDLE_VALUE);
}
size_t FileOutputStream::write(void* buffer, size_t size) {
bool FileOutputStream::isOpen() const {
return (FileOutputStream::hFile != INVALID_HANDLE_VALUE);
}
void FileOutputStream::close() {
if (FileOutputStream::hFile != INVALID_HANDLE_VALUE) {
CloseHandle(FileOutputStream::hFile);
}
}
size_t FileOutputStream::write(const void* buffer, size_t size) {
DWORD w;
WriteFile(FileOutputStream::hFile, buffer, size, &w, nullptr);
return static_cast<size_t>(w);
}
size_t FileOutputStream::seek(size_t position) {
LARGE_INTEGER offset{};
offset.QuadPart = position;
if (SetFilePointerEx(FileOutputStream::hFile, offset, nullptr, FILE_BEGIN) < 0) {
return FileOutputStream::INVALID_FILE_POSITION;
}
return position;
}
size_t FileOutputStream::tell() {
LARGE_INTEGER zero = { 0 };
LARGE_INTEGER pos;
if (SetFilePointerEx((HANDLE)FileOutputStream::hFile, zero, &pos, FILE_CURRENT) < 0) {
return FileOutputStream::INVALID_FILE_POSITION;
}
return (size_t)pos.QuadPart;
}
size_t FileOutputStream::getSize() {
LARGE_INTEGER size{};
if (GetFileSizeEx(FileOutputStream::hFile, &size) > 0) {
return FileOutputStream::INVALID_FILE_SIZE;
}
return (size_t)size.QuadPart;
}
}
#endif
#if defined(MCE_PLATFORM_LINUX) || defined(MCE_PLATFORM_MACOS)
#pragma warning(disable:4996)
#include <fcntl.h>
#include <sys/stat.h>
#include "FileOutputStream.hpp"
namespace mce {
FileOutputStream::FileOutputStream() :
file(nullptr) {}
FileOutputStream::~FileOutputStream() {
FileOutputStream::close();
}
bool FileOutputStream::open(const std::string& fileName) {
if (FileOutputStream::file)
std::fclose(FileOutputStream::file);
FileOutputStream::file = std::fopen(fileName.c_str(), "wb");
return FileOutputStream::file != NULL;
}
void FileOutputStream::close() {
if (FileOutputStream::file != nullptr) {
std::fclose(FileOutputStream::file);
FileOutputStream::file = nullptr;
}
}
bool FileOutputStream::isOpen() const {
return FileOutputStream::file != nullptr;
}
size_t FileOutputStream::write(const void* buffer, size_t size) {
if (FileOutputStream::file)
return std::fwrite(buffer, 1, size, FileOutputStream::file);
else
return 0;
}
size_t FileOutputStream::seek(size_t position) {
if (FileOutputStream::file) {
if (std::fseek(FileOutputStream::file, static_cast<long>(position), SEEK_SET))
return FileOutputStream::INVALID_FILE_POSITION;
return tell();
}
else {
return FileOutputStream::INVALID_FILE_POSITION;
}
}
size_t FileOutputStream::tell() {
if (FileOutputStream::file)
return std::ftell(FileOutputStream::file);
else
return FileOutputStream::INVALID_FILE_POSITION;
}
size_t FileOutputStream::getSize() {
if (FileOutputStream::file) {
size_t position = FileOutputStream::tell();
std::fseek(FileOutputStream::file, 0, SEEK_END);
size_t size = FileOutputStream::tell();
FileOutputStream::seek(position);
return size;
}
else {
return FileOutputStream::INVALID_FILE_SIZE;
}
}
}
#endif

View File

@@ -1,41 +1,99 @@
#pragma once
#include "..\..\Common\Platform.hpp"
#include "OutputStream.hpp"
#ifdef MCE_PLATFORM_WINDOWS
#undef INVALID_FILE_SIZE
#endif
#include <EASTL/string_view.h>
#include <string>
#include <cstdio>
namespace mce {
/**
* @brief Platform-independent file output stream implementation.
*
* Provides a concrete OutputStream that writes data to a file using the
* platform native file handle or FILE* depending on the platform.
*/
class FileOutputStream final : public OutputStream {
public:
FileOutputStream() = default;
explicit FileOutputStream(eastl::string_view file);
/**
* @brief Opens a file to read from
* @param file The path (absolute or relative) to the file
* @brief Default constructor.
*/
void open(eastl::string_view file);
FileOutputStream() = default;
/**
* @return True if the file was successfully opened
* @brief Opens a file for writing (creates/truncates by default).
* @param file Path (absolute or relative) to the file to open.
* @return True if the file was successfully opened.
*/
bool open(const std::string& file);
/**
* @brief Query whether the underlying file handle is open.
* @return True when the file is open and ready for writing.
*/
bool isOpen() const;
/**
* @brief Checks if the stream is at the end of the file
* @return True if the file stream has the end-of-file flag (EOF).
*/
bool eof() const;
/**
* @brief Closes the file
* @brief Close the file and release any resources.
*/
void close();
void flush() override;
size_t write(void* buffer, size_t size) override;
/**
* @brief Write bytes to the file.
* @param buffer Pointer to the data to write.
* @param size Number of bytes to write from buffer.
* @return Number of bytes actually written.
*/
size_t write(const void* buffer, size_t size) override;
/**
* @brief Change the current write position in the file.
* @param position The absolute position (in bytes) to seek to.
* @return The new position in the file after seeking.
*/
size_t seek(size_t position) override;
/**
* @brief Get the current write position in the file.
* @return Current position in bytes from the start of the file.
*/
size_t tell() override;
/**
* @brief Get the total size of the underlying file in bytes.
* @return File size in bytes or INVALID_FILE_SIZE on error.
*/
size_t getSize() override;
/**
* @brief Constant indicating an invalid file size/position.
*
* This value is returned by getSize() or tell() when the operation
* fails.
*/
static inline constexpr size_t INVALID_FILE_SIZE = ~(0);
/**
* @brief Constant indicating an invalid file position.
*/
static inline constexpr size_t INVALID_FILE_POSITION = ~(0);
private:
#ifdef MCE_PLATFORM_WINDOWS
/**
* @brief Native Windows file handle pointer (opaque).
*
* Stored as void* to avoid including Windows headers in this header
* file. The implementation file should treat this as a HANDLE.
*/
void* hFile = nullptr;
#elif defined(MCE_PLATFORM_LINUX) || defined(MCE_PLATFORM_MACOS)
/**
* @brief Standard C FILE* used on POSIX platforms.
*/
std::FILE* file = nullptr;
#endif
};
}