| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file Copyright.txt or https://cmake.org/licensing for details. */ |
| #pragma once |
| |
| #include "cmConfigure.h" // IWYU pragma: keep |
| |
| #include <string> |
| |
| #include "cmsys/FStream.hxx" |
| |
| #include "cm_codecvt.hxx" |
| |
| // This is the first base class of cmGeneratedFileStream. It will be |
| // created before and destroyed after the ofstream portion and can |
| // therefore be used to manage the temporary file. |
| class cmGeneratedFileStreamBase |
| { |
| protected: |
| // This constructor does not prepare the temporary file. The open |
| // method must be used. |
| cmGeneratedFileStreamBase(); |
| |
| // This constructor prepares the temporary output file. |
| cmGeneratedFileStreamBase(std::string const& name); |
| |
| // The destructor renames the temporary output file to the real name. |
| ~cmGeneratedFileStreamBase(); |
| |
| // Internal methods to handle the temporary file. Open is always |
| // called before the real stream is opened. Close is always called |
| // after the real stream is closed and Okay is set to whether the |
| // real stream was still valid for writing when it was closed. |
| void Open(std::string const& name); |
| bool Close(); |
| |
| // Internal file replacement implementation. |
| int RenameFile(std::string const& oldname, std::string const& newname); |
| |
| // Internal file compression implementation. |
| int CompressFile(std::string const& oldname, std::string const& newname); |
| |
| // The name of the final destination file for the output. |
| std::string Name; |
| |
| // The extension of the temporary file. |
| std::string TempExt; |
| |
| // The name of the temporary file. |
| std::string TempName; |
| |
| // Whether to do a copy-if-different. |
| bool CopyIfDifferent = false; |
| |
| // Whether the real file stream was valid when it was closed. |
| bool Okay = false; |
| |
| // Whether the destination file is compressed |
| bool Compress = false; |
| |
| // Whether the destination file is compressed |
| bool CompressExtraExtension = true; |
| }; |
| |
| /** \class cmGeneratedFileStream |
| * \brief Output stream for generated files. |
| * |
| * File generation should be atomic so that if CMake is killed then a |
| * generated file is either the original version or the complete new |
| * version. This stream is used to make sure file generation is |
| * atomic. Optionally the output file is only replaced if its |
| * contents have changed to prevent the file modification time from |
| * being updated. |
| */ |
| class cmGeneratedFileStream |
| : private cmGeneratedFileStreamBase |
| , public cmsys::ofstream |
| { |
| public: |
| using Stream = cmsys::ofstream; |
| using Encoding = codecvt::Encoding; |
| |
| /** |
| * This constructor prepares a default stream. The open method must |
| * be used before writing to the stream. |
| */ |
| cmGeneratedFileStream(Encoding encoding = codecvt::None); |
| |
| /** |
| * This constructor takes the name of the file to be generated. It |
| * automatically generates a name for the temporary file. If the |
| * file cannot be opened an error message is produced unless the |
| * second argument is set to true. |
| */ |
| cmGeneratedFileStream(std::string const& name, bool quiet = false, |
| Encoding encoding = codecvt::None); |
| |
| /** |
| * The destructor checks the stream status to be sure the temporary |
| * file was successfully written before allowing the original to be |
| * replaced. |
| */ |
| ~cmGeneratedFileStream() override; |
| |
| cmGeneratedFileStream(cmGeneratedFileStream const&) = delete; |
| |
| /** |
| * Open an output file by name. This should be used only with a |
| * non-open stream. It automatically generates a name for the |
| * temporary file. If the file cannot be opened an error message is |
| * produced unless the second argument is set to true. |
| */ |
| cmGeneratedFileStream& Open(std::string const& name, bool quiet = false, |
| bool binaryFlag = false); |
| |
| /** |
| * Close the output file. This should be used only with an open |
| * stream. The temporary file is atomically renamed to the |
| * destination file if the stream is still valid when this method |
| * is called. |
| */ |
| bool Close(); |
| |
| /** |
| * Set whether copy-if-different is done. |
| */ |
| void SetCopyIfDifferent(bool copy_if_different); |
| |
| /** |
| * Set whether compression is done. |
| */ |
| void SetCompression(bool compression); |
| |
| /** |
| * Set whether compression has extra extension |
| */ |
| void SetCompressionExtraExtension(bool ext); |
| |
| /** |
| * Set name of the file that will hold the actual output. This method allows |
| * the output file to be changed during the use of cmGeneratedFileStream. |
| */ |
| void SetName(const std::string& fname); |
| |
| /** |
| * Set set a custom temporary file extension used with 'Open'. |
| * This does not work if the file was opened by the constructor. |
| */ |
| void SetTempExt(std::string const& ext); |
| |
| /** |
| * Writes the given string directly to the file without changing the |
| * encoding. |
| */ |
| void WriteRaw(std::string const& data); |
| |
| private: |
| // The original locale of the stream (performs no encoding conversion). |
| std::locale OriginalLocale; |
| }; |