#include "PlatformDetermination.h" #include "Exceptions.h" #include "CPfilepaths.h" #include "CPstrings.h" #include "CoolPropTools.h" #include #include #include #include // This will kill the horrible min and max macros #ifndef NOMINMAX #define NOMINMAX #endif #if defined(__ISWINDOWS__) #define UNICODE #define _UNICODE #include "Windows.h" #include // for the CreateDirectory function #else #include #if !defined(__powerpc__) #include #endif #endif #if defined(__ISWINDOWS__) /// From http://stackoverflow.com/a/17827724/1360263 bool IsBrowsePath(const std::wstring& path) { return (path == L"." || path == L".."); } unsigned long long CalculateDirSize(const std::wstring &path, std::vector *errVect) { unsigned long long size = 0; WIN32_FIND_DATAW data; HANDLE sh = NULL; sh = FindFirstFileW((path + L"\\*").c_str(), &data); if (sh == INVALID_HANDLE_VALUE ) { //if we want, store all happened error if (errVect != NULL) errVect ->push_back(path); return size; } do { // skip current and parent if (!IsBrowsePath(data.cFileName)) { // if found object is ... if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // directory, then search it recursievly size += CalculateDirSize(path + L"\\" + data.cFileName, NULL); else // otherwise get object size and add it to directory size size += data.nFileSizeHigh * (unsigned long long)(MAXDWORD) + data.nFileSizeLow; } } while (FindNextFileW(sh, &data)); // do FindClose(sh); return size; } #elif defined(__ANDROID__) || defined(__powerpc__) // Android doesn't have ftw.h, also doesn't accept not having this file unsigned long long CalculateDirSize(const std::string &path){ return 0; } #else #include #include #include static thread_local unsigned long long ftw_summer; // An evil global variable for the ftw function int ftw_function(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf){ ftw_summer += sb->st_size; return 0; /* To tell nftw() to continue */ } unsigned long long CalculateDirSize(const std::string &path){ ftw_summer = 0; int flags = 0 | FTW_DEPTH | FTW_PHYS; nftw(path.c_str(), ftw_function, 20, flags); double temp = ftw_summer; ftw_summer = 0; return temp; } #endif std::vector get_binary_file_contents(const char *filename) { std::ifstream in(filename, std::ios::in | std::ios::binary); if (in) { std::vector contents; in.seekg(0, std::ios::end); contents.resize((unsigned int) in.tellg()); in.seekg(0, std::ios::beg); in.read(&contents[0], contents.size()); in.close(); return(contents); } throw(errno); } void make_dirs(std::string file_path) { std::replace( file_path.begin(), file_path.end(), '\\', '/'); // replace all '\' with '/' #if defined(__ISWINDOWS__) const char sep = '\\'; // well, Windows (and DOS) allows forward slash "/", too :) #else const char sep = '/'; #endif std::vector pathsplit = strsplit(file_path,'/'); std::string path = pathsplit[0]; // will throw if pathsplit.size() == 0 for (std::size_t i = 0, sz = pathsplit.size(); i < sz; i++) { if (!path_exists(path)) { #if defined(__ISWINDOWS__) // Defined for 32-bit and 64-bit windows int errcode = CreateDirectoryA((LPCSTR)path.c_str(),NULL); if (errcode == 0){ switch(GetLastError()){ case ERROR_ALREADY_EXISTS: break; case ERROR_PATH_NOT_FOUND: throw CoolProp::ValueError(format("Unable to make the directory %s",path.c_str())); default: break; } } #else #if defined(__powerpc__) #else mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); #endif #endif } if (i < (sz-1)) path += format("%c%s", sep, pathsplit[i+1].c_str()); } }; std::string get_home_dir(void) { // See http://stackoverflow.com/questions/2552416/how-can-i-find-the-users-home-dir-in-a-cross-platform-manner-using-c #if defined(__ISLINUX__) char *home = NULL; home = getenv("HOME"); return std::string(home); #elif defined(__ISAPPLE__) char *home = NULL; home = getenv("HOME"); if (home==NULL) { struct passwd* pwd = getpwuid(getuid()); if (pwd) { home = pwd->pw_dir; } } if (home==NULL) { throw CoolProp::NotImplementedError("Could not detect home directory."); } return std::string(home); #elif defined(__ISWINDOWS__) #if defined(_MSC_VER) #pragma warning (push) #pragma warning (disable : 4996) #endif char * pUSERPROFILE = getenv("USERPROFILE"); if (pUSERPROFILE != NULL) { return std::string(pUSERPROFILE); } else { char * pHOMEDRIVE = getenv("HOMEDRIVE"); char * pHOMEPATH = getenv("HOMEPATH"); if (pHOMEDRIVE != NULL && pHOMEPATH != NULL) { return std::string(pHOMEDRIVE) + std::string(pHOMEPATH); } else { return std::string(""); } } #if defined(_MSC_VER) #pragma warning (pop) #endif #else throw CoolProp::NotImplementedError("This function is not defined for your platform."); #endif }; bool path_exists(const std::string &path) { #if defined(__ISWINDOWS__) // Defined for 32-bit and 64-bit windows struct _stat buf; // Get data associated with path using the windows libraries, // and if you can (result == 0), the path exists if ( _stat( path.c_str(), &buf) == 0) return true; else return false; #elif defined(__ISLINUX__) || defined(__ISAPPLE__) struct stat st; if(lstat(path.c_str(),&st) == 0) { if(S_ISDIR(st.st_mode)) return true; if(S_ISREG(st.st_mode)) return true; return false; } else { return false; } #else throw CoolProp::NotImplementedError("This function is not defined for your platform."); #endif }; std::string get_file_contents(const char *filename) { std::ifstream in(filename, std::ios::in | std::ios::binary); if (in) { std::string contents; in.seekg(0, std::ios::end); contents.resize((unsigned int) in.tellg()); in.seekg(0, std::ios::beg); in.read(&contents[0], contents.size()); in.close(); return(contents); } throw(errno); }