Move duplicated utilities to the common util folder and remove NEXT_DIR (#29)

* move things to the common library and remove next_dir

* fix for windows

* one last windows fix

* last fix for real this time

* debug listener test

* fix listener threading bug
This commit is contained in:
water111
2020-09-10 20:03:31 -04:00
committed by GitHub
parent 8cbcb36687
commit de5aa7e5e4
45 changed files with 138 additions and 351 deletions
+40
View File
@@ -0,0 +1,40 @@
#ifndef JAK_V2_BINARYREADER_H
#define JAK_V2_BINARYREADER_H
#include <cstdint>
#include <cassert>
#include <vector>
class BinaryReader {
public:
BinaryReader(uint8_t* _buffer, uint32_t _size) : buffer(_buffer), size(_size) {}
explicit BinaryReader(std::vector<uint8_t>& _buffer)
: buffer((uint8_t*)_buffer.data()), size(_buffer.size()) {}
template <typename T>
T read() {
assert(seek + sizeof(T) <= size);
T& obj = *(T*)(buffer + seek);
seek += sizeof(T);
return obj;
}
void ffwd(int amount) {
seek += amount;
assert(seek <= size);
}
uint32_t bytes_left() const { return size - seek; }
uint8_t* here() { return buffer + seek; }
uint32_t get_seek() { return seek; }
private:
uint8_t* buffer;
uint32_t size;
uint32_t seek = 0;
};
#endif // JAK_V2_BINARYREADER_H
+2 -1
View File
@@ -1,3 +1,4 @@
add_library(common_util
SHARED
FileUtil.cpp)
FileUtil.cpp
Timer.cpp)
+65 -6
View File
@@ -1,6 +1,9 @@
#include "FileUtil.h"
#include <iostream>
#include <stdio.h> /* defines FILENAME_MAX */
#include <fstream>
#include <sstream>
#include <cassert>
#ifdef _WIN32
#include <Windows.h>
@@ -8,7 +11,7 @@
#include <unistd.h>
#endif
std::string FileUtil::GetProjectPath() {
std::string file_util::get_project_path() {
#ifdef _WIN32
char buffer[FILENAME_MAX];
GetModuleFileNameA(NULL, buffer, FILENAME_MAX);
@@ -16,20 +19,21 @@ std::string FileUtil::GetProjectPath() {
"\\jak-project\\"); // Strip file path down to \jak-project\ directory
return std::string(buffer).substr(
0, pos + 12); // + 12 to include "\jak-project" in the returned filepath
#else // do Linux stuff
#else
// do Linux stuff
char buffer[FILENAME_MAX];
readlink("/proc/self/exe", buffer,
FILENAME_MAX); // /proc/self acts like a "virtual folder" containing information about
// the current process
std::string::size_type pos = std::string(buffer).find_last_of(
std::string::size_type pos = std::string(buffer).rfind(
"/jak-project/"); // Strip file path down to /jak-project/ directory
return std::string(buffer).substr(
0, pos + 12); // + 12 to include "/jak-project" in the returned filepath
#endif
}
std::string FileUtil::get_file_path(const std::vector<std::string>& input) {
std::string currentPath = FileUtil::GetProjectPath();
std::string file_util::get_file_path(const std::vector<std::string>& input) {
std::string currentPath = file_util::get_project_path();
char dirSeparator;
#ifdef _WIN32
@@ -39,9 +43,64 @@ std::string FileUtil::get_file_path(const std::vector<std::string>& input) {
#endif
std::string filePath = currentPath;
for (int i = 0; i < input.size(); i++) {
for (int i = 0; i < int(input.size()); i++) {
filePath = filePath + dirSeparator + input[i];
}
return filePath;
}
void file_util::write_binary_file(const std::string& name, void* data, size_t size) {
FILE* fp = fopen(name.c_str(), "wb");
if (!fp) {
throw std::runtime_error("couldn't open file " + name);
}
if (fwrite(data, size, 1, fp) != 1) {
throw std::runtime_error("couldn't write file " + name);
}
fclose(fp);
}
void file_util::write_text_file(const std::string& file_name, const std::string& text) {
FILE* fp = fopen(file_name.c_str(), "w");
if (!fp) {
printf("Failed to fopen %s\n", file_name.c_str());
throw std::runtime_error("Failed to open file");
}
fprintf(fp, "%s\n", text.c_str());
fclose(fp);
}
std::vector<uint8_t> file_util::read_binary_file(const std::string& filename) {
auto fp = fopen(filename.c_str(), "rb");
if (!fp)
throw std::runtime_error("File " + filename + " cannot be opened");
fseek(fp, 0, SEEK_END);
auto len = ftell(fp);
rewind(fp);
std::vector<uint8_t> data;
data.resize(len);
if (fread(data.data(), len, 1, fp) != 1) {
throw std::runtime_error("File " + filename + " cannot be read");
}
return data;
}
std::string file_util::read_text_file(const std::string& path) {
std::ifstream file(path);
if (!file.good()) {
throw std::runtime_error("couldn't open " + path);
}
std::stringstream ss;
ss << file.rdbuf();
return ss.str();
}
bool file_util::is_printable_char(char c) {
return c >= ' ' && c <= '~';
}
+8 -3
View File
@@ -2,7 +2,12 @@
#include <string>
#include <vector>
namespace FileUtil {
std::string GetProjectPath();
namespace file_util {
std::string get_project_path();
std::string get_file_path(const std::vector<std::string>& input);
} // namespace FileUtil
void write_binary_file(const std::string& name, void* data, size_t size);
void write_text_file(const std::string& file_name, const std::string& text);
std::vector<uint8_t> read_binary_file(const std::string& filename);
std::string read_text_file(const std::string& path);
bool is_printable_char(char c);
} // namespace file_util
+21
View File
@@ -0,0 +1,21 @@
#ifndef JAK1_MATCHPARAM_H
#define JAK1_MATCHPARAM_H
template <typename T>
struct MatchParam {
MatchParam() { is_wildcard = true; }
// intentionally not explicit so you don't have to put MatchParam<whatever>(blah) everywhere
MatchParam(T x) {
value = x;
is_wildcard = false;
}
T value;
bool is_wildcard = true;
bool operator==(const T& other) const { return is_wildcard || (value == other); }
bool operator!=(const T& other) const { return !(*this == other); }
};
#endif // JAK1_MATCHPARAM_H
+54
View File
@@ -0,0 +1,54 @@
#include "Timer.h"
#ifdef _WIN32
#include <Windows.h>
#define MS_PER_SEC 1000ULL // MS = milliseconds
#define US_PER_MS 1000ULL // US = microseconds
#define HNS_PER_US 10ULL // HNS = hundred-nanoseconds (e.g., 1 hns = 100 ns)
#define NS_PER_US 1000ULL
#define HNS_PER_SEC (MS_PER_SEC * US_PER_MS * HNS_PER_US)
#define NS_PER_HNS (100ULL) // NS = nanoseconds
#define NS_PER_SEC (MS_PER_SEC * US_PER_MS * NS_PER_US)
int Timer::clock_gettime_monotonic(struct timespec* tv) {
static LARGE_INTEGER ticksPerSec;
LARGE_INTEGER ticks;
double seconds;
if (!ticksPerSec.QuadPart) {
QueryPerformanceFrequency(&ticksPerSec);
if (!ticksPerSec.QuadPart) {
errno = ENOTSUP;
return -1;
}
}
QueryPerformanceCounter(&ticks);
seconds = (double)ticks.QuadPart / (double)ticksPerSec.QuadPart;
tv->tv_sec = (time_t)seconds;
tv->tv_nsec = (long)((ULONGLONG)(seconds * NS_PER_SEC) % NS_PER_SEC);
return 0;
}
#endif
void Timer::start() {
#ifdef __linux__
clock_gettime(CLOCK_MONOTONIC, &_startTime);
#elif _WIN32
clock_gettime_monotonic(&_startTime);
#endif
}
int64_t Timer::getNs() {
struct timespec now = {};
#ifdef __linux__
clock_gettime(CLOCK_MONOTONIC, &now);
#elif _WIN32
clock_gettime_monotonic(&now);
#endif
return (int64_t)(now.tv_nsec - _startTime.tv_nsec) +
1000000000 * (now.tv_sec - _startTime.tv_sec);
}
+47
View File
@@ -0,0 +1,47 @@
#ifndef JAK_V2_TIMER_H
#define JAK_V2_TIMER_H
#include <cassert>
#include <cstdint>
#include <ctime>
/*!
* Timer for measuring time elapsed with clock_monotonic
*/
class Timer {
public:
/*!
* Construct and start timer
*/
explicit Timer() { start(); }
#ifdef _WIN32
int clock_gettime_monotonic(struct timespec* tv);
#endif
/*!
* Start the timer
*/
void start();
/*!
* Get milliseconds elapsed
*/
double getMs() { return (double)getNs() / 1.e6; }
double getUs() { return (double)getNs() / 1.e3; }
/*!
* Get nanoseconds elapsed
*/
int64_t getNs();
/*!
* Get seconds elapsed
*/
double getSeconds() { return (double)getNs() / 1.e9; }
struct timespec _startTime = {};
};
#endif // JAK_V2_TIMER_H