| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 | 
							- /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 
-    file Copyright.txt or https://cmake.org/licensing for details.  */
 
- #include "cmGeneratedFileStream.h"
 
- #include <cstdio>
 
- #include "cmStringAlgorithms.h"
 
- #include "cmSystemTools.h"
 
- #if !defined(CMAKE_BOOTSTRAP)
 
- #  include <cm3p/zlib.h>
 
- #  include "cm_codecvt.hxx"
 
- #endif
 
- cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
 
-   : OriginalLocale(this->getloc())
 
- {
 
- #ifndef CMAKE_BOOTSTRAP
 
-   if (encoding != codecvt::None) {
 
-     this->imbue(std::locale(this->OriginalLocale, new codecvt(encoding)));
 
-   }
 
- #else
 
-   static_cast<void>(encoding);
 
- #endif
 
- }
 
- cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name,
 
-                                              bool quiet, Encoding encoding)
 
-   : cmGeneratedFileStreamBase(name)
 
-   , Stream(this->TempName.c_str())
 
- {
 
-   // Check if the file opened.
 
-   if (!*this && !quiet) {
 
-     cmSystemTools::Error("Cannot open file for write: " + this->TempName);
 
-     cmSystemTools::ReportLastSystemError("");
 
-   }
 
- #ifndef CMAKE_BOOTSTRAP
 
-   if (encoding != codecvt::None) {
 
-     this->imbue(std::locale(this->getloc(), new codecvt(encoding)));
 
-   }
 
- #else
 
-   static_cast<void>(encoding);
 
- #endif
 
-   if (encoding == codecvt::UTF8_WITH_BOM) {
 
-     // Write the BOM encoding header into the file
 
-     char magic[] = { static_cast<char>(0xEF), static_cast<char>(0xBB),
 
-                      static_cast<char>(0xBF) };
 
-     this->write(magic, 3);
 
-   }
 
- }
 
- cmGeneratedFileStream::~cmGeneratedFileStream()
 
- {
 
-   // This is the first destructor called.  Check the status of the
 
-   // stream and give the information to the private base.  Next the
 
-   // stream will be destroyed which will close the temporary file.
 
-   // Finally the base destructor will be called to replace the
 
-   // destination file.
 
-   this->Okay = !this->fail();
 
- }
 
- cmGeneratedFileStream& cmGeneratedFileStream::Open(std::string const& name,
 
-                                                    bool quiet, bool binaryFlag)
 
- {
 
-   // Store the file name and construct the temporary file name.
 
-   this->cmGeneratedFileStreamBase::Open(name);
 
-   // Open the temporary output file.
 
-   if (binaryFlag) {
 
-     this->Stream::open(this->TempName.c_str(),
 
-                        std::ios::out | std::ios::binary);
 
-   } else {
 
-     this->Stream::open(this->TempName.c_str());
 
-   }
 
-   // Check if the file opened.
 
-   if (!*this && !quiet) {
 
-     cmSystemTools::Error("Cannot open file for write: " + this->TempName);
 
-     cmSystemTools::ReportLastSystemError("");
 
-   }
 
-   return *this;
 
- }
 
- bool cmGeneratedFileStream::Close()
 
- {
 
-   // Save whether the temporary output file is valid before closing.
 
-   this->Okay = !this->fail();
 
-   // Close the temporary output file.
 
-   this->Stream::close();
 
-   // Remove the temporary file (possibly by renaming to the real file).
 
-   return this->cmGeneratedFileStreamBase::Close();
 
- }
 
- void cmGeneratedFileStream::SetCopyIfDifferent(bool copy_if_different)
 
- {
 
-   this->CopyIfDifferent = copy_if_different;
 
- }
 
- void cmGeneratedFileStream::SetCompression(bool compression)
 
- {
 
-   this->Compress = compression;
 
- }
 
- void cmGeneratedFileStream::SetCompressionExtraExtension(bool ext)
 
- {
 
-   this->CompressExtraExtension = ext;
 
- }
 
- cmGeneratedFileStreamBase::cmGeneratedFileStreamBase() = default;
 
- cmGeneratedFileStreamBase::cmGeneratedFileStreamBase(std::string const& name)
 
- {
 
-   this->Open(name);
 
- }
 
- cmGeneratedFileStreamBase::~cmGeneratedFileStreamBase()
 
- {
 
-   this->Close();
 
- }
 
- void cmGeneratedFileStreamBase::Open(std::string const& name)
 
- {
 
-   // Save the original name of the file.
 
-   this->Name = name;
 
-   // Create the name of the temporary file.
 
-   this->TempName = name;
 
- #if defined(__VMS)
 
-   this->TempName += "_";
 
- #else
 
-   this->TempName += ".";
 
- #endif
 
-   if (!this->TempExt.empty()) {
 
-     this->TempName += this->TempExt;
 
-   } else {
 
-     char buf[64];
 
-     snprintf(buf, sizeof(buf), "tmp%05x",
 
-              cmSystemTools::RandomSeed() & 0xFFFFF);
 
-     this->TempName += buf;
 
-   }
 
-   // Make sure the temporary file that will be used is not present.
 
-   cmSystemTools::RemoveFile(this->TempName);
 
-   std::string dir = cmSystemTools::GetFilenamePath(this->TempName);
 
-   cmSystemTools::MakeDirectory(dir);
 
- }
 
- bool cmGeneratedFileStreamBase::Close()
 
- {
 
-   bool replaced = false;
 
-   std::string resname = this->Name;
 
-   if (this->Compress && this->CompressExtraExtension) {
 
-     resname += ".gz";
 
-   }
 
-   // Only consider replacing the destination file if no error
 
-   // occurred.
 
-   if (!this->Name.empty() && this->Okay &&
 
-       (!this->CopyIfDifferent ||
 
-        cmSystemTools::FilesDiffer(this->TempName, resname))) {
 
-     // The destination is to be replaced.  Rename the temporary to the
 
-     // destination atomically.
 
-     if (this->Compress) {
 
-       std::string gzname = cmStrCat(this->TempName, ".temp.gz");
 
-       if (this->CompressFile(this->TempName, gzname)) {
 
-         this->RenameFile(gzname, resname);
 
-       }
 
-       cmSystemTools::RemoveFile(gzname);
 
-     } else {
 
-       this->RenameFile(this->TempName, resname);
 
-     }
 
-     replaced = true;
 
-   }
 
-   // Else, the destination was not replaced.
 
-   //
 
-   // Always delete the temporary file. We never want it to stay around.
 
-   if (!this->TempName.empty()) {
 
-     cmSystemTools::RemoveFile(this->TempName);
 
-   }
 
-   return replaced;
 
- }
 
- #ifndef CMAKE_BOOTSTRAP
 
- int cmGeneratedFileStreamBase::CompressFile(std::string const& oldname,
 
-                                             std::string const& newname)
 
- {
 
-   gzFile gf = gzopen(newname.c_str(), "w");
 
-   if (!gf) {
 
-     return 0;
 
-   }
 
-   FILE* ifs = cmsys::SystemTools::Fopen(oldname, "r");
 
-   if (!ifs) {
 
-     gzclose(gf);
 
-     return 0;
 
-   }
 
-   size_t res;
 
-   const size_t BUFFER_SIZE = 1024;
 
-   char buffer[BUFFER_SIZE];
 
-   while ((res = fread(buffer, 1, BUFFER_SIZE, ifs)) > 0) {
 
-     if (!gzwrite(gf, buffer, static_cast<int>(res))) {
 
-       fclose(ifs);
 
-       gzclose(gf);
 
-       return 0;
 
-     }
 
-   }
 
-   fclose(ifs);
 
-   gzclose(gf);
 
-   return 1;
 
- }
 
- #else
 
- int cmGeneratedFileStreamBase::CompressFile(std::string const&,
 
-                                             std::string const&)
 
- {
 
-   return 0;
 
- }
 
- #endif
 
- int cmGeneratedFileStreamBase::RenameFile(std::string const& oldname,
 
-                                           std::string const& newname)
 
- {
 
-   return cmSystemTools::RenameFile(oldname, newname);
 
- }
 
- void cmGeneratedFileStream::SetName(const std::string& fname)
 
- {
 
-   this->Name = fname;
 
- }
 
- void cmGeneratedFileStream::SetTempExt(std::string const& ext)
 
- {
 
-   this->TempExt = ext;
 
- }
 
- void cmGeneratedFileStream::WriteRaw(std::string const& data)
 
- {
 
- #ifndef CMAKE_BOOTSTRAP
 
-   std::locale activeLocale = this->imbue(this->OriginalLocale);
 
-   this->write(data.data(), data.size());
 
-   this->imbue(activeLocale);
 
- #else
 
-   this->write(data.data(), data.size());
 
- #endif
 
- }
 
 
  |