CoolProp 6.8.1dev
An open-source fluid property and humid air property database
CPfilepaths.cpp
Go to the documentation of this file.
2#include "Exceptions.h"
3#include "CPfilepaths.h"
4#include "CPstrings.h"
5#include "CoolPropTools.h"
6
7#include <fstream>
8#include <algorithm>
9#include <sys/types.h>
10#include <sys/stat.h>
11#include <cerrno>
12
13// This will kill the horrible min and max macros
14#ifndef NOMINMAX
15# define NOMINMAX
16#endif
17
18#if defined(__ISWINDOWS__)
19# define UNICODE
20# define _UNICODE
21# include "Windows.h"
22# include <windows.h> // for the CreateDirectory function
23#else
24# include <unistd.h>
25# if !defined(__powerpc__)
26# include <pwd.h>
27# endif
28#endif
29
30#if defined(__ISWINDOWS__)
32bool IsBrowsePath(const std::wstring& path) {
33 return (path == L"." || path == L"..");
34}
35unsigned long long CalculateDirSize(const std::wstring& path, std::vector<std::wstring>* errVect) {
36 unsigned long long size = 0;
37 WIN32_FIND_DATAW data;
38 HANDLE sh = NULL;
39 sh = FindFirstFileW((path + L"\\*").c_str(), &data);
40
41 if (sh == INVALID_HANDLE_VALUE) {
42 //if we want, store all happened error
43 if (errVect != NULL) errVect->push_back(path);
44 return size;
45 }
46
47 do {
48 // skip current and parent
49 if (!IsBrowsePath(data.cFileName)) {
50 // if found object is ...
51 if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
52 // directory, then search it recursievly
53 size += CalculateDirSize(path + L"\\" + data.cFileName, NULL);
54 else
55 // otherwise get object size and add it to directory size
56 size += data.nFileSizeHigh * (unsigned long long)(MAXDWORD) + data.nFileSizeLow;
57 }
58
59 } while (FindNextFileW(sh, &data)); // do
60
61 FindClose(sh);
62
63 return size;
64}
65#elif defined(__ANDROID__) || defined(__powerpc__)
66// Android doesn't have ftw.h, also doesn't accept not having this file
67unsigned long long CalculateDirSize(const std::string& path) {
68 return 0;
69}
70#else
71# include <ftw.h>
72# include <stdint.h>
73# include <iostream>
74
75static thread_local unsigned long long ftw_summer; // An evil global variable for the ftw function
76int ftw_function(const char* fpath, const struct stat* sb, int tflag, struct FTW* ftwbuf) {
77 ftw_summer += sb->st_size;
78 return 0; /* To tell nftw() to continue */
79}
80unsigned long long CalculateDirSize(const std::string& path) {
81 ftw_summer = 0;
82 int flags = 0 | FTW_DEPTH | FTW_PHYS;
83 nftw(path.c_str(), ftw_function, 20, flags);
84 double temp = ftw_summer;
85 ftw_summer = 0;
86 return temp;
87}
88#endif
89
90std::vector<char> get_binary_file_contents(const char* filename) {
91 std::ifstream in(filename, std::ios::in | std::ios::binary);
92 if (in) {
93 std::vector<char> contents;
94 in.seekg(0, std::ios::end);
95 contents.resize((unsigned int)in.tellg());
96 in.seekg(0, std::ios::beg);
97 in.read(&contents[0], contents.size());
98 in.close();
99 return (contents);
100 }
101 throw(errno);
102}
103
104void make_dirs(std::string file_path) {
105 std::replace(file_path.begin(), file_path.end(), '\\', '/'); // replace all '\' with '/'
106
107#if defined(__ISWINDOWS__)
108 const char sep = '\\'; // well, Windows (and DOS) allows forward slash "/", too :)
109#else
110 const char sep = '/';
111#endif
112
113 std::vector<std::string> pathsplit = strsplit(file_path, '/');
114 std::string path = pathsplit[0]; // will throw if pathsplit.size() == 0
115 for (std::size_t i = 0, sz = pathsplit.size(); i < sz; i++) {
116 if (!path_exists(path)) {
117#if defined(__ISWINDOWS__) // Defined for 32-bit and 64-bit windows
118 int errcode = CreateDirectoryA((LPCSTR)path.c_str(), NULL);
119 if (errcode == 0) {
120 switch (GetLastError()) {
121 case ERROR_ALREADY_EXISTS:
122 break;
123 case ERROR_PATH_NOT_FOUND:
124 throw CoolProp::ValueError(format("Unable to make the directory %s", path.c_str()));
125 default:
126 break;
127 }
128 }
129#else
130# if defined(__powerpc__)
131# else
132 mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
133# endif
134#endif
135 }
136 if (i < (sz - 1)) path += format("%c%s", sep, pathsplit[i + 1].c_str());
137 }
138};
139
140std::string get_separator(void) {
141#if defined(__ISLINUX__)
142 return std::string("/");
143#elif defined(__ISAPPLE__)
144 return std::string("/");
145#elif defined(__ISWINDOWS__)
146 return std::string("\\");
147#else
148 throw CoolProp::NotImplementedError("This function is not defined for your platform.");
149#endif
150}
151
152std::string get_home_dir(void) {
153// See http://stackoverflow.com/questions/2552416/how-can-i-find-the-users-home-dir-in-a-cross-platform-manner-using-c
154#if defined(__ISLINUX__)
155 char* home = NULL;
156 home = getenv("HOME");
157 return std::string(home);
158#elif defined(__ISAPPLE__)
159 char* home = NULL;
160 home = getenv("HOME");
161 if (home == NULL) {
162 struct passwd* pwd = getpwuid(getuid());
163 if (pwd) {
164 home = pwd->pw_dir;
165 }
166 }
167 if (home == NULL) {
168 throw CoolProp::NotImplementedError("Could not detect home directory.");
169 }
170 return std::string(home);
171#elif defined(__ISWINDOWS__)
172# if defined(_MSC_VER)
173# pragma warning(push)
174# pragma warning(disable : 4996)
175# endif
176 char* pUSERPROFILE = getenv("USERPROFILE");
177 if (pUSERPROFILE != NULL) {
178 return std::string(pUSERPROFILE);
179 } else {
180 char* pHOMEDRIVE = getenv("HOMEDRIVE");
181 char* pHOMEPATH = getenv("HOMEPATH");
182 if (pHOMEDRIVE != NULL && pHOMEPATH != NULL) {
183 return std::string(pHOMEDRIVE) + std::string(pHOMEPATH);
184 } else {
185 return std::string("");
186 }
187 }
188# if defined(_MSC_VER)
189# pragma warning(pop)
190# endif
191#else
192 throw CoolProp::NotImplementedError("This function is not defined for your platform.");
193#endif
194};
195
196bool path_exists(const std::string& path) {
197 std::string path_cpy;
198 if (endswith(path, get_separator())) {
199 path_cpy = path.substr(0, path.size() - 1);
200 } else {
201 path_cpy = path;
202 }
203
204#if defined(__ISWINDOWS__) // Defined for 32-bit and 64-bit windows
205 struct _stat buf;
206 // Get data associated with path using the windows libraries,
207 // and if you can (result == 0), the path exists
208 if (_stat(path_cpy.c_str(), &buf) == 0) {
209 return true;
210 } else {
211 return false;
212 }
213#elif defined(__ISLINUX__) || defined(__ISAPPLE__)
214 struct stat st;
215 if (lstat(path_cpy.c_str(), &st) == 0) {
216 if (S_ISDIR(st.st_mode)) return true;
217 if (S_ISREG(st.st_mode)) return true;
218 return false;
219 } else {
220 return false;
221 }
222#else
223 throw CoolProp::NotImplementedError("This function is not defined for your platform.");
224#endif
225};
226
227std::string join_path(const std::string& one, const std::string& two) {
228 std::string result;
229 std::string separator = get_separator();
230 if (!endswith(one, separator) && !one.empty()) {
231 result = one + separator;
232 } else {
233 result = one;
234 }
235 result.append(two);
236 return result;
237}
238
239std::string get_file_contents(const char* filename) {
240 std::ifstream in(filename, std::ios::in | std::ios::binary);
241 if (in) {
242 std::string contents;
243 in.seekg(0, std::ios::end);
244 contents.resize((unsigned int)in.tellg());
245 in.seekg(0, std::ios::beg);
246 in.read(&contents[0], contents.size());
247 in.close();
248 return (contents);
249 }
250 throw(errno);
251}