xrpld
Loading...
Searching...
No Matches
libxrpl/basics/FileUtilities.cpp
1#include <xrpl/basics/FileUtilities.h>
2
3#include <xrpl/basics/contract.h>
4
5#include <cerrno>
6#include <cstddef>
7#include <filesystem>
8#include <format>
9#include <fstream>
10#include <iomanip>
11#include <ios>
12#include <iostream>
13#include <iterator>
14#include <optional>
15#include <random>
16#include <sstream>
17#include <stdexcept>
18#include <string>
19#include <system_error>
20
21namespace xrpl {
22
23std::string
26 std::filesystem::path const& sourcePath,
28{
29 using namespace std::filesystem;
30
31 path const fullPath{canonical(sourcePath, ec)};
32 if (ec)
33 return {};
34
35 if (maxSize && (file_size(fullPath, ec) > *maxSize || ec))
36 {
37 if (!ec)
38 ec = make_error_code(std::errc::file_too_large);
39 return {};
40 }
41
42 std::ifstream fileStream(fullPath, std::ios::in);
43
44 if (!fileStream)
45 {
46 ec.assign(errno, std::generic_category());
47 return {};
48 }
49
50 std::string result{
52
53 if (fileStream.bad())
54 {
55 ec.assign(errno, std::generic_category());
56 return {};
57 }
58
59 return result;
60}
61
62void
65 std::filesystem::path const& destPath,
66 std::string const& contents)
67{
68 std::ofstream fileStream(destPath, std::ios::out | std::ios::trunc);
69
70 if (!fileStream)
71 {
72 ec.assign(errno, std::generic_category());
73 return;
74 }
75
76 fileStream << contents;
77
78 if (fileStream.bad())
79 {
80 ec.assign(errno, std::generic_category());
81 return;
82 }
83}
84
87 std::filesystem::path const& base,
88 std::string const& prefix,
89 std::size_t maxAttempts)
90{
92 for (std::size_t attempt = 0; attempt < maxAttempts; ++attempt)
93 {
95 oss << prefix << std::hex << std::setfill('0') << std::setw(8) << rd() << std::setw(8)
96 << rd();
97 auto candidate = base / oss.str();
99 bool const exists = std::filesystem::exists(candidate, ec);
100 if (ec)
101 {
103 std::format("Unable to check path '{}': {}", candidate.string(), ec.message()));
104 }
105 if (!exists)
106 return candidate;
107 }
109 std::format("Unable to generate a unique path under '{}'", base.string()));
110}
111
116
118{
119 // use non-throwing calls in the destructor
122 if (ec)
123 {
124 std::cerr << "Unable to remove temporary directory '" << path_.string()
125 << "': " << ec.message() << '\n';
126 }
127}
128
131{
132 return path_.string();
133}
134
136TempDir::file(std::string const& name) const
137{
138 return (path_ / name).string();
139}
140
141} // namespace xrpl
T assign(T... args)
T bad(T... args)
T canonical(T... args)
std::filesystem::path path_
TempDir()
Construct a temporary directory.
std::string path() const
Get the native path for the temporary directory.
~TempDir()
Destroy a temporary directory.
std::string file(std::string const &name) const
Get the native path for a file.
T create_directory(T... args)
T exists(T... args)
T file_size(T... args)
T format(T... args)
T generic_category(T... args)
T hex(T... args)
T message(T... args)
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::error_code make_error_code(xrpl::TokenCodecErrc e)
std::filesystem::path uniqueRandomPath(std::filesystem::path const &base, std::string const &prefix="", std::size_t maxAttempts=100)
Generate a unique, non-existing path under base whose filename starts with prefix and ends with a ran...
std::string getFileContents(std::error_code &ec, std::filesystem::path const &sourcePath, std::optional< std::size_t > maxSize=std::nullopt)
void writeFileContents(std::error_code &ec, std::filesystem::path const &destPath, std::string const &contents)
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
T remove_all(T... args)
T setfill(T... args)
T setw(T... args)
T str(T... args)
T temp_directory_path(T... args)