mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2024-11-10 00:52:11 +01:00
128 lines
2.7 KiB
C++
128 lines
2.7 KiB
C++
#include "file_cache.h"
|
|
|
|
#include <tinydir/tinydir.h>
|
|
|
|
#include <iostream>
|
|
|
|
void FileCache::wwwroot_register_file(const std::string &file_path) {
|
|
registered_files.insert(file_path);
|
|
}
|
|
|
|
void FileCache::wwwroot_deregister_file(const std::string &file_path) {
|
|
registered_files.erase(file_path);
|
|
}
|
|
|
|
bool FileCache::wwwroot_has_file(const std::string &file_path) {
|
|
return registered_files.find(file_path) != registered_files.end();
|
|
}
|
|
|
|
void FileCache::wwwroot_refresh_cache() {
|
|
registered_files.clear();
|
|
|
|
wwwroot_evaluate_dir(wwwroot.c_str());
|
|
}
|
|
|
|
void FileCache::wwwroot_evaluate_dir(const char *path, const bool should_exist) {
|
|
tinydir_dir dir;
|
|
if (tinydir_open(&dir, path) == -1) {
|
|
|
|
if (should_exist)
|
|
printf("Error opening wwwroot! folder: %s\n", path);
|
|
|
|
return;
|
|
}
|
|
|
|
while (dir.has_next) {
|
|
tinydir_file file;
|
|
if (tinydir_readfile(&dir, &file) == -1) {
|
|
tinydir_next(&dir);
|
|
continue;
|
|
}
|
|
|
|
if (!file.is_dir) {
|
|
std::string np = file.path;
|
|
np = np.substr(wwwroot.size(), np.size() - wwwroot.size());
|
|
|
|
registered_files.insert(np);
|
|
} else {
|
|
if (file.name[0] == '.' && file.name[1] == '\0' || file.name[0] == '.' && file.name[1] == '.') {
|
|
tinydir_next(&dir);
|
|
continue;
|
|
}
|
|
|
|
wwwroot_evaluate_dir(file.path);
|
|
}
|
|
|
|
tinydir_next(&dir);
|
|
}
|
|
|
|
tinydir_close(&dir);
|
|
}
|
|
|
|
bool FileCache::get_cached_body(const std::string &path, std::string *body) {
|
|
//TODO ERROR MACRO body == null
|
|
|
|
//this shouldn't need mutexes
|
|
|
|
CacheEntry *e = cache_map[path];
|
|
|
|
if (!e) {
|
|
return false;
|
|
}
|
|
|
|
int64_t current_timestamp = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
|
|
|
int64_t diff = current_timestamp - e->timestamp;
|
|
|
|
if (diff > cache_invalidation_time) {
|
|
return false;
|
|
}
|
|
|
|
body->append(e->body);
|
|
|
|
return true;
|
|
}
|
|
|
|
void FileCache::set_cached_body(const std::string &path, const std::string &body) {
|
|
cache_mutex.lock();
|
|
|
|
CacheEntry *e = cache_map[path];
|
|
|
|
if (!e) {
|
|
e = new CacheEntry();
|
|
cache_map[path] = e;
|
|
}
|
|
|
|
int64_t current_timestamp = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
|
|
|
e->timestamp = current_timestamp;
|
|
e->body = body;
|
|
|
|
cache_mutex.unlock();
|
|
}
|
|
|
|
FileCache::FileCache(bool singleton) {
|
|
if (singleton) {
|
|
if (_instance) {
|
|
printf("FileCache: Filecache instance is set as singleton, but an another FileCache instance is already set up as singleton! Ignoring setting!\n");
|
|
} else {
|
|
_instance = this;
|
|
}
|
|
}
|
|
|
|
cache_invalidation_time = 1;
|
|
}
|
|
|
|
FileCache::~FileCache() {
|
|
registered_files.clear();
|
|
|
|
if (_instance == this)
|
|
_instance = nullptr;
|
|
}
|
|
|
|
FileCache *FileCache::get_singleton() {
|
|
return _instance;
|
|
}
|
|
|
|
FileCache *FileCache::_instance = nullptr;
|