1/*
2---------------------------------------------------------------------------
3Open Asset Import Library (assimp)
4---------------------------------------------------------------------------
5
6Copyright (c) 2006-2022, assimp team
7
8All rights reserved.
9
10Redistribution and use of this software in source and binary forms,
11with or without modification, are permitted provided that the following
12conditions are met:
13
14* Redistributions of source code must retain the above
15 copyright notice, this list of conditions and the
16 following disclaimer.
17
18* Redistributions in binary form must reproduce the above
19 copyright notice, this list of conditions and the
20 following disclaimer in the documentation and/or other
21 materials provided with the distribution.
22
23* Neither the name of the assimp team, nor the names of its
24 contributors may be used to endorse or promote products
25 derived from this software without specific prior
26 written permission of the assimp team.
27
28THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39---------------------------------------------------------------------------
40*/
41/** @file Default implementation of IOSystem using the standard C file functions */
42
43#include <assimp/StringComparison.h>
44
45#include <assimp/DefaultIOStream.h>
46#include <assimp/DefaultIOSystem.h>
47#include <assimp/ai_assert.h>
48#include <stdlib.h>
49#include <assimp/DefaultLogger.hpp>
50
51#ifdef __unix__
52# include <stdlib.h>
53# include <sys/param.h>
54#endif
55
56#ifdef _WIN32
57# include <windows.h>
58#endif
59
60using namespace Assimp;
61
62#ifdef _WIN32
63
64const std::wstring wdummy;
65
66static std::wstring Utf8ToWide(const char *in) {
67 if (nullptr == in) {
68 return wdummy;
69 }
70 int size = MultiByteToWideChar(CP_UTF8, 0, in, -1, nullptr, 0);
71 // size includes terminating null; std::wstring adds null automatically
72 std::wstring out(static_cast<size_t>(size) - 1, L'\0');
73 MultiByteToWideChar(CP_UTF8, 0, in, -1, &out[0], size);
74
75 return out;
76}
77
78const std::string dummy;
79
80static std::string WideToUtf8(const wchar_t *in) {
81 if (nullptr == in) {
82 return dummy;
83 }
84 int size = WideCharToMultiByte(CP_UTF8, 0, in, -1, nullptr, 0, nullptr, nullptr);
85 // size includes terminating null; std::string adds null automatically
86 std::string out(static_cast<size_t>(size) - 1, '\0');
87 WideCharToMultiByte(CP_UTF8, 0, in, -1, &out[0], size, nullptr, nullptr);
88
89 return out;
90}
91#endif
92
93// ------------------------------------------------------------------------------------------------
94// Tests for the existence of a file at the given path.
95bool DefaultIOSystem::Exists(const char *pFile) const {
96#ifdef _WIN32
97 struct __stat64 filestat;
98 if (_wstat64(Utf8ToWide(pFile).c_str(), &filestat) != 0) {
99 return false;
100 }
101#else
102 FILE *file = ::fopen(filename: pFile, modes: "rb");
103 if (!file) {
104 return false;
105 }
106
107 ::fclose(stream: file);
108#endif
109
110 return true;
111}
112
113// ------------------------------------------------------------------------------------------------
114// Open a new file with a given path.
115IOStream *DefaultIOSystem::Open(const char *strFile, const char *strMode) {
116 ai_assert(strFile != nullptr);
117 ai_assert(strMode != nullptr);
118 FILE *file;
119#ifdef _WIN32
120 std::wstring name = Utf8ToWide(strFile);
121 if (name.empty()) {
122 return nullptr;
123 }
124
125 file = ::_wfopen(name.c_str(), Utf8ToWide(strMode).c_str());
126#else
127 file = ::fopen(filename: strFile, modes: strMode);
128#endif
129 if (!file) {
130 return nullptr;
131 }
132
133 return new DefaultIOStream(file, strFile);
134}
135
136// ------------------------------------------------------------------------------------------------
137// Closes the given file and releases all resources associated with it.
138void DefaultIOSystem::Close(IOStream *pFile) {
139 delete pFile;
140}
141
142// ------------------------------------------------------------------------------------------------
143// Returns the operation specific directory separator
144char DefaultIOSystem::getOsSeparator() const {
145#ifndef _WIN32
146 return '/';
147#else
148 return '\\';
149#endif
150}
151
152// ------------------------------------------------------------------------------------------------
153// IOSystem default implementation (ComparePaths isn't a pure virtual function)
154bool IOSystem::ComparePaths(const char *one, const char *second) const {
155 return !ASSIMP_stricmp(s1: one, s2: second);
156}
157
158// ------------------------------------------------------------------------------------------------
159// Convert a relative path into an absolute path
160inline static std::string MakeAbsolutePath(const char *in) {
161 ai_assert(in);
162 std::string out;
163#ifdef _WIN32
164 wchar_t *ret = ::_wfullpath(nullptr, Utf8ToWide(in).c_str(), 0);
165 if (ret) {
166 out = WideToUtf8(ret);
167 free(ret);
168 }
169#else
170 char *ret = realpath(name: in, resolved: nullptr);
171 if (ret) {
172 out = ret;
173 free(ptr: ret);
174 }
175#endif
176 else {
177 // preserve the input path, maybe someone else is able to fix
178 // the path before it is accessed (e.g. our file system filter)
179 ASSIMP_LOG_WARN("Invalid path: ", std::string(in));
180 out = in;
181 }
182 return out;
183}
184
185// ------------------------------------------------------------------------------------------------
186// DefaultIOSystem's more specialized implementation
187bool DefaultIOSystem::ComparePaths(const char *one, const char *second) const {
188 // chances are quite good both paths are formatted identically,
189 // so we can hopefully return here already
190 if (!ASSIMP_stricmp(s1: one, s2: second))
191 return true;
192
193 std::string temp1 = MakeAbsolutePath(in: one);
194 std::string temp2 = MakeAbsolutePath(in: second);
195
196 return !ASSIMP_stricmp(a: temp1, b: temp2);
197}
198
199// ------------------------------------------------------------------------------------------------
200std::string DefaultIOSystem::fileName(const std::string &path) {
201 std::string ret = path;
202 std::size_t last = ret.find_last_of(s: "\\/");
203 if (last != std::string::npos) ret = ret.substr(pos: last + 1);
204 return ret;
205}
206
207// ------------------------------------------------------------------------------------------------
208std::string DefaultIOSystem::completeBaseName(const std::string &path) {
209 std::string ret = fileName(path);
210 std::size_t pos = ret.find_last_of(c: '.');
211 if (pos != std::string::npos) ret = ret.substr(pos: 0, n: pos);
212 return ret;
213}
214
215// ------------------------------------------------------------------------------------------------
216std::string DefaultIOSystem::absolutePath(const std::string &path) {
217 std::string ret = path;
218 std::size_t last = ret.find_last_of(s: "\\/");
219 if (last != std::string::npos) ret = ret.substr(pos: 0, n: last);
220 return ret;
221}
222
223// ------------------------------------------------------------------------------------------------
224

source code of qtquick3d/src/3rdparty/assimp/src/code/Common/DefaultIOSystem.cpp