utility 2026.1.9
A comprehensive C++ utilities library tailored for the development of modern desktop and extended reality (XR) applications.
Loading...
Searching...
No Matches
default_system_io.cpp
1/*
2 Copyright (c) 2026 ETIB Corporation
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in
6 the Software without restriction, including without limitation the rights to
7 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8 of the Software, and to permit persons to whom the Software is furnished to do
9 so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 SOFTWARE.
21 */
22
23#include <filesystem>
24#include <memory>
25
27
28#include "utility/system_io/default_system_io.hpp"
29
30namespace
31{
32 std::string NormalizePath(const std::string &path)
33 {
34 return std::filesystem::path(path).lexically_normal().generic_string();
35 }
36} // namespace
37
39 : _logger(
40 std::make_unique<utility::logging::DefaultLogger>("DefaultSystemIO"))
41{
42}
43
45
50
52{
53 return *_logger;
54}
55
56bool utility::DefaultSystemIO::loadDirectory(const std::string &directory)
57{
58 std::error_code error;
59 const std::filesystem::path directoryPath(directory);
60 if (!std::filesystem::exists(directoryPath, error)
61 || !std::filesystem::is_directory(directoryPath, error)) {
62 getLogger().warning()
63 << "Asset directory does not exist or is invalid: " << directory;
64 return false;
65 }
66
67 bool success = true;
68 for (const auto &entry:
69 std::filesystem::directory_iterator(directoryPath, error)) {
70 if (error) {
71 getLogger().warning()
72 << "Failed to iterate asset directory: " << directory;
73 return false;
74 }
75
76 if (entry.is_regular_file(error) && !error) {
77 const std::string path = entry.path().string();
78 if (this->add(path) == nullptr) {
79 getLogger().warning() << "Failed to load asset: " << path;
80 success = false;
81 }
82 }
83 }
84
85 return success;
86}
87
88std::shared_ptr<utility::File>
89 utility::DefaultSystemIO::add(const std::string &path)
90{
91 const std::string key = NormalizePath(path);
92 if (this->exists(key)) {
93 return this->open(key);
94 }
95
96 std::ifstream file(key, std::ios::binary | std::ios::ate);
97
98 if (!file.is_open()) {
99 getLogger().warning() << "Failed to open file: " << key;
100 return nullptr;
101 }
102
103 const std::streamsize fileSize = file.tellg();
104 if (fileSize < 0) {
105 getLogger().warning() << "Failed to read file size: " << key;
106 return nullptr;
107 }
108
109 std::string content;
110 content.resize(static_cast<size_t>(fileSize));
111 file.seekg(0, std::ios::beg);
112 if (!content.empty()) {
113 file.read(content.data(), static_cast<std::streamsize>(content.size()));
114 if (!file) {
115 getLogger().warning() << "Failed to read file content: " << key;
116 return nullptr;
117 }
118 }
119 file.close();
120
121 auto asset = std::make_shared<utility::File>(path, content);
122 if (!asset) {
123 getLogger().warning() << "Failed to create File for: " << key;
124 return nullptr;
125 }
126
127 _assets[key] = asset;
128 return asset;
129}
130
131void utility::DefaultSystemIO::remove(const std::string &path, bool save)
132{
133 const std::string key = NormalizePath(path);
134 auto it = _assets.find(key);
135 if (it != _assets.end()) {
136 if (save) {
137 this->save(key);
138 }
139 _assets.erase(it);
140 } else {
141 getLogger().warning() << "Asset not found: " << key;
142 }
143}
144
145bool utility::DefaultSystemIO::save(const std::string &path,
146 const std::string &newPath)
147{
148 const std::string key = NormalizePath(path);
149 auto it = _assets.find(key);
150 if (it == _assets.end()) {
151 getLogger().warning() << "Asset not found: " << key;
152 return false;
153 }
154
155 const auto &content = it->second->data();
156 const std::string savePath = newPath.empty() ? key : newPath;
157
158 std::error_code error;
159 const auto parentPath = std::filesystem::path(savePath).parent_path();
160 if (!parentPath.empty()) {
161 std::filesystem::create_directories(parentPath, error);
162 if (error) {
163 getLogger().warning()
164 << "Failed to create parent directories for: " << savePath;
165 return false;
166 }
167 }
168
169 std::ofstream file(savePath, std::ios::binary);
170 if (!file.is_open()) {
171 getLogger().warning()
172 << "Failed to open file for writing: " << savePath;
173 return false;
174 }
175
176 file.write(reinterpret_cast<const char *>(content.data()), content.size());
177 if (!file) {
178 getLogger().warning() << "Failed to write file content: " << savePath;
179 return false;
180 }
181 file.close();
182
183 return true;
184}
void remove(const std::string &path, bool save=true) override
Removes an asset from the manager.
bool loadDirectory(const std::string &directory) override
Loads assets from a directory.
DefaultSystemIO()
Constructs a DefaultSystemIO.
bool save(const std::string &path, const std::string &newPath="") override
Saves an asset to the file system.
std::shared_ptr< utility::File > add(const std::string &path) override
Adds an asset to the manager by loading it from the file system.
utility::logging::Logger & getLogger(void)
Get the internal logger.
~DefaultSystemIO() override
Default destructor for DefaultSystemIO.
Abstract logger interface defining stream-style logging operations.
Definition logger.hpp:96
Platform-specific default logger alias.
The utility namespace contains classes and functions for the utility project.
Definition cache.hpp:34