ppforest2 v0.1.0
Projection Pursuit Decision Trees and Random Forests
Loading...
Searching...
No Matches
TempFile.hpp
Go to the documentation of this file.
1
5#pragma once
6
7#include <filesystem>
8#include <fstream>
9#include <sstream>
10#include <string>
11#include <vector>
12
13#ifdef _WIN32
14#include <io.h>
15#include <windows.h>
16#else
17#include <unistd.h>
18#endif
19
20namespace ppforest2::io {
28 class TempFile {
29 public:
30 explicit TempFile(std::string const& suffix = ".json") {
31 // clang-format off
32 #ifdef _WIN32
33 char tmp_dir[MAX_PATH];
34 GetTempPathA(MAX_PATH, tmp_dir);
35 char tmp_file[MAX_PATH];
36 GetTempFileNameA(tmp_dir, "ppforest2", 0, tmp_file);
37 sentinel_ = tmp_file;
38 path_ = sentinel_ + suffix;
39 std::ofstream touch(path_);
40 #else
41 std::string tmpl = "/tmp/ppforest2_XXXXXX" + suffix;
42 std::vector<char> tmpl_buf(tmpl.begin(), tmpl.end());
43 tmpl_buf.push_back('\0');
44
45 int fd = mkstemps(tmpl_buf.data(), static_cast<int>(suffix.size()));
46
47 if (fd != -1) {
48 path_ = tmpl_buf.data();
49 close(fd);
50 }
51 #endif
52 // clang-format on
53 }
54
56 if (!path_.empty()) {
57 std::remove(path_.c_str());
58 }
59
60 // clang-format off
61 #ifdef _WIN32
62 if (!sentinel_.empty()) {
63 std::remove(sentinel_.c_str());
64 }
65 #endif
66 // clang-format on
67 }
68
69 TempFile(TempFile const&) = delete;
70 TempFile& operator=(TempFile const&) = delete;
71
72 TempFile(TempFile&& other) noexcept
73 : path_(std::move(other.path_)) {
74 other.path_.clear();
75 // clang-format off
76 #ifdef _WIN32
77 sentinel_ = std::move(other.sentinel_);
78 other.sentinel_.clear();
79 #endif
80 // clang-format on
81 }
82
83 TempFile& operator=(TempFile&& other) noexcept {
84 if (this != &other) {
85 if (!path_.empty()) {
86 std::remove(path_.c_str());
87 }
88
89 // clang-format off
90 #ifdef _WIN32
91 if (!sentinel_.empty()) {
92 std::remove(sentinel_.c_str());
93 }
94 sentinel_ = std::move(other.sentinel_);
95 other.sentinel_.clear();
96 #endif
97 // clang-format on
98
99 path_ = std::move(other.path_);
100 other.path_.clear();
101 }
102
103 return *this;
104 }
105
106 std::string const& path() const { return path_; }
107
109 void clear() const { std::remove(path_.c_str()); }
110
112 std::string read() const {
113 std::ifstream in(path_);
114 std::stringstream ss;
115 ss << in.rdbuf();
116 return ss.str();
117 }
118
119 private:
120 std::string path_;
121 // clang-format off
122 #ifdef _WIN32
123 std::string sentinel_; // keep the .tmp file alive to prevent GetTempFileNameA reuse
124 #endif
125 // clang-format on
126 };
127
134 class TempDir {
135 public:
137 // clang-format off
138 #ifdef _WIN32
139 // clang-format on
140 char tmp_dir[MAX_PATH];
141 GetTempPathA(MAX_PATH, tmp_dir);
142 char tmp_file[MAX_PATH];
143 GetTempFileNameA(tmp_dir, "ppd", 0, tmp_file);
144 // GetTempFileNameA creates a file; replace it with a directory
145 std::remove(tmp_file);
146 path_ = tmp_file;
147 std::filesystem::create_directories(path_);
148 // clang-format off
149 #else
150 // clang-format on
151 path_ = "/tmp/ppforest2_dir_XXXXXX";
152 std::vector<char> buf(path_.begin(), path_.end());
153 buf.push_back('\0');
154 char* result = mkdtemp(buf.data());
155
156 if (result != nullptr) {
157 path_ = result;
158 }
159 // clang-format off
160 #endif
161 // clang-format on
162 }
163
165 if (!path_.empty()) {
166 std::filesystem::remove_all(path_);
167 }
168 }
169
170 TempDir(TempDir const&) = delete;
171 TempDir& operator=(TempDir const&) = delete;
172
173 std::string const& path() const { return path_; }
174
176 std::string file(std::string const& name) const { return (std::filesystem::path(path_) / name).string(); }
177
178 private:
179 std::string path_;
180 };
181}
std::string file(std::string const &name) const
Return a path inside this directory (file need not exist yet).
Definition TempFile.hpp:176
TempDir & operator=(TempDir const &)=delete
~TempDir()
Definition TempFile.hpp:164
TempDir(TempDir const &)=delete
std::string const & path() const
Definition TempFile.hpp:173
TempDir()
Definition TempFile.hpp:136
TempFile & operator=(TempFile const &)=delete
TempFile(std::string const &suffix=".json")
Definition TempFile.hpp:30
TempFile & operator=(TempFile &&other) noexcept
Definition TempFile.hpp:83
std::string read() const
Read the entire file contents as a string.
Definition TempFile.hpp:112
TempFile(TempFile &&other) noexcept
Definition TempFile.hpp:72
void clear() const
Remove the file so the path can be used as a fresh output target.
Definition TempFile.hpp:109
std::string const & path() const
Definition TempFile.hpp:106
~TempFile()
Definition TempFile.hpp:55
TempFile(TempFile const &)=delete
Definition Color.hpp:31