FBX2glTF/src/utils/File_Utils.cpp

204 lines
6.1 KiB
C++

/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#include <string>
#include <vector>
#include <fstream>
#include <stdint.h>
#include <stdio.h>
#if defined( __unix__ ) || defined ( __APPLE__ )
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#define _getcwd getcwd
#define _mkdir(a) mkdir(a, 0777)
#elif defined( _WIN32 )
#include <direct.h>
#include <process.h>
#else
#include <direct.h>
#include <process.h>
#endif
#include <sys/stat.h>
#include "FBX2glTF.h"
#include "String_Utils.h"
namespace FileUtils {
std::string GetCurrentFolder()
{
char cwd[StringUtils::MAX_PATH_LENGTH];
if (!_getcwd(cwd, sizeof(cwd))) {
return std::string();
}
cwd[sizeof(cwd) - 1] = '\0';
StringUtils::GetCleanPath(cwd, cwd, StringUtils::PATH_UNIX);
const size_t length = strlen(cwd);
if (cwd[length - 1] != '/' && length < StringUtils::MAX_PATH_LENGTH - 1) {
cwd[length + 0] = '/';
cwd[length + 1] = '\0';
}
return std::string(cwd);
}
bool FolderExists(const std::string &folderPath)
{
#if defined( __unix__ ) || defined( __APPLE__ )
DIR *dir = opendir(folderPath.c_str());
if (dir) {
closedir(dir);
return true;
}
return false;
#else
const DWORD ftyp = GetFileAttributesA( folderPath.c_str() );
if ( ftyp == INVALID_FILE_ATTRIBUTES )
{
return false; // bad path
}
return ( ftyp & FILE_ATTRIBUTE_DIRECTORY ) != 0;
#endif
}
bool MatchExtension(const char *fileExtension, const char *matchExtensions)
{
if (matchExtensions[0] == '\0') {
return true;
}
if (fileExtension[0] == '.') {
fileExtension++;
}
for (const char *end = matchExtensions; end[0] != '\0';) {
for (; end[0] == ';'; end++) {}
const char *ext = end;
for (; end[0] != ';' && end[0] != '\0'; end++) {}
#if defined( __unix__ ) || defined( __APPLE__ )
if (strncasecmp(fileExtension, ext, end - ext) == 0)
#else
if ( _strnicmp( fileExtension, ext, end - ext ) == 0 )
#endif
{
return true;
}
}
return false;
}
std::vector<std::string> ListFolderFiles(const char *folder, const char *matchExtensions)
{
std::vector<std::string> fileList;
#if defined( __unix__ ) || defined( __APPLE__ )
DIR *dir = opendir(strlen(folder) > 0 ? folder : ".");
if (dir != nullptr) {
for (;;) {
struct dirent *dp = readdir(dir);
if (dp == nullptr) {
break;
}
if (dp->d_type == DT_DIR) {
continue;
}
const char *fileName = dp->d_name;
const char *fileExt = strrchr(fileName, '.');
if (!fileExt || !MatchExtension(fileExt, matchExtensions)) {
continue;
}
fileList.emplace_back(fileName);
}
closedir(dir);
}
#else
std::string pathStr = folder;
pathStr += "*";
WIN32_FIND_DATA FindFileData;
HANDLE hFind = FindFirstFile( pathStr.c_str(), &FindFileData );
if ( hFind != INVALID_HANDLE_VALUE )
{
do
{
if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
std::string fileName = FindFileData.cFileName;
std::string::size_type extPos = fileName.rfind('.');
if (extPos != std::string::npos &&
MatchExtension(fileName.substr(extPos + 1).c_str(), matchExtensions)) {
fileList.push_back(fileName);
}
}
} while ( FindNextFile( hFind, &FindFileData ) );
FindClose( hFind );
}
#endif
return fileList;
}
bool CreatePath(const char *path)
{
#if defined( __unix__ ) || defined( __APPLE__ )
StringUtils::PathSeparator separator = StringUtils::PATH_UNIX;
#else
StringUtils::PathSeparator separator = StringUtils::PATH_WIN;
#endif
std::string folder = StringUtils::GetFolderString(path);
std::string clean = StringUtils::GetCleanPathString(folder, separator);
std::string build = clean;
for (int i = 0; i < clean.length(); i ++) {
if (clean[i] == separator && i > 0) {
build[i] = '\0';
if (i > 1 || build[1] != ':') {
if (_mkdir(build.c_str()) != 0 && errno != EEXIST) {
return false;
}
}
}
build[i] = clean[i];
}
return true;
}
bool CopyFile(const std::string &srcFilename, const std::string &dstFilename) {
std::ifstream srcFile(srcFilename, std::ios::binary);
if (!srcFile) {
fmt::printf("Warning: Couldn't open file %s for reading.\n", srcFilename);
return false;
}
// find source file length
srcFile.seekg(0, std::ios::end);
std::streamsize srcSize = srcFile.tellg();
srcFile.seekg(0, std::ios::beg);
std::ofstream dstFile(dstFilename, std::ios::binary | std::ios::trunc);
if (!dstFile) {
fmt::printf("Warning: Couldn't open file %s for writing.\n", srcFilename);
return false;
}
dstFile << srcFile.rdbuf();
std::streamsize dstSize = dstFile.tellp();
if (srcSize == dstSize) {
return true;
}
fmt::printf("Warning: Only copied %lu bytes to %s, when %s is %lu bytes long.\n", dstSize, dstFilename, srcFilename, srcSize);
return false;
}
}