/src/CMake/Source/cmGeneratedFileStream.h
Line | Count | Source |
1 | | /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
2 | | file LICENSE.rst or https://cmake.org/licensing for details. */ |
3 | | #pragma once |
4 | | |
5 | | #include "cmConfigure.h" // IWYU pragma: keep |
6 | | |
7 | | #include <string> |
8 | | |
9 | | #include "cmsys/FStream.hxx" |
10 | | |
11 | | #include "cm_codecvt_Encoding.hxx" |
12 | | |
13 | | // This is the first base class of cmGeneratedFileStream. It will be |
14 | | // created before and destroyed after the ofstream portion and can |
15 | | // therefore be used to manage the temporary file. |
16 | | class cmGeneratedFileStreamBase |
17 | | { |
18 | | protected: |
19 | | // This constructor does not prepare the temporary file. The open |
20 | | // method must be used. |
21 | | cmGeneratedFileStreamBase(); |
22 | | |
23 | | // This constructor prepares the temporary output file. |
24 | | cmGeneratedFileStreamBase(std::string const& name); |
25 | | |
26 | | // The destructor renames the temporary output file to the real name. |
27 | | ~cmGeneratedFileStreamBase(); |
28 | | |
29 | | // Internal methods to handle the temporary file. Open is always |
30 | | // called before the real stream is opened. Close is always called |
31 | | // after the real stream is closed and Okay is set to whether the |
32 | | // real stream was still valid for writing when it was closed. |
33 | | void Open(std::string const& name); |
34 | | bool Close(); |
35 | | |
36 | | // Internal file replacement implementation. |
37 | | int RenameFile(std::string const& oldname, std::string const& newname); |
38 | | |
39 | | // Internal file compression implementation. |
40 | | int CompressFile(std::string const& oldname, std::string const& newname); |
41 | | |
42 | | // The name of the final destination file for the output. |
43 | | std::string Name; |
44 | | |
45 | | // The extension of the temporary file. |
46 | | std::string TempExt; |
47 | | |
48 | | // The name of the temporary file. |
49 | | std::string TempName; |
50 | | |
51 | | // Whether to do a copy-if-different. |
52 | | bool CopyIfDifferent = false; |
53 | | |
54 | | // Whether the real file stream was valid when it was closed. |
55 | | bool Okay = false; |
56 | | |
57 | | // Whether the destination file is compressed |
58 | | bool Compress = false; |
59 | | |
60 | | // Whether the destination file is compressed |
61 | | bool CompressExtraExtension = true; |
62 | | }; |
63 | | |
64 | | /** \class cmGeneratedFileStream |
65 | | * \brief Output stream for generated files. |
66 | | * |
67 | | * File generation should be atomic so that if CMake is killed then a |
68 | | * generated file is either the original version or the complete new |
69 | | * version. This stream is used to make sure file generation is |
70 | | * atomic. Optionally the output file is only replaced if its |
71 | | * contents have changed to prevent the file modification time from |
72 | | * being updated. |
73 | | */ |
74 | | class cmGeneratedFileStream |
75 | | : private cmGeneratedFileStreamBase |
76 | | , public cmsys::ofstream |
77 | | { |
78 | | public: |
79 | | using Stream = cmsys::ofstream; |
80 | | using Encoding = codecvt_Encoding; |
81 | | |
82 | | /** |
83 | | * This constructor prepares a default stream. The open method must |
84 | | * be used before writing to the stream. |
85 | | */ |
86 | | cmGeneratedFileStream(codecvt_Encoding encoding = codecvt_Encoding::None); |
87 | | |
88 | | /** |
89 | | * This constructor takes the name of the file to be generated. It |
90 | | * automatically generates a name for the temporary file. If the |
91 | | * file cannot be opened an error message is produced unless the |
92 | | * second argument is set to true. |
93 | | */ |
94 | | cmGeneratedFileStream(std::string const& name, bool quiet = false, |
95 | | codecvt_Encoding encoding = codecvt_Encoding::None); |
96 | | |
97 | | /** |
98 | | * The destructor checks the stream status to be sure the temporary |
99 | | * file was successfully written before allowing the original to be |
100 | | * replaced. |
101 | | */ |
102 | | ~cmGeneratedFileStream() override; |
103 | | |
104 | | cmGeneratedFileStream(cmGeneratedFileStream const&) = delete; |
105 | | |
106 | | /** |
107 | | * Open an output file by name. This should be used only with a |
108 | | * non-open stream. It automatically generates a name for the |
109 | | * temporary file. If the file cannot be opened an error message is |
110 | | * produced unless the second argument is set to true. |
111 | | */ |
112 | | cmGeneratedFileStream& Open(std::string const& name, bool quiet = false, |
113 | | bool binaryFlag = false); |
114 | | |
115 | | /** |
116 | | * Close the output file. This should be used only with an open |
117 | | * stream. The temporary file is atomically renamed to the |
118 | | * destination file if the stream is still valid when this method |
119 | | * is called. |
120 | | */ |
121 | | bool Close(); |
122 | | |
123 | | /** |
124 | | * Set whether copy-if-different is done. |
125 | | */ |
126 | | void SetCopyIfDifferent(bool copy_if_different); |
127 | | |
128 | | /** |
129 | | * Set whether compression is done. |
130 | | */ |
131 | | void SetCompression(bool compression); |
132 | | |
133 | | /** |
134 | | * Set whether compression has extra extension |
135 | | */ |
136 | | void SetCompressionExtraExtension(bool ext); |
137 | | |
138 | | /** |
139 | | * Set name of the file that will hold the actual output. This method allows |
140 | | * the output file to be changed during the use of cmGeneratedFileStream. |
141 | | */ |
142 | | void SetName(std::string const& fname); |
143 | | |
144 | | /** |
145 | | * Set set a custom temporary file extension used with 'Open'. |
146 | | * This does not work if the file was opened by the constructor. |
147 | | */ |
148 | | void SetTempExt(std::string const& ext); |
149 | | |
150 | | /** |
151 | | * Get the name of the temporary file. |
152 | | */ |
153 | 0 | std::string const& GetTempName() const { return this->TempName; } |
154 | | |
155 | | /** |
156 | | * Write a specific string using an alternate encoding. |
157 | | * Afterward, the original encoding is restored. |
158 | | */ |
159 | | void WriteAltEncoding(std::string const& data, codecvt_Encoding encoding); |
160 | | }; |