From fc3b502ed585095bc0860ee7c9a21259fdf7abe1 Mon Sep 17 00:00:00 2001 From: technoyes Date: Mon, 28 Aug 2023 20:16:38 +0200 Subject: [PATCH] Add get_as_string() and get_as_raw_ptr() This change adds support for directly fetching resource data as std::string as well as raw "const char *" combined with std::size_t. This allows cleaner code in use cases where the existing file interface is overkill. --- CMakeRC.cmake | 21 +++++++++++++++++++-- README.md | 11 +++++++++++ tests/CMakeLists.txt | 14 ++++++++++++++ tests/simple_raw_ptr.cpp | 12 ++++++++++++ tests/simple_string.cpp | 11 +++++++++++ 5 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 tests/simple_raw_ptr.cpp create mode 100644 tests/simple_string.cpp diff --git a/CMakeRC.cmake b/CMakeRC.cmake index 6a5147a..745f562 100644 --- a/CMakeRC.cmake +++ b/CMakeRC.cmake @@ -340,7 +340,7 @@ public: : _index(&index) {} - file open(const std::string& path) const { + const detail::file_data& _get_file_data(const std::string& path) const { auto entry_ptr = _get(path); if (!entry_ptr || !entry_ptr->is_file()) { #ifdef CMRC_NO_EXCEPTIONS @@ -350,10 +350,27 @@ public: throw std::system_error(make_error_code(std::errc::no_such_file_or_directory), path); #endif } - auto& dat = entry_ptr->as_file(); + return entry_ptr->as_file(); + } + + file open(const std::string& path) const { + auto& dat = _get_file_data(path); return file{dat.begin_ptr, dat.end_ptr}; } + std::string get_as_string(const std::string& path) const { + auto& dat = _get_file_data(path); + auto& f = file{dat.begin_ptr, dat.end_ptr}; + return std::string{dat.begin_ptr, f.size()}; + } + + const char *get_as_raw_ptr(const std::string& path, std::size_t& file_size) const { + auto& dat = _get_file_data(path); + auto& f = file{dat.begin_ptr, dat.end_ptr}; + file_size = f.size(); + return dat.begin_ptr; + } + bool is_file(const std::string& path) const noexcept { auto entry_ptr = _get(path); return entry_ptr && entry_ptr->is_file(); diff --git a/README.md b/README.md index 5672799..45cb2d1 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,13 @@ statically allocated resource library data. - `open(const std::string& path) -> cmrc::file` - Opens and returns a non-directory `file` object at `path`, or throws `std::system_error()` on error. +- `get_as_string(const std::string& path) -> std::string` - Returns the + non-directory data at `path` as a `std::string`, or throws `std::system_error()` + on error. +- `get_as_raw_ptr(const std::string& path, std::size_t& file_size) -> const char *` - + Returns the non-directory data at `path` as a raw `const char *` pointer and updates + the supplied `file_size` reference with the data size, or throws + `std::system_error()` on error. - `is_file(const std::string& path) -> bool` - Returns `true` if the given `path` names a regular file, `false` otherwise. - `is_directory(const std::string& path) -> bool` - Returns `true` if the given @@ -179,6 +186,10 @@ the library using `cmrc_add_resources` with the name of the library and the paths to any additional resources that you wish to compile in. This way you can lazily add resources to the library as your configure script runs. +Resources are always stored with an extra trailing `null` byte to facilitate +the direct use of data as C strings if needed. The `null` byte is not a part of +the actual data and does not count towards its size. + Both `cmrc_add_resource_library` and `cmrc_add_resources` take two additional keyword parameters: diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1a55c79..ca09875 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -38,6 +38,20 @@ cmrc_add_test( subdir_a/subdir_b/file_b.txt ) +cmrc_add_test( + NAME simple_string + PASS_REGEX "^Hello, world!" + RESOURCES + hello.txt + ) + +cmrc_add_test( + NAME simple_raw_ptr + PASS_REGEX "^Hello, world!" + RESOURCES + hello.txt + ) + cmrc_add_test( NAME flower RESOURCES flower.jpg diff --git a/tests/simple_raw_ptr.cpp b/tests/simple_raw_ptr.cpp new file mode 100644 index 0000000..9ad547c --- /dev/null +++ b/tests/simple_raw_ptr.cpp @@ -0,0 +1,12 @@ +#include + +#include + +CMRC_DECLARE(simple_raw_ptr); + +int main() { + auto fs = cmrc::simple_raw_ptr::get_filesystem(); + std::size_t sz; + const char *data = fs.get_as_raw_ptr("hello.txt", sz); + std::cout << std::string(data, sz) << '\n'; +} diff --git a/tests/simple_string.cpp b/tests/simple_string.cpp new file mode 100644 index 0000000..b2d1f23 --- /dev/null +++ b/tests/simple_string.cpp @@ -0,0 +1,11 @@ +#include + +#include + +CMRC_DECLARE(simple_string); + +int main() { + auto fs = cmrc::simple_string::get_filesystem(); + std::string a_string = fs.get_as_string("hello.txt"); + std::cout << a_string << '\n'; +}