Files
UnrealEngine/Engine/Source/ThirdParty/Windows/glTF-Toolkit/WindowsMRAssetConverter/FileSystem.cpp
2025-05-18 13:04:45 +08:00

117 lines
3.5 KiB
C++

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
#include "stdafx.h"
#include "FileSystem.h"
std::wstring FileSystem::GetRelativePathWithTrailingSeparator(std::wstring from, std::wstring to)
{
// once c++17 filesystem is fully supported, this should become something like:
// return std::filesystem::relative(to, from) + std::filesystem::path::preferred_separator;
std::experimental::filesystem::path fromFS(std::experimental::filesystem::canonical(from));
std::experimental::filesystem::path toFS(std::experimental::filesystem::canonical(to));
std::experimental::filesystem::path result;
auto fromIter = fromFS.begin();
auto toIter = toFS.begin();
while (fromIter != fromFS.end() || toIter != toFS.end())
{
const auto& f = *fromIter;
const auto& t = *toIter;
if (f == t)
{
fromIter++;
toIter++;
}
else
{
while (fromIter != fromFS.end())
{
result /= "..";
fromIter++;
}
while (toIter != toFS.end())
{
result /= *toIter;
toIter++;
}
result += std::experimental::filesystem::path::preferred_separator;
}
}
return result;
}
std::wstring FileSystem::GetBasePath(const std::wstring& path)
{
std::wstring pathCopy(path);
wchar_t *basePath = &pathCopy[0];
if (FAILED(PathCchRemoveFileSpec(basePath, pathCopy.length() + 1)))
{
throw std::invalid_argument("Invalid input path.");
}
return std::move(std::wstring(basePath));
}
std::wstring FileSystem::GetFullPath(const std::wstring& path)
{
wchar_t fullPath[MAX_PATH];
if (GetFullPathName(path.c_str(), ARRAYSIZE(fullPath), fullPath, NULL) == 0)
{
throw std::invalid_argument("Invalid input file path.");
}
return std::move(std::wstring(fullPath));
}
std::wstring FileSystem::CreateSubFolder(const std::wstring& parentPath, const std::wstring& subFolderName)
{
std::wstring errorMessageW = L"Could not create a sub-folder of " + parentPath + L".";
std::string errorMessage(errorMessageW.begin(), errorMessageW.end());
wchar_t subFolderPath[MAX_PATH];
if (FAILED(PathCchCombine(subFolderPath, ARRAYSIZE(subFolderPath), parentPath.c_str(), (subFolderName + L"\\").c_str())))
{
throw std::runtime_error(errorMessage);
}
if (CreateDirectory(subFolderPath, NULL) == 0 && GetLastError() != ERROR_ALREADY_EXISTS)
{
throw std::runtime_error(errorMessage);
}
return std::move(std::wstring(subFolderPath));
}
std::wstring FileSystem::CreateTempFolder()
{
std::wstring errorMessageW = L"Could not get a temporary folder. Try specifying one in the command line.";
std::string errorMessage(errorMessageW.begin(), errorMessageW.end());
wchar_t tmpDirRaw[MAX_PATH];
auto returnValue = GetTempPath(MAX_PATH, tmpDirRaw);
if (returnValue > MAX_PATH || (returnValue == 0))
{
throw std::runtime_error(errorMessage);
}
// Get a random folder to drop the files
GUID guid = { 0 };
if (FAILED(CoCreateGuid(&guid)))
{
throw std::runtime_error(errorMessage);
}
wchar_t guidRaw[MAX_PATH];
if (StringFromGUID2(guid, guidRaw, ARRAYSIZE(guidRaw)) == 0)
{
throw std::runtime_error(errorMessage);
}
return std::move(CreateSubFolder(tmpDirRaw, guidRaw));
}