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