Cogs.Core
DefaultIOHandler.cpp
1#include "DefaultIOHandler.h"
2
3#include <fstream>
4#include <string>
5#include <regex>
6
7#ifndef EMSCRIPTEN
8#include <filesystem>
9
10namespace sys = std::filesystem;
11#endif
12
13namespace
14{
15 void autoExpandEnvironmentVariables(std::string & text)
16 {
17 static std::regex env("%([0-9A-Za-z\\/]*)%");
18 std::smatch match;
19 while (std::regex_search(text, match, env)) {
20 const char * s = std::getenv(match[1].str().c_str());
21 const std::string var(s == nullptr ? "" : s);
22 text.replace(match[0].first, match[0].second, var);
23 }
24 }
25
26 std::string expandEnvironmentVariables(const std::string & input)
27 {
28 std::string text = input;
29 autoExpandEnvironmentVariables(text);
30 return text;
31 }
32
33 std::string getPath(Cogs::IIOHandler::FileType type, const std::string & fileName)
34 {
35 if (type == Cogs::IIOHandler::FileType::ShaderCache) {
36 std::string path = std::string("%LOCALAPPDATA%") + "\\Kongsberg Digital\\Cogs.Rendering\\ShaderCache\\" + fileName;
37 return expandEnvironmentVariables(path);
38 }
39
40 return{};
41 }
42}
43
44bool Cogs::DefaultIOHandler::openFile(const StringView & fileName, std::string & content)
45{
46 return resolveFile("", fileName, content);
47}
48
49bool Cogs::DefaultIOHandler::resolveFile(const StringView & /*source*/, const StringView & fileName, std::string & content)
50{
51 std::ifstream file;
52
53 for (auto & searchPath : searchPaths) {
54 const auto & path = searchPath.size() ? searchPath + std::string(fileName) : std::string(fileName);
55
56 file.open(path, std::ios::in);
57
58 if (file.is_open()) break;
59 }
60 if (!file.is_open()) {
61 fprintf(stderr, "Failed to load \"%.*s\"\n", StringViewFormat(fileName));
62 return false;
63 }
64
65 file.seekg(0, std::ios::end);
66
67 const auto fileSize = file.tellg();
68
69 if (!fileSize) {
70 return false;
71 }
72
73 content.resize(content.size() + fileSize, ' ');
74
75 file.seekg(0, std::ios::beg);
76
77 file.read(&content[0], fileSize);
78
79 file.close();
80
81 return true;
82}
83
84void Cogs::DefaultIOHandler::addSearchPath(const StringView & path)
85{
86 searchPaths.push_back(std::string(path));
87}
88
89void Cogs::DefaultIOHandler::pushSearchPaths()
90{
91 pushedSearchPaths = searchPaths;
92}
93
94void Cogs::DefaultIOHandler::popSearchPaths()
95{
96 searchPaths = std::move(pushedSearchPaths);
97}
98
99bool Cogs::DefaultIOHandler::exists(FileType type, const StringView & fileName)
100{
101#ifndef EMSCRIPTEN
102 sys::path path(getPath(type, std::string(fileName)));
103
104 return sys::exists(path);
105#else
106 (void)type;
107 (void)fileName;
108 return false;
109#endif
110}
111
112bool Cogs::DefaultIOHandler::writeBinaryFile(FileType type, const StringView & fileName, const void * content, size_t contentSize)
113{
114#ifndef EMSCRIPTEN
115 sys::path path(getPath(type, std::string(fileName)));
116 sys::create_directories(path.parent_path());
117
118 std::fstream file(path.string(), std::ios::binary | std::ios::out);
119
120 file.seekg(0, std::ios::beg);
121
122 file.write((const char *)content, contentSize);
123
124 file.close();
125
126 return true;
127#else
128 (void)type;
129 (void)fileName;
130 (void)content;
131 (void)contentSize;
132 return false;
133#endif
134}
135
136bool Cogs::DefaultIOHandler::openBinaryFile(FileType type, const StringView & fileName, std::vector<uint8_t> & content)
137{
138 std::fstream file(getPath(type, std::string(fileName)), std::ios::binary | std::ios::in);
139
140 if (!file.is_open()) return false;
141
142 file.seekg(0, std::ios::end);
143
144 const auto fileSize = file.tellg();
145
146 if (!fileSize) {
147 return false;
148 }
149
150 content.resize(content.size() + fileSize, ' ');
151
152 file.seekg(0, std::ios::beg);
153
154 file.read((char *)content.data(), fileSize);
155
156 file.close();
157
158 return true;
159}
Provides a weakly referenced view over the contents of a string.
Definition: StringView.h:24
bool openFile(const StringView &fileName, std::string &content) override
Callback method used to open files.
bool resolveFile(const StringView &source, const StringView &fileName, std::string &content) override
Callback method used to resolve include statements in shader code and get the contents to include.