1 /*
2  * Copyright (C) 2020 Veloman Yunkan
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
11  * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
12  * NON-INFRINGEMENT.  See the GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
17  *
18  */
19 
20 #ifndef ZIM_TEST_TOOLS_H
21 #define ZIM_TEST_TOOLS_H
22 
23 
24 #include <string>
25 #include <sys/types.h>
26 #ifdef _WIN32
27 #include <windows.h>
28 #include <io.h>
29 #else
30 #include <unistd.h>
31 #endif
32 
33 #include "../src/buffer.h"
34 
35 namespace zim
36 {
37 
38 namespace unittests
39 {
40 
41 // TempFile is a utility class for working with temporary files in RAII fashion:
42 //
43 //   1. An empty temporary file is created (in the temporary file directory)
44 //      by the constructor.
45 //
46 //   2. The file can be filled with data via the file descriptor (returned
47 //      by the fd() member function).
48 //
49 //      -------------------------------------------------------------
50 //      | IMPORTANT!                                                |
51 //      |                                                           |
52 //      | The file descriptor must NOT be close()-ed. Under Windows |
53 //      | this will result in the file being removed.               |
54 //      -------------------------------------------------------------
55 //
56 //   3. The destructor automatically (closes and) removes the file
57 //
58 class TempFile
59 {
60   int fd_;
61   std::string path_;
62 #ifdef _WIN32
63   wchar_t wpath_[MAX_PATH];
64 #endif
65 public:
66   // Creates an empty file in the temporary directory (under Linux and friends
67   // its path is read from the TMPDIR environment variable or defaults to /tmp)
68   explicit TempFile(const char* name);
69 
70   TempFile(const TempFile& ) = delete;
71   void operator=(const TempFile& ) = delete;
72 
73   // Closes and removes the file
74   ~TempFile();
75 
76   // Close the file descriptor if opened
77   void close();
78 
79   // File descriptor
80   // Important! It must NOT be close()-ed
81   int fd();
82 
83   // Absolute path of the file
path()84   std::string path() const { return path_; }
85 };
86 
87 template<typename T>
write_to_buffer(const T & object)88 zim::Buffer write_to_buffer(const T& object)
89 {
90   TempFile tmpFile("test_temp_file");
91   const auto tmp_fd = tmpFile.fd();
92   object.write(tmp_fd);
93   auto size = lseek(tmp_fd, 0, SEEK_END);
94 
95   auto buf = zim::Buffer::makeBuffer(zim::zsize_t(size));
96   lseek(tmp_fd, 0, SEEK_SET);
97   if (read(tmp_fd, const_cast<char*>(buf.data()), size) == -1)
98     throw std::runtime_error("Cannot read");
99   return buf;
100 }
101 
102 } // namespace unittests
103 
104 } // namespace zim
105 
106 #endif // ZIM_TEST_TOOLS_H
107