| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // This file is part of INSTINCT, the INS Toolkit for Integrated | ||
| 2 | // Navigation Concepts and Training by the Institute of Navigation of | ||
| 3 | // the University of Stuttgart, Germany. | ||
| 4 | // | ||
| 5 | // This Source Code Form is subject to the terms of the Mozilla Public | ||
| 6 | // License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| 7 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
| 8 | |||
| 9 | /// @file CMakeRC.hpp | ||
| 10 | /// @brief Handles compiling resources into the binary | ||
| 11 | /// @author T. Topp (topp@ins.uni-stuttgart.de) | ||
| 12 | /// @date 2021-08-24 | ||
| 13 | /// @see https://caiorss.github.io/C-Cpp-Notes/resources-executable.html#org7635e6a | ||
| 14 | |||
| 15 | #pragma once | ||
| 16 | #include <fstream> | ||
| 17 | |||
| 18 | #include <cmrc/cmrc.hpp> | ||
| 19 | |||
| 20 | /// @brief Defines the namespace of the filesystem | ||
| 21 | CMRC_DECLARE(instinct); | ||
| 22 | |||
| 23 | namespace cmrc | ||
| 24 | { | ||
| 25 | /// Credits: https://stackoverflow.com/a/13059195 | ||
| 26 | /// https://stackoverflow.com/questions/13059091/ | ||
| 27 | struct membuf : std::streambuf | ||
| 28 | { | ||
| 29 | /// @brief Constructor | ||
| 30 | /// @param[in] base Pointer to the start of the memory block | ||
| 31 | /// @param[in] size Size of the memory block | ||
| 32 | ✗ | membuf(const char* base, size_t size) | |
| 33 | ✗ | { | |
| 34 | ✗ | char* p{ const_cast<char*>(base) }; // NOLINT(cppcoreguidelines-pro-type-const-cast) | |
| 35 | ✗ | this->setg(p, p, p + size); | |
| 36 | ✗ | } | |
| 37 | /// @brief Destructor | ||
| 38 | ✗ | ~membuf() override = default; | |
| 39 | /// @brief Copy constructor | ||
| 40 | membuf(const membuf&) = default; | ||
| 41 | /// @brief Move constructor | ||
| 42 | membuf(membuf&&) = default; | ||
| 43 | /// @brief Copy assignment operator | ||
| 44 | membuf& operator=(const membuf&) = default; | ||
| 45 | /// @brief Move assignment operator | ||
| 46 | membuf& operator=(membuf&&) = default; | ||
| 47 | }; | ||
| 48 | |||
| 49 | /// Credits: https://stackoverflow.com/a/13059195 | ||
| 50 | /// https://stackoverflow.com/questions/13059091/ | ||
| 51 | struct memstream : virtual membuf, std::istream | ||
| 52 | { | ||
| 53 | /// @brief Constructor | ||
| 54 | /// @param[in] base Pointer to the start of the memory block | ||
| 55 | /// @param[in] end Pointer to the end of the memory block | ||
| 56 | ✗ | memstream(char const* base, char* const end) | |
| 57 | ✗ | : membuf(base, reinterpret_cast<uintptr_t>(end) - reinterpret_cast<uintptr_t>(base)), | |
| 58 | ✗ | std::istream(static_cast<std::streambuf*>(this)) {} | |
| 59 | |||
| 60 | /// @brief Constructor | ||
| 61 | /// @param[in] base Pointer to the start of the memory block | ||
| 62 | /// @param[in] size Size of the memory block | ||
| 63 | memstream(char const* base, size_t size) | ||
| 64 | : membuf(base, size), | ||
| 65 | std::istream(static_cast<std::streambuf*>(this)) {} | ||
| 66 | }; | ||
| 67 | } // namespace cmrc | ||
| 68 | |||
| 69 | /* Example Usage: https://caiorss.github.io/C-Cpp-Notes/resources-executable.html#org7635e6a | ||
| 70 | |||
| 71 | #define SHOW_EXPR(expr) \ | ||
| 72 | std::cout << " =>> EXPR( " << #expr << " ) = " << (expr) << std::endl | ||
| 73 | |||
| 74 | int main(int argc, const char** argv) | ||
| 75 | { | ||
| 76 | auto fs = cmrc::app1::get_filesystem(); | ||
| 77 | |||
| 78 | std::cout << std::boolalpha; | ||
| 79 | |||
| 80 | std::puts("\n ========= Experiment 1 ==>> Check resources =========="); | ||
| 81 | |||
| 82 | SHOW_EXPR( fs.is_file("resources/protocols.txt") ); | ||
| 83 | SHOW_EXPR( fs.is_file("resources/hosts.txt") ); | ||
| 84 | SHOW_EXPR( fs.is_file("/resources/hosts.txt") ); | ||
| 85 | SHOW_EXPR( fs.is_file("resources/protoc.txt") ); | ||
| 86 | |||
| 87 | std::puts("\n ========= Experiment 2 ==>> Read resource =========="); | ||
| 88 | { | ||
| 89 | auto fd1 = fs.open("resources/hosts.txt"); | ||
| 90 | |||
| 91 | // Read whole file content to string | ||
| 92 | auto st1 = std::string(fd1.begin(), fd1.end()); | ||
| 93 | |||
| 94 | std::cout << "\n Content of resources/hosts = \n" << st1 << std::endl; | ||
| 95 | } | ||
| 96 | |||
| 97 | std::puts("\n ========= Experiment 3 ===>> Read resource as stream ==="); | ||
| 98 | { | ||
| 99 | |||
| 100 | auto fd2 = fs.open("resources/protocols.txt"); | ||
| 101 | |||
| 102 | auto is = memstream ( const_cast<char*>(fd2.begin()), | ||
| 103 | const_cast<char*>(fd2.end()) ); | ||
| 104 | |||
| 105 | std::string line; | ||
| 106 | int n = 0; | ||
| 107 | while(std::getline(is, line) && n < 25) | ||
| 108 | std::cout << " line[" << n++ << "] = " << line << std::endl; | ||
| 109 | |||
| 110 | } | ||
| 111 | |||
| 112 | std::puts("\n ========= Experiment 4 ===>> Extract resource to file ==="); | ||
| 113 | { | ||
| 114 | auto fd = fs.open("resources/terminal.jpeg"); | ||
| 115 | |||
| 116 | auto is = memstream ( const_cast<char*>(fd.begin()), | ||
| 117 | const_cast<char*>(fd.end()) ); | ||
| 118 | |||
| 119 | |||
| 120 | auto ofs = std::ofstream("/tmp/picture.jpeg"); | ||
| 121 | // Redirect is to ofs | ||
| 122 | ofs << is.rdbuf(); | ||
| 123 | // Force writing | ||
| 124 | ofs.flush(); | ||
| 125 | } | ||
| 126 | |||
| 127 | return 0; | ||
| 128 | } | ||
| 129 | */ | ||
| 130 |