Skip to content

Commit f5698a3

Browse files
Hubert DegaudenziHubert Degaudenzi
authored andcommitted
Move uniquePath implementation from Path to Temporary and refactor usage
- Remove uniquePath from Path and add to Temporary with new logic - Use std::random and std::filesystem for unique path generation - Add DEFAULT_TMP_MAX_ATTEMPTS constant for path generation attempts - Update TempPath to use new uniquePath implementation
1 parent 4923ef2 commit f5698a3

File tree

5 files changed

+55
-16
lines changed

5 files changed

+55
-16
lines changed

ElementsKernel/ElementsKernel/Path.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -279,15 +279,6 @@ extern template ELEMENTS_API std::vector<Item> removeDuplicates(const std::vecto
279279
/// Template instantiation for the most common types
280280
extern template ELEMENTS_API std::vector<Item> removeDuplicates(const std::vector<std::string>& path_list);
281281

282-
/**
283-
* @brief Geenrate a unique random path according to to a pattern
284-
* @ingroup ElementsKernel
285-
* @param p
286-
* initial pattern
287-
* @return the path random path stem
288-
*/
289-
ELEMENTS_API Item uniquePath(Item const& p = "%%%%-%%%%-%%%%-%%%%");
290-
291282
} // namespace Path
292283
} // namespace Kernel
293284
} // namespace Elements

ElementsKernel/ElementsKernel/Temporary.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ namespace Elements {
3838
const std::string DEFAULT_TMP_KEEP_VAR{"KEEPTEMPDIR"};
3939
/// The default random creation motif
4040
const std::string DEFAULT_TMP_MOTIF{"%%%%-%%%%-%%%%-%%%%"};
41+
/// Defualt max number of attempt to find a random path
42+
const int DEFAULT_TMP_MAX_ATTEMPTS{100};
43+
44+
/**
45+
* @brief Geenrate a unique random path according to to a pattern
46+
* @ingroup ElementsKernel
47+
* @param p
48+
* initial pattern
49+
* @return the path random path stem
50+
*/
51+
ELEMENTS_API Path::Item uniquePath(Path::Item const& p = DEFAULT_TMP_MOTIF);
4152

4253
class ELEMENTS_API TempPath {
4354
public:

ElementsKernel/src/Lib/Path.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,6 @@ template vector<Item> multiPathAppend(const vector<string>& initial_locations, c
139139
template vector<Item> removeDuplicates(const vector<Item>& path_list);
140140
template vector<Item> removeDuplicates(const vector<string>& path_list);
141141

142-
Item uniquePath(Item const& p) {
143-
using boost::filesystem::unique_path;
144-
return Item{unique_path(p.string()).string()};
145-
}
146-
147142
} // namespace Path
148143
} // namespace Kernel
149144
} // namespace Elements

ElementsKernel/src/Lib/Temporary.cpp

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include <filesystem> // for operator/, ofstream, path>
2525
#include <fstream> // for ofstream>
26+
#include <random> // for random_device, mt19937, uniform_int_distribution
2627
#include <string> // for string
2728

2829
#include <utility>
@@ -34,12 +35,53 @@
3435
using std::string;
3536
using std::filesystem::temp_directory_path;
3637

38+
namespace fs = std::filesystem;
39+
3740
namespace Elements {
3841

3942
namespace {
4043
auto log = Logging::getLogger();
4144
}
4245

46+
inline std::string randomHexString(const std::size_t length) {
47+
static std::random_device rd;
48+
static std::mt19937 gen(rd());
49+
static std::uniform_int_distribution<> dist(0, 15);
50+
51+
static const char* hex_chars = "0123456789abcdef";
52+
53+
std::string result;
54+
result.reserve(length);
55+
for (std::size_t i = 0; i < length; ++i)
56+
result += hex_chars[dist(gen)];
57+
return result;
58+
}
59+
60+
Path::Item uniquePath(Path::Item const& model) {
61+
62+
auto model_string = model.string();
63+
64+
if (model_string.empty())
65+
model_string = DEFAULT_TMP_MOTIF;
66+
67+
string path_str;
68+
69+
for (int tries = 0; tries < DEFAULT_TMP_MAX_ATTEMPTS; ++tries) { // avoid infinite loops
70+
path_str.clear();
71+
for (char c : model_string) {
72+
if (c == '%')
73+
path_str += randomHexString(1);
74+
else
75+
path_str += c;
76+
}
77+
fs::path candidate = fs::temp_directory_path() / path_str;
78+
if (!fs::exists(candidate))
79+
return path_str;
80+
}
81+
82+
throw std::runtime_error("unique_path: could not find unique path");
83+
}
84+
4385
TempPath::TempPath(string motif, string keep_var)
4486
: m_motif(std::move(motif)), m_path(temp_directory_path()), m_keep_var(std::move(keep_var)) {
4587

@@ -54,7 +96,7 @@ TempPath::TempPath(string motif, string keep_var)
5496
pattern = DEFAULT_TMP_MOTIF;
5597
}
5698

57-
m_path /= Path::uniquePath(pattern);
99+
m_path /= uniquePath(pattern);
58100
}
59101

60102
TempPath::~TempPath() {

ElementsKernel/tests/src/Temporary_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ BOOST_AUTO_TEST_CASE(KeepTmpDir_test) {
192192
}
193193

194194
BOOST_AUTO_TEST_CASE(Fake_test) {
195-
using Path::uniquePath;
195+
196196
using std::filesystem::temp_directory_path;
197197

198198
const string motif1;

0 commit comments

Comments
 (0)