C++17ification! - Filesystem interaction now uses std::filesystem::path. - Usage of const char*, std::string have been changed to std::string_view where appropriate. - Usage of printf-style functions changed to use fmt.
87 lines
2.1 KiB
C++
87 lines
2.1 KiB
C++
/**
|
|
******************************************************************************
|
|
* Xenia : Xbox 360 Emulator Research Project *
|
|
******************************************************************************
|
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
******************************************************************************
|
|
*/
|
|
|
|
#include "xenia/base/mapped_memory.h"
|
|
|
|
#include <sys/mman.h>
|
|
#include <cstdio>
|
|
#include <memory>
|
|
|
|
#include "xenia/base/string.h"
|
|
|
|
namespace xe {
|
|
|
|
class PosixMappedMemory : public MappedMemory {
|
|
public:
|
|
PosixMappedMemory(const std::filesystem::path& path, Mode mode)
|
|
: MappedMemory(path, mode), file_handle(nullptr) {}
|
|
|
|
~PosixMappedMemory() override {
|
|
if (data_) {
|
|
munmap(data_, size_);
|
|
}
|
|
if (file_handle) {
|
|
fclose(file_handle);
|
|
}
|
|
}
|
|
|
|
FILE* file_handle;
|
|
};
|
|
|
|
std::unique_ptr<MappedMemory> MappedMemory::Open(
|
|
const std::filesystem::path& path, Mode mode, size_t offset,
|
|
size_t length) {
|
|
const char* mode_str;
|
|
int prot;
|
|
switch (mode) {
|
|
case Mode::kRead:
|
|
mode_str = "rb";
|
|
prot = PROT_READ;
|
|
break;
|
|
case Mode::kReadWrite:
|
|
mode_str = "r+b";
|
|
prot = PROT_READ | PROT_WRITE;
|
|
break;
|
|
}
|
|
|
|
auto mm =
|
|
std::unique_ptr<PosixMappedMemory>(new PosixMappedMemory(path, mode));
|
|
|
|
mm->file_handle = fopen(path.c_str(), mode_str);
|
|
if (!mm->file_handle) {
|
|
return nullptr;
|
|
}
|
|
|
|
size_t map_length;
|
|
map_length = length;
|
|
if (!length) {
|
|
fseeko(mm->file_handle, 0, SEEK_END);
|
|
map_length = ftello(mm->file_handle);
|
|
fseeko(mm->file_handle, 0, SEEK_SET);
|
|
}
|
|
mm->size_ = map_length;
|
|
|
|
mm->data_ =
|
|
mmap(0, map_length, prot, MAP_SHARED, fileno(mm->file_handle), offset);
|
|
if (!mm->data_) {
|
|
return nullptr;
|
|
}
|
|
|
|
return std::move(mm);
|
|
}
|
|
|
|
std::unique_ptr<ChunkedMappedMemoryWriter> ChunkedMappedMemoryWriter::Open(
|
|
const std::filesystem::path& path, size_t chunk_size,
|
|
bool low_address_space) {
|
|
// TODO(DrChat)
|
|
return nullptr;
|
|
}
|
|
|
|
} // namespace xe
|