DIY  3.0
data-parallel out-of-core C++ library
 All Classes Namespaces Functions Typedefs Groups Pages
utils.hpp
1 #ifndef DIY_IO_UTILS_HPP
2 #define DIY_IO_UTILS_HPP
3 
4 #if defined(_WIN32)
5 #include <direct.h>
6 #include <io.h>
7 #else
8 #include <unistd.h> // mkstemp() on Mac
9 #include <dirent.h>
10 #endif
11 
12 #include <cstdio> // remove()
13 #include <cstdlib> // mkstemp() on Linux
14 #include <sys/stat.h>
15 
16 #include "../constants.h" // for DIY_UNUSED
17 
18 namespace diy
19 {
20 namespace io
21 {
22 namespace utils
23 {
27  inline bool is_directory(const std::string& filename)
28  {
29 #if defined(_WIN32)
30  DWORD attr = GetFileAttributes(filename.c_str());
31  return (attr != INVALID_FILE_ATTRIBUTES) && ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0);
32 #else
33  struct stat s;
34  return (stat(filename.c_str(), &s) == 0 && S_ISDIR(s.st_mode));
35 #endif
36  }
37 
41  inline bool make_directory(const std::string& filename)
42  {
43 #if defined(_WIN32)
44  return _mkdir(filename.c_str()) == 0;
45 #else
46  return mkdir(filename.c_str(), 0755) == 0;
47 #endif
48  }
49 
54  inline void truncate(const std::string& filename, size_t length)
55  {
56 #if defined(_WIN32)
57  int fd = -1;
58  _sopen_s(&fd, filename.c_str(), _O_WRONLY | _O_BINARY, _SH_DENYNO, _S_IWRITE);
59  if (fd != -1)
60  {
61  _chsize_s(fd, static_cast<__int64>(length));
62  _close(fd);
63  }
64 #else
65  ::truncate(filename.c_str(), static_cast<off_t>(length));
66 #endif
67  }
68 
69  inline int mkstemp(std::string& filename)
70  {
71  const size_t slen = filename.size();
72  char *s_template = new char[filename.size() + 1];
73  std::copy_n(filename.c_str(), slen+1, s_template);
74 
75  int handle = -1;
76 #if defined(_WIN32)
77  if (_mktemp_s(s_template, slen+1) == 0) // <- returns 0 on success.
78  _sopen_s(&handle, s_template, _O_WRONLY | _O_CREAT | _O_BINARY, _SH_DENYNO, _S_IWRITE);
79 #elif defined(__MACH__)
80  // TODO: figure out how to open with O_SYNC
81  handle = ::mkstemp(s_template);
82 #else
83  handle = mkostemp(s_template, O_WRONLY | O_SYNC);
84 #endif
85  if (handle != -1)
86  filename = s_template;
87  return handle;
88  }
89 
90  inline void close(int fd)
91  {
92 #if defined(_WIN32)
93  _close(fd);
94 #else
95  fsync(fd);
96  ::close(fd);
97 #endif
98  }
99 
100  inline void sync(int fd)
101  {
102 #if !defined(_WIN32)
103  fsync(fd);
104 #else
105  DIY_UNUSED(fd);
106 #endif
107  }
108 
109  inline bool remove(const std::string& filename)
110  {
111  return ::remove(filename.c_str()) == 0;
112  }
113 }
114 }
115 }
116 
117 #endif