1*b64983f0SShantappa Teekappanavar #pragma once
2*b64983f0SShantappa Teekappanavar 
3*b64983f0SShantappa Teekappanavar #include <filesystem>
4*b64983f0SShantappa Teekappanavar #include <utility>
5*b64983f0SShantappa Teekappanavar 
6*b64983f0SShantappa Teekappanavar namespace watchdog
7*b64983f0SShantappa Teekappanavar {
8*b64983f0SShantappa Teekappanavar namespace dump
9*b64983f0SShantappa Teekappanavar {
10*b64983f0SShantappa Teekappanavar 
11*b64983f0SShantappa Teekappanavar namespace fs = std::filesystem;
12*b64983f0SShantappa Teekappanavar 
13*b64983f0SShantappa Teekappanavar /**
14*b64983f0SShantappa Teekappanavar  * @class TemporaryFile
15*b64983f0SShantappa Teekappanavar  *
16*b64983f0SShantappa Teekappanavar  * A temporary file in the file system.
17*b64983f0SShantappa Teekappanavar  *
18*b64983f0SShantappa Teekappanavar  * The temporary file is created by the constructor.  The absolute path to the
19*b64983f0SShantappa Teekappanavar  * file can be obtained using getPath().
20*b64983f0SShantappa Teekappanavar  *
21*b64983f0SShantappa Teekappanavar  * The temporary file can be deleted by calling remove().  Otherwise the file
22*b64983f0SShantappa Teekappanavar  * will be deleted by the destructor.
23*b64983f0SShantappa Teekappanavar  *
24*b64983f0SShantappa Teekappanavar  * TemporaryFile objects cannot be copied, but they can be moved.  This enables
25*b64983f0SShantappa Teekappanavar  * them to be stored in containers like std::vector.
26*b64983f0SShantappa Teekappanavar  */
27*b64983f0SShantappa Teekappanavar class TemporaryFile
28*b64983f0SShantappa Teekappanavar {
29*b64983f0SShantappa Teekappanavar   public:
30*b64983f0SShantappa Teekappanavar     // Specify which compiler-generated methods we want
31*b64983f0SShantappa Teekappanavar     TemporaryFile(const TemporaryFile&) = delete;
32*b64983f0SShantappa Teekappanavar     TemporaryFile& operator=(const TemporaryFile&) = delete;
33*b64983f0SShantappa Teekappanavar 
34*b64983f0SShantappa Teekappanavar     /**
35*b64983f0SShantappa Teekappanavar      * @brief Constructor.
36*b64983f0SShantappa Teekappanavar      *
37*b64983f0SShantappa Teekappanavar      * @details Creates a temporary file in the temporary directory (normally
38*b64983f0SShantappa Teekappanavar      * /tmp).
39*b64983f0SShantappa Teekappanavar      *
40*b64983f0SShantappa Teekappanavar      * Throws an exception if the file cannot be created.
41*b64983f0SShantappa Teekappanavar      */
42*b64983f0SShantappa Teekappanavar     TemporaryFile();
43*b64983f0SShantappa Teekappanavar 
44*b64983f0SShantappa Teekappanavar     /**
45*b64983f0SShantappa Teekappanavar      * @brief Move constructor.
46*b64983f0SShantappa Teekappanavar      *
47*b64983f0SShantappa Teekappanavar      * @details Transfers ownership of a temporary file.
48*b64983f0SShantappa Teekappanavar      *
49*b64983f0SShantappa Teekappanavar      * @param file TemporaryFile object being moved
50*b64983f0SShantappa Teekappanavar      */
TemporaryFile(TemporaryFile && file)51*b64983f0SShantappa Teekappanavar     TemporaryFile(TemporaryFile&& file) : path{std::move(file.path)}
52*b64983f0SShantappa Teekappanavar     {
53*b64983f0SShantappa Teekappanavar         // Clear path in other object; after move path is in unspecified state
54*b64983f0SShantappa Teekappanavar         file.path.clear();
55*b64983f0SShantappa Teekappanavar     }
56*b64983f0SShantappa Teekappanavar 
57*b64983f0SShantappa Teekappanavar     /**
58*b64983f0SShantappa Teekappanavar      * @brief Move assignment operator.
59*b64983f0SShantappa Teekappanavar      *
60*b64983f0SShantappa Teekappanavar      * @details Deletes the temporary file owned by this object.  Then transfers
61*b64983f0SShantappa Teekappanavar      * ownership of the temporary file owned by the other object.
62*b64983f0SShantappa Teekappanavar      *
63*b64983f0SShantappa Teekappanavar      * Throws an exception if an error occurs during the deletion.
64*b64983f0SShantappa Teekappanavar      *
65*b64983f0SShantappa Teekappanavar      * @param file TemporaryFile object being moved
66*b64983f0SShantappa Teekappanavar      */
67*b64983f0SShantappa Teekappanavar     TemporaryFile& operator=(TemporaryFile&& file);
68*b64983f0SShantappa Teekappanavar 
69*b64983f0SShantappa Teekappanavar     /**
70*b64983f0SShantappa Teekappanavar      * @brief Destructor.
71*b64983f0SShantappa Teekappanavar      *
72*b64983f0SShantappa Teekappanavar      * @details description the temporary file if necessary.
73*b64983f0SShantappa Teekappanavar      */
~TemporaryFile()74*b64983f0SShantappa Teekappanavar     ~TemporaryFile()
75*b64983f0SShantappa Teekappanavar     {
76*b64983f0SShantappa Teekappanavar         try
77*b64983f0SShantappa Teekappanavar         {
78*b64983f0SShantappa Teekappanavar             remove();
79*b64983f0SShantappa Teekappanavar         }
80*b64983f0SShantappa Teekappanavar         catch (...)
81*b64983f0SShantappa Teekappanavar         {
82*b64983f0SShantappa Teekappanavar             // Destructors should not throw exceptions
83*b64983f0SShantappa Teekappanavar         }
84*b64983f0SShantappa Teekappanavar     }
85*b64983f0SShantappa Teekappanavar 
86*b64983f0SShantappa Teekappanavar     /**
87*b64983f0SShantappa Teekappanavar      * @brief Deletes the temporary file.
88*b64983f0SShantappa Teekappanavar      *
89*b64983f0SShantappa Teekappanavar      * @details Does nothing if the file has already been deleted.
90*b64983f0SShantappa Teekappanavar      *
91*b64983f0SShantappa Teekappanavar      * Throws an exception if an error occurs during the deletion.
92*b64983f0SShantappa Teekappanavar      */
93*b64983f0SShantappa Teekappanavar     void remove();
94*b64983f0SShantappa Teekappanavar 
95*b64983f0SShantappa Teekappanavar     /**
96*b64983f0SShantappa Teekappanavar      * @brief Returns the absolute path to the temporary file.
97*b64983f0SShantappa Teekappanavar      *
98*b64983f0SShantappa Teekappanavar      * @details Returns an empty path if the file has been deleted.
99*b64983f0SShantappa Teekappanavar      *
100*b64983f0SShantappa Teekappanavar      * @return temporary file path
101*b64983f0SShantappa Teekappanavar      */
getPath() const102*b64983f0SShantappa Teekappanavar     const fs::path& getPath() const
103*b64983f0SShantappa Teekappanavar     {
104*b64983f0SShantappa Teekappanavar         return path;
105*b64983f0SShantappa Teekappanavar     }
106*b64983f0SShantappa Teekappanavar 
107*b64983f0SShantappa Teekappanavar   private:
108*b64983f0SShantappa Teekappanavar     /**
109*b64983f0SShantappa Teekappanavar      * @brief Absolute path to the temporary file.
110*b64983f0SShantappa Teekappanavar      *
111*b64983f0SShantappa Teekappanavar      * @details Empty when file has been deleted.
112*b64983f0SShantappa Teekappanavar      */
113*b64983f0SShantappa Teekappanavar     fs::path path{};
114*b64983f0SShantappa Teekappanavar };
115*b64983f0SShantappa Teekappanavar 
116*b64983f0SShantappa Teekappanavar } // namespace dump
117*b64983f0SShantappa Teekappanavar } // namespace watchdog
118