Filesystem.cpp165 lines · 3.4 KiB
| 1 | #include "Filesystem.hpp" |
| 2 | |
| 3 | #include <cstring> |
| 4 | #include <filesystem> |
| 5 | #include <fstream> |
| 6 | #include <iostream> |
| 7 | |
| 8 | static std::string make_path_relative(std::string & path, std::string & root) |
| 9 | { |
| 10 | return std::filesystem::relative(path, root); |
| 11 | } |
| 12 | |
| 13 | static bool is_directory(std::string & path) |
| 14 | { |
| 15 | return std::filesystem::is_directory(path); |
| 16 | } |
| 17 | |
| 18 | bool Filesystem::AddSingleFile(std::string path, std::string root) |
| 19 | { |
| 20 | if (is_directory(path) == true) |
| 21 | { |
| 22 | return true; |
| 23 | } |
| 24 | |
| 25 | std::ifstream ifs(path, std::ios::binary | std::ios::ate); |
| 26 | |
| 27 | if (!ifs) |
| 28 | { |
| 29 | return false; |
| 30 | } |
| 31 | |
| 32 | auto end = ifs.tellg(); |
| 33 | if (end <= 0) |
| 34 | { |
| 35 | return false; |
| 36 | } |
| 37 | if (!ifs.seekg(0, std::ios::beg)) |
| 38 | { |
| 39 | return false; |
| 40 | } |
| 41 | |
| 42 | auto size = end - ifs.tellg(); |
| 43 | |
| 44 | if (size <= 0) |
| 45 | { |
| 46 | return false; |
| 47 | } |
| 48 | |
| 49 | struct file_data fd = {}; |
| 50 | try |
| 51 | { |
| 52 | fd.data.resize(size); |
| 53 | } |
| 54 | catch (const std::exception & e) |
| 55 | { |
| 56 | return false; |
| 57 | } |
| 58 | |
| 59 | if (!ifs.read((char *)fd.data.data(), fd.data.size())) |
| 60 | { |
| 61 | return false; |
| 62 | } |
| 63 | |
| 64 | std::string relpath = make_path_relative(path, root); |
| 65 | if (m_Files.count(relpath) > 0) |
| 66 | { |
| 67 | std::cout << "Adding file: " << path << " (" << size << " bytes) and overwriting " << relpath << " to " << this |
| 68 | << std::endl; |
| 69 | } |
| 70 | else |
| 71 | { |
| 72 | std::cout << "Adding file: " << path << " (" << size << " bytes) as " << relpath << " to " << this << std::endl; |
| 73 | } |
| 74 | |
| 75 | { |
| 76 | char const * const mp = magic_file(m_Magic, path.c_str()); |
| 77 | if (mp != NULL) |
| 78 | { |
| 79 | fd.mime = magic_file(m_Magic, path.c_str()); |
| 80 | } |
| 81 | else |
| 82 | { |
| 83 | fd.mime = "application/octet-stream"; |
| 84 | } |
| 85 | m_Files[relpath] = fd; |
| 86 | } |
| 87 | |
| 88 | return true; |
| 89 | } |
| 90 | |
| 91 | bool Filesystem::Scan(std::string root) |
| 92 | { |
| 93 | return Scan(root, {}, true); |
| 94 | } |
| 95 | |
| 96 | bool Filesystem::Scan(std::string root, std::vector<std::string> extensions, bool exclude_extensions) |
| 97 | { |
| 98 | bool retval = true; |
| 99 | |
| 100 | for (const auto & entry : std::filesystem::recursive_directory_iterator(root)) |
| 101 | { |
| 102 | std::string ext = std::filesystem::path(entry).extension(); |
| 103 | bool found_extension = false; |
| 104 | |
| 105 | for (const auto & extension : extensions) |
| 106 | { |
| 107 | if (ext == "." + extension) |
| 108 | { |
| 109 | found_extension = true; |
| 110 | break; |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | if (found_extension == true && exclude_extensions == false) |
| 115 | { |
| 116 | if (AddSingleFile(entry.path(), root) == false) |
| 117 | { |
| 118 | retval = false; |
| 119 | } |
| 120 | } |
| 121 | if (found_extension == false && exclude_extensions == true) |
| 122 | { |
| 123 | if (AddSingleFile(entry.path(), root) == false) |
| 124 | { |
| 125 | retval = false; |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | return retval; |
| 131 | } |
| 132 | |
| 133 | FilesDict & Filesystem::GetFiles() |
| 134 | { |
| 135 | return m_Files; |
| 136 | } |
| 137 | |
| 138 | void Filesystem::GetFilenamesSorted(std::vector<std::string> & sortedFilenames) |
| 139 | { |
| 140 | for (auto const & f : GetFiles()) |
| 141 | { |
| 142 | sortedFilenames.push_back(f.first); |
| 143 | } |
| 144 | std::sort(sortedFilenames.begin(), sortedFilenames.end()); |
| 145 | #if 1 |
| 146 | for (auto const & f : sortedFilenames) |
| 147 | { |
| 148 | std::cout << "Added file (alnum sorted): " << f << std::endl; |
| 149 | } |
| 150 | #endif |
| 151 | } |
| 152 | |
| 153 | void Filesystem::MagicInit() |
| 154 | { |
| 155 | m_Magic = magic_open(MAGIC_MIME_TYPE); |
| 156 | |
| 157 | magic_load(m_Magic, NULL); |
| 158 | magic_compile(m_Magic, NULL); |
| 159 | } |
| 160 | |
| 161 | void Filesystem::MagicClose() |
| 162 | { |
| 163 | magic_close(m_Magic); |
| 164 | } |
| 165 |