mirror of
https://github.com/wiiu-env/WUHBUtilsModule.git
synced 2024-11-25 12:56:53 +01:00
Improve open files tracking implementation
This commit is contained in:
parent
0785f08953
commit
d1774b8015
@ -1,20 +1,17 @@
|
||||
#include "FileUtils.h"
|
||||
#include "utils/FileReader.h"
|
||||
#include "utils/FileReaderCompressed.h"
|
||||
#include "utils/utils.h"
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <wuhb_utils/utils.h>
|
||||
#include <wums/exports.h>
|
||||
|
||||
std::vector<FileReader *> openFiles;
|
||||
std::forward_list<std::unique_ptr<FileReader>> openFiles;
|
||||
std::map<std::string, std::string> mountedWUHB;
|
||||
std::mutex mutex;
|
||||
|
||||
void WUHBUtils_CleanUp() {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
for (auto &file : openFiles) {
|
||||
delete file;
|
||||
}
|
||||
openFiles.clear();
|
||||
|
||||
for (const auto &[name, path] : mountedWUHB) {
|
||||
@ -69,22 +66,24 @@ WUHBUtilsApiErrorType WUU_FileOpen(const char *name, uint32_t *outHandle) {
|
||||
return WUHB_UTILS_API_ERROR_INVALID_ARG;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
FileReader *reader;
|
||||
std::unique_ptr<FileReader> reader;
|
||||
std::string path = std::string(name);
|
||||
std::string pathGZ = path + ".gz";
|
||||
|
||||
if (CheckFile(path.c_str())) {
|
||||
reader = new (std::nothrow) FileReader(path);
|
||||
reader = make_unique_nothrow<FileReader>(path);
|
||||
} else if (CheckFile(pathGZ.c_str())) {
|
||||
reader = new (std::nothrow) FileReaderCompressed(pathGZ);
|
||||
reader = make_unique_nothrow<FileReaderCompressed>(pathGZ);
|
||||
} else {
|
||||
return WUHB_UTILS_API_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
if (reader == nullptr) {
|
||||
|
||||
if (!reader || !reader->isReady()) {
|
||||
return WUHB_UTILS_API_ERROR_NO_MEMORY;
|
||||
}
|
||||
openFiles.push_back(reader);
|
||||
*outHandle = (uint32_t) reader;
|
||||
*outHandle = reader->getHandle();
|
||||
openFiles.push_front(std::move(reader));
|
||||
|
||||
return WUHB_UTILS_API_ERROR_NONE;
|
||||
}
|
||||
|
||||
@ -93,43 +92,22 @@ WUHBUtilsApiErrorType WUU_FileRead(uint32_t handle, uint8_t *buffer, uint32_t si
|
||||
return WUHB_UTILS_API_ERROR_INVALID_ARG;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
auto found = false;
|
||||
FileReader *reader;
|
||||
for (auto &cur : openFiles) {
|
||||
if ((uint32_t) cur == handle) {
|
||||
found = true;
|
||||
reader = cur;
|
||||
break;
|
||||
for (auto &reader : openFiles) {
|
||||
if ((uint32_t) reader.get() == (uint32_t) handle) {
|
||||
*outRes = (int32_t) reader->read(buffer, size);
|
||||
return WUHB_UTILS_API_ERROR_NONE;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return WUHB_UTILS_API_ERROR_FILE_HANDLE_NOT_FOUND;
|
||||
}
|
||||
|
||||
*outRes = (int32_t) reader->read(buffer, size);
|
||||
|
||||
return WUHB_UTILS_API_ERROR_NONE;
|
||||
return WUHB_UTILS_API_ERROR_FILE_HANDLE_NOT_FOUND;
|
||||
}
|
||||
|
||||
WUHBUtilsApiErrorType WUU_FileClose(uint32_t handle) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
auto count = 0;
|
||||
auto found = false;
|
||||
FileReader *reader;
|
||||
for (auto &cur : openFiles) {
|
||||
if ((uint32_t) cur == handle) {
|
||||
found = true;
|
||||
reader = cur;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
if (remove_locked_first_if(mutex, openFiles, [handle](auto &cur) { return cur->getHandle() == handle; })) {
|
||||
return WUHB_UTILS_API_ERROR_NONE;
|
||||
}
|
||||
if (!found) {
|
||||
return WUHB_UTILS_API_ERROR_FILE_HANDLE_NOT_FOUND;
|
||||
}
|
||||
openFiles.erase(openFiles.begin() + count);
|
||||
delete reader;
|
||||
return WUHB_UTILS_API_ERROR_NONE;
|
||||
|
||||
return WUHB_UTILS_API_ERROR_FILE_HANDLE_NOT_FOUND;
|
||||
}
|
||||
|
||||
WUHBUtilsApiErrorType WUU_FileExists(const char *name, int32_t *outRes) {
|
||||
|
@ -24,6 +24,14 @@ int64_t FileReader::read(uint8_t *buffer, uint32_t size) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
FileReader::FileReader(uint8_t *buffer, uint32_t size) {
|
||||
this->input_buffer = buffer;
|
||||
this->input_size = size;
|
||||
this->input_pos = 0;
|
||||
this->isReadFromBuffer = true;
|
||||
this->isReadFromFile = false;
|
||||
}
|
||||
|
||||
FileReader::FileReader(std::string &path) {
|
||||
int fd;
|
||||
if ((fd = open(path.c_str(), O_RDONLY)) >= 0) {
|
||||
@ -41,10 +49,7 @@ FileReader::~FileReader() {
|
||||
}
|
||||
}
|
||||
|
||||
FileReader::FileReader(uint8_t *buffer, uint32_t size) {
|
||||
this->input_buffer = buffer;
|
||||
this->input_size = size;
|
||||
this->input_pos = 0;
|
||||
this->isReadFromBuffer = true;
|
||||
this->isReadFromFile = false;
|
||||
}
|
||||
|
||||
bool FileReader::isReady() {
|
||||
return this->isReadFromFile || this->isReadFromBuffer;
|
||||
}
|
@ -17,6 +17,12 @@ public:
|
||||
|
||||
virtual int64_t read(uint8_t *buffer, uint32_t size);
|
||||
|
||||
virtual bool isReady();
|
||||
|
||||
virtual uint32_t getHandle() {
|
||||
return reinterpret_cast<uint32_t>(this);
|
||||
}
|
||||
|
||||
private:
|
||||
bool isReadFromBuffer = false;
|
||||
uint8_t *input_buffer = nullptr;
|
||||
|
31
src/utils/utils.h
Normal file
31
src/utils/utils.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <forward_list>
|
||||
#include <malloc.h>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
template<class T, class... Args>
|
||||
std::unique_ptr<T> make_unique_nothrow(Args &&...args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
|
||||
return std::unique_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template<class T, class... Args>
|
||||
std::shared_ptr<T> make_shared_nothrow(Args &&...args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
|
||||
return std::shared_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template<typename T, class Allocator, class Predicate>
|
||||
bool remove_locked_first_if(std::mutex &mutex, std::forward_list<T, Allocator> &list, Predicate pred) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
auto oit = list.before_begin(), it = std::next(oit);
|
||||
while (it != list.end()) {
|
||||
if (pred(*it)) {
|
||||
list.erase_after(oit);
|
||||
return true;
|
||||
}
|
||||
oit = it++;
|
||||
}
|
||||
return false;
|
||||
}
|
Loading…
Reference in New Issue
Block a user