Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion !Format + one_header.bat
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
call auto_format.bat
call format_all.bat
call make_one_header.bat
64 changes: 40 additions & 24 deletions ResourceManager/include/ResourceManager/ResourceHandle.h
Original file line number Diff line number Diff line change
@@ -1,49 +1,55 @@
// Copyright (c) 2018 Johnny Borov <JohnnyBorov@gmail.com>. Released under MIT License.
// Copyright (c) 2018 Johnny Borov <JohnnyBorov@gmail.com>. Released under MIT
// License.

#ifndef RM_RESOURCE_HANDLE_H
#define RM_RESOURCE_HANDLE_H

#include <cstddef>
#include <string>
#include <exception>
#include <string>

// This exception type is thrown if ResourceHandle constructor gets invalid resource name.
// Compile with -DRM_NO_EXCEPTIONS to disable throwing on invalid resource name.
// This exception type is thrown if ResourceHandle constructor gets invalid
// resource name. Compile with -DRM_NO_EXCEPTIONS to disable throwing on invalid
// resource name.
class ResourceNotFound : public std::exception {
public:
ResourceNotFound(std::string resource_name) : m_message{"ResourceManager: Resource not found: " + resource_name} {}
virtual const char* what() const noexcept { return m_message.c_str(); }
ResourceNotFound(std::string resource_name)
: m_message{"ResourceManager: Resource not found: " + resource_name} {}
virtual const char *what() const noexcept { return m_message.c_str(); }

private:
const std::string m_message;
};


// This class holds a pointer to the beginning of binary data for the requested resource
// and the length/size (in bytes) of this data. (length and size are the same thing).
// This class holds a pointer to the beginning of binary data for the requested
// resource and the length/size (in bytes) of this data. (length and size are
// the same thing).
// -------------------------------------------------------------------------------------------
// If constructor is called with an invalid resource name ResourceNotFound exception is thrown
// Compile with -DRM_NO_EXCEPTIONS to disable throwing on invalid resource name.
// If constructor is called with an invalid resource name ResourceNotFound
// exception is thrown Compile with -DRM_NO_EXCEPTIONS to disable throwing on
// invalid resource name.
// -------------------------------------------------------------------------------------------
// If exceptions are disabled and constructor is called with an invalid resource name
// then the pointer to the data equials nullptr and length/size equals 0.
// In this case you can use isValid() to determine whether construction was successful or not.
// If exceptions are disabled and constructor is called with an invalid resource
// name then the pointer to the data equials nullptr and length/size equals 0.
// In this case you can use isValid() to determine whether construction was
// successful or not.
// ===========================================================================================
// Avaliable functions:
// -- const bool isValid() const noexcept:
// # returns true if construction was successful, false otherwise.
// #
// -- const unsigned char* const data() const noexcept:
// # returns the pointer to the beginning of binary data or nullptr if construction failed.
// # The data is null-terminated in the end.
// # returns the pointer to the beginning of binary data or nullptr if
// construction failed. # The data is null-terminated in the end.
// #
// -- const char* const c_str() const noexcept:
// # returns the pointer to the beginning of binary data or nullptr if construction failed.
// # The data is null-terminated in the end.
// # returns the pointer to the beginning of binary data or nullptr if
// construction failed. # The data is null-terminated in the end.
// #
// -- std::string string() const:
// # returns std::string based on the binary data with same length as the data.
// # If there are zeroes in the middle of the data string will contain them anyway.
// # If there are zeroes in the middle of the data string will contain them
// anyway.
// #
// -- const size_t size() const noexcept:
// # returns size of the data in bytes or 0 if construction failed.
Expand All @@ -57,18 +63,28 @@ class ResourceHandle {
public:
ResourceHandle(std::string resource_name);

const bool isValid() const noexcept { if (m_data_start) return true; else return false; }
const bool isValid() const noexcept {
if (m_data_start)
return true;
else
return false;
}

const size_t size() const noexcept { return m_data_len; }
const size_t length() const noexcept { return m_data_len; }

const unsigned char* const data() const noexcept { return m_data_start; }
const unsigned char *const data() const noexcept { return m_data_start; }

const char* const c_str() const noexcept { return reinterpret_cast<const char*>(m_data_start); }
std::string string() const { return std::string(reinterpret_cast<const char*>(m_data_start), m_data_len); }
const char *const c_str() const noexcept {
return reinterpret_cast<const char *>(m_data_start);
}
std::string string() const {
return std::string(reinterpret_cast<const char *>(m_data_start),
m_data_len);
}

private:
const unsigned char* m_data_start;
const unsigned char *m_data_start;
size_t m_data_len;
};

Expand Down
170 changes: 95 additions & 75 deletions ResourceManager/src/embed_resource.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
// Copyright (c) 2018 Johnny Borov <JohnnyBorov@gmail.com>. Released under MIT License.
// Copyright (c) 2018 Johnny Borov <JohnnyBorov@gmail.com>. Released under MIT
// License.

#include <fstream>
#include <string>

void generateResourceDataSourceFile(char* resource_name, char* resource_file_name, char* output_file_name);
void generateResourcesConfigSourceFile(char* resource_names_list, char* config_file_name);
void generateResourceDataSourceFile(char *resource_name,
char *resource_file_name,
char *output_file_name);
void generateResourcesConfigSourceFile(char *resource_names_list,
char *config_file_name);
std::string modifyFileName(std::string file_name);


int main(int argc, char* argv[]) {
int main(int argc, char *argv[]) {
// working directory = CMAKE_BINARY_DIR when called from cmake custom command
if (std::string(argv[1]) == "-data") {
if (argc == 5)
Expand All @@ -25,19 +28,26 @@ int main(int argc, char* argv[]) {
return 0;
}


// generate a cpp file (e.g. resources/res.txt.cpp) containing global extern array of const unsigned char
// of binary data read from the requested input file (CMAKE_SOURCE_DIR/resources/res.txt) plus null-terminator
// in the end of data and a global extern const size_t size of this data in bytes (without null-terminator)
void generateResourceDataSourceFile(char* resource_name, char* resource_file_name, char* output_file_name) {
std::string name{ resource_name }; // e.g. "resources/res.txt"
std::string modified_name = modifyFileName(name); // becomes "resources__slash__res__dot__txt"

std::ifstream ifs{ resource_file_name, std::ios::binary }; // e.g. reads from CMAKE_SOURCE_DIR/resources/res.txt
std::ofstream ofs{ output_file_name }; // e.g. writes to resources/res.txt.cpp
// generate a cpp file (e.g. resources/res.txt.cpp) containing global extern
// array of const unsigned char of binary data read from the requested input
// file (CMAKE_SOURCE_DIR/resources/res.txt) plus null-terminator in the end of
// data and a global extern const size_t size of this data in bytes (without
// null-terminator)
void generateResourceDataSourceFile(char *resource_name,
char *resource_file_name,
char *output_file_name) {
std::string name{resource_name}; // e.g. "resources/res.txt"
std::string modified_name =
modifyFileName(name); // becomes "resources__slash__res__dot__txt"

std::ifstream ifs{
resource_file_name,
std::ios::binary}; // e.g. reads from CMAKE_SOURCE_DIR/resources/res.txt
std::ofstream ofs{output_file_name}; // e.g. writes to resources/res.txt.cpp

ofs << "#include <cstddef>\n";
ofs << "extern const unsigned char _resource_" << modified_name << "_data[] = {\n";
ofs << "extern const unsigned char _resource_" << modified_name
<< "_data[] = {\n";

int line_count = 0;
char c;
Expand All @@ -50,28 +60,31 @@ void generateResourceDataSourceFile(char* resource_name, char* resource_file_nam
}
}

ofs << "\'\\0\'"; // null-terminator in case data is going to be interprited as a c string
ofs << "\'\\0\'"; // null-terminator in case data is going to be interprited
// as a c string
ofs << "};\n";
// -1 excludes null-terminator
ofs << "extern const size_t _resource_" << modified_name << "_len = sizeof(_resource_" << modified_name << "_data) - 1;\n";
ofs << "extern const size_t _resource_" << modified_name
<< "_len = sizeof(_resource_" << modified_name << "_data) - 1;\n";
}


// generate a cpp file (e.g. __resources__config.cpp) that defines ResourceHandle constructor.
// The defenition contains the hardcoded mapping of original resource names (e.g. "resources/res.txt")
// to their corresponding global extern variables names. Thus it returns a handle which contains pointer to
// the beginning of global extern array of const unsigned char and its size (see -data option description)
void generateResourcesConfigSourceFile(char* resource_names_list, char* config_file_name) {
// generate a cpp file (e.g. __resources__config.cpp) that defines
// ResourceHandle constructor. The defenition contains the hardcoded mapping of
// original resource names (e.g. "resources/res.txt") to their corresponding
// global extern variables names. Thus it returns a handle which contains
// pointer to the beginning of global extern array of const unsigned char and
// its size (see -data option description)
void generateResourcesConfigSourceFile(char *resource_names_list,
char *config_file_name) {
std::ofstream ofs(config_file_name); // e.g. writes to __resources__config.cpp

ofs <<
"#include \"ResourceManager/ResourceHandle.h\"\n"
"\n"
"ResourceHandle::ResourceHandle(std::string resource_name) {\n"
" ";

ofs << "#include \"ResourceManager/ResourceHandle.h\"\n"
"\n"
"ResourceHandle::ResourceHandle(std::string resource_name) {\n"
" ";

std::string resource_names{resource_names_list}; // e.g. "res.txt;res2.txt;resources/res.txt"
std::string resource_names{
resource_names_list}; // e.g. "res.txt;res2.txt;resources/res.txt"
size_t length = resource_names.length();
size_t start_pos = 0;
do {
Expand All @@ -83,59 +96,66 @@ void generateResourcesConfigSourceFile(char* resource_names_list, char* config_f
std::string name = resource_names.substr(start_pos, end_pos - start_pos);
std::string modified_name = modifyFileName(name);

ofs <<
"if (resource_name == \"" << name << "\") {\n"
" extern const unsigned char _resource_" << modified_name << "_data[];\n"
" extern const size_t _resource_" << modified_name << "_len;\n"
" m_data_start = _resource_" << modified_name << "_data;\n"
" m_data_len = _resource_" << modified_name << "_len;\n"
" } else ";

start_pos = end_pos + 1; // e.g. start next read from res2... position in "res.txt;res2.txt;resources/res.txt"
ofs << "if (resource_name == \"" << name
<< "\") {\n"
" extern const unsigned char _resource_"
<< modified_name
<< "_data[];\n"
" extern const size_t _resource_"
<< modified_name
<< "_len;\n"
" m_data_start = _resource_"
<< modified_name
<< "_data;\n"
" m_data_len = _resource_"
<< modified_name
<< "_len;\n"
" } else ";

start_pos = end_pos + 1; // e.g. start next read from res2... position in
// "res.txt;res2.txt;resources/res.txt"
} while (start_pos < length);


ofs <<
"{\n"
"#ifdef RM_NO_EXCEPTIONS\n"
" m_data_start = nullptr;\n"
" m_data_len = 0;\n"
"#else\n"
" throw ResourceNotFound{resource_name};\n"
"#endif\n"
" }\n"
"}\n";
ofs << "{\n"
"#ifdef RM_NO_EXCEPTIONS\n"
" m_data_start = nullptr;\n"
" m_data_len = 0;\n"
"#else\n"
" throw ResourceNotFound{resource_name};\n"
"#endif\n"
" }\n"
"}\n";
}


// replace symbols that cant be used in c++ identeficator name
// e.g. "resources/res.txt" -> "resources__slash__res__dot__txt"
std::string modifyFileName(std::string file_name) {
size_t search_from_pos = 0;
size_t replace_from_pos;
while ((replace_from_pos = file_name.find_first_of(".- /\\", search_from_pos)) != std::string::npos) {
switch (file_name[replace_from_pos]) {
case '.':
file_name.replace(replace_from_pos, 1, "__dot__");
search_from_pos = replace_from_pos + 7; // shift len(__dot__) = 5 symbols
break;
case '-':
file_name.replace(replace_from_pos, 1, "__dash__");
search_from_pos = replace_from_pos + 8;
break;
case ' ':
file_name.replace(replace_from_pos, 1, "__space__");
search_from_pos = replace_from_pos + 9;
break;
case '/':
file_name.replace(replace_from_pos, 1, "__slash__");
search_from_pos = replace_from_pos + 9;
break;
case '\\':
file_name.replace(replace_from_pos, 1, "__bslash__");
search_from_pos = replace_from_pos + 10;
break;
}
while ((replace_from_pos = file_name.find_first_of(
".- /\\", search_from_pos)) != std::string::npos) {
switch (file_name[replace_from_pos]) {
case '.':
file_name.replace(replace_from_pos, 1, "__dot__");
search_from_pos = replace_from_pos + 7; // shift len(__dot__) = 5 symbols
break;
case '-':
file_name.replace(replace_from_pos, 1, "__dash__");
search_from_pos = replace_from_pos + 8;
break;
case ' ':
file_name.replace(replace_from_pos, 1, "__space__");
search_from_pos = replace_from_pos + 9;
break;
case '/':
file_name.replace(replace_from_pos, 1, "__slash__");
search_from_pos = replace_from_pos + 9;
break;
case '\\':
file_name.replace(replace_from_pos, 1, "__bslash__");
search_from_pos = replace_from_pos + 10;
break;
}
}

return file_name;
Expand Down
10 changes: 6 additions & 4 deletions ResourceManager/test/src/test_main.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// Copyright (c) 2018 Johnny Borov <JohnnyBorov@gmail.com>. Released under MIT License.
// Copyright (c) 2018 Johnny Borov <JohnnyBorov@gmail.com>. Released under MIT
// License.

#include <iostream>
#include "ResourceManager/ResourceHandle.h"
#include <iostream>

void testInvalidResource() {
ResourceHandle rhdi("i_dont_exist"); // -DRM_NO_EXCEPTIONS to disable throw on invalid recource
ResourceHandle rhdi("i_dont_exist"); // -DRM_NO_EXCEPTIONS to disable throw on
// invalid recource
std::cout << "rhdi is valid = " << rhdi.isValid() << '\n';
}

Expand All @@ -21,7 +23,7 @@ int main() {
std::cout << "rh3 size = " << rh3.size() << '\n';

testInvalidResource();
} catch (const ResourceNotFound& e) {
} catch (const ResourceNotFound &e) {
std::cout << e.what() << '\n';
}

Expand Down
Loading
Loading