cmGeneratedFileStream.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #ifndef cmGeneratedFileStream_h
  4. #define cmGeneratedFileStream_h
  5. #include "cmConfigure.h" // IWYU pragma: keep
  6. #include "cm_codecvt.hxx"
  7. #include "cmsys/FStream.hxx"
  8. #include <string>
  9. // This is the first base class of cmGeneratedFileStream. It will be
  10. // created before and destroyed after the ofstream portion and can
  11. // therefore be used to manage the temporary file.
  12. class cmGeneratedFileStreamBase
  13. {
  14. protected:
  15. // This constructor does not prepare the temporary file. The open
  16. // method must be used.
  17. cmGeneratedFileStreamBase();
  18. // This constructor prepares the temporary output file.
  19. cmGeneratedFileStreamBase(const char* name);
  20. // The destructor renames the temporary output file to the real name.
  21. ~cmGeneratedFileStreamBase();
  22. // Internal methods to handle the temporary file. Open is always
  23. // called before the real stream is opened. Close is always called
  24. // after the real stream is closed and Okay is set to whether the
  25. // real stream was still valid for writing when it was closed.
  26. void Open(const char* name);
  27. bool Close();
  28. // Internal file replacement implementation.
  29. int RenameFile(const char* oldname, const char* newname);
  30. // Internal file compression implementation.
  31. int CompressFile(const char* oldname, const char* newname);
  32. // The name of the final destination file for the output.
  33. std::string Name;
  34. // The name of the temporary file.
  35. std::string TempName;
  36. // Whether to do a copy-if-different.
  37. bool CopyIfDifferent;
  38. // Whether the real file stream was valid when it was closed.
  39. bool Okay;
  40. // Whether the destination file is compressed
  41. bool Compress;
  42. // Whether the destination file is compressed
  43. bool CompressExtraExtension;
  44. };
  45. /** \class cmGeneratedFileStream
  46. * \brief Output stream for generated files.
  47. *
  48. * File generation should be atomic so that if CMake is killed then a
  49. * generated file is either the original version or the complete new
  50. * version. This stream is used to make sure file generation is
  51. * atomic. Optionally the output file is only replaced if its
  52. * contents have changed to prevent the file modification time from
  53. * being updated.
  54. */
  55. class cmGeneratedFileStream : private cmGeneratedFileStreamBase,
  56. public cmsys::ofstream
  57. {
  58. public:
  59. typedef cmsys::ofstream Stream;
  60. typedef codecvt::Encoding Encoding;
  61. /**
  62. * This constructor prepares a default stream. The open method must
  63. * be used before writing to the stream.
  64. */
  65. cmGeneratedFileStream(Encoding encoding = codecvt::None);
  66. /**
  67. * This constructor takes the name of the file to be generated. It
  68. * automatically generates a name for the temporary file. If the
  69. * file cannot be opened an error message is produced unless the
  70. * second argument is set to true.
  71. */
  72. cmGeneratedFileStream(const char* name, bool quiet = false,
  73. Encoding encoding = codecvt::None);
  74. /**
  75. * The destructor checks the stream status to be sure the temporary
  76. * file was successfully written before allowing the original to be
  77. * replaced.
  78. */
  79. ~cmGeneratedFileStream() override;
  80. /**
  81. * Open an output file by name. This should be used only with a
  82. * non-open stream. It automatically generates a name for the
  83. * temporary file. If the file cannot be opened an error message is
  84. * produced unless the second argument is set to true.
  85. */
  86. cmGeneratedFileStream& Open(const char* name, bool quiet = false,
  87. bool binaryFlag = false);
  88. /**
  89. * Close the output file. This should be used only with an open
  90. * stream. The temporary file is atomically renamed to the
  91. * destionation file if the stream is still valid when this method
  92. * is called.
  93. */
  94. bool Close();
  95. /**
  96. * Set whether copy-if-different is done.
  97. */
  98. void SetCopyIfDifferent(bool copy_if_different);
  99. /**
  100. * Set whether compression is done.
  101. */
  102. void SetCompression(bool compression);
  103. /**
  104. * Set whether compression has extra extension
  105. */
  106. void SetCompressionExtraExtension(bool ext);
  107. /**
  108. * Set name of the file that will hold the actual output. This method allows
  109. * the output file to be changed during the use of cmGeneratedFileStream.
  110. */
  111. void SetName(const std::string& fname);
  112. private:
  113. cmGeneratedFileStream(cmGeneratedFileStream const&); // not implemented
  114. };
  115. #endif