Line data Source code
1 : ///
2 : /// @file ar/test_utilities/tmp_file.cpp
3 : /// @copyright (c) 2015 by Petr Zemek (s3rvac@gmail.com) and contributors
4 : /// @license MIT, see the @c LICENSE file for more details
5 : /// @brief Implementation of the temporary-file utilities.
6 : ///
7 :
8 : #include <cstdio>
9 : #include <fstream>
10 : #include <random>
11 :
12 : #include "ar/test_utilities/tmp_file.h"
13 :
14 : namespace ar {
15 : namespace tests {
16 :
17 : namespace {
18 :
19 : ///
20 : /// Returns a path to a unique, temporary file.
21 : ///
22 6 : std::string getUniqueTemporaryFilePath() {
23 : // As the creation of a temporary file with accessible name in the standard
24 : // C++ is painful, simply create the temporary file in the current
25 : // directory. After all, this function is only used in tests.
26 : //
27 : // The use of static variables makes the code unsafe for threads, but since
28 : // we do not use threads in tests, it is OK. The problem is that at least
29 : // on Windows (MSYS2), std::random_device is only a pseudo-random number
30 : // generator that always generates the same sequence. Therefore, we
31 : // initialize the random number generator when the tests start (when
32 : // getUniqueTemporaryFilePath() is first called) and use it for all tests.
33 6 : static std::random_device rd;
34 6 : static std::mt19937 mt{rd()};
35 6 : static std::uniform_int_distribution<std::size_t> dist;
36 6 : return "ar-cpp-" + std::to_string(dist(mt)) + ".tmp";
37 : }
38 :
39 : } // anonymous namespace
40 :
41 : ///
42 : /// Creates a temporary file with the given content.
43 : ///
44 6 : TmpFile::TmpFile(const std::string& content):
45 6 : path{getUniqueTemporaryFilePath()} {
46 12 : std::ofstream file{path, std::ios::binary};
47 6 : file << content;
48 6 : }
49 :
50 : ///
51 : /// Removes the temporary file from the filesystem.
52 : ///
53 12 : TmpFile::~TmpFile() {
54 6 : std::remove(path.c_str());
55 6 : }
56 :
57 : ///
58 : /// Returns a path to the file.
59 : ///
60 8 : std::string TmpFile::getPath() const {
61 8 : return path;
62 : }
63 :
64 : ///
65 : /// Creates a temporary file with the given content.
66 : ///
67 6 : std::unique_ptr<TmpFile> TmpFile::createWithContent(const std::string& content) {
68 6 : return std::make_unique<TmpFile>(content);
69 : }
70 :
71 2 : RemoveFileOnDestruction::RemoveFileOnDestruction(const std::string& path):
72 2 : path(path) {}
73 :
74 4 : RemoveFileOnDestruction::~RemoveFileOnDestruction() {
75 2 : std::remove(path.c_str());
76 2 : }
77 :
78 : } // namespace tests
79 : } // namespace ar
|