| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 | /*============================================================================  CMake - Cross Platform Makefile Generator  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium  Distributed under the OSI-approved BSD License (the "License");  see accompanying file Copyright.txt for details.  This software is distributed WITHOUT ANY WARRANTY; without even the  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the License for more information.============================================================================*/#include "cmGeneratedFileStream.h"#include "cmSystemTools.h"#if defined(CMAKE_BUILD_WITH_CMAKE)# include <cm_zlib.h>#endif//----------------------------------------------------------------------------cmGeneratedFileStream::cmGeneratedFileStream():  cmGeneratedFileStreamBase(), Stream(){}//----------------------------------------------------------------------------cmGeneratedFileStream::cmGeneratedFileStream(const char* name, bool quiet):  cmGeneratedFileStreamBase(name),  Stream(TempName.c_str()){  // Check if the file opened.  if(!*this && !quiet)    {    cmSystemTools::Error("Cannot open file for write: ",                         this->TempName.c_str());    cmSystemTools::ReportLastSystemError("");    }}//----------------------------------------------------------------------------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)?true:false;}//----------------------------------------------------------------------------cmGeneratedFileStream&cmGeneratedFileStream::Open(const char* 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(), std::ios::out);    }  // Check if the file opened.  if(!*this && !quiet)    {    cmSystemTools::Error("Cannot open file for write: ",                         this->TempName.c_str());    cmSystemTools::ReportLastSystemError("");    }  return *this;}//----------------------------------------------------------------------------boolcmGeneratedFileStream::Close(){  // Save whether the temporary output file is valid before closing.  this->Okay = (*this)?true:false;  // 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():  Name(),  TempName(),  CopyIfDifferent(false),  Okay(false),  Compress(false),  CompressExtraExtension(true){}//----------------------------------------------------------------------------cmGeneratedFileStreamBase::cmGeneratedFileStreamBase(const char* name):  Name(),  TempName(),  CopyIfDifferent(false),  Okay(false),  Compress(false),  CompressExtraExtension(true){  this->Open(name);}//----------------------------------------------------------------------------cmGeneratedFileStreamBase::~cmGeneratedFileStreamBase(){  this->Close();}//----------------------------------------------------------------------------void cmGeneratedFileStreamBase::Open(const char* 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 += "_tmp";#else  this->TempName += ".tmp";#endif  // 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.c_str());}//----------------------------------------------------------------------------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 = this->TempName + ".temp.gz";      if ( this->CompressFile(this->TempName.c_str(), gzname.c_str()) )        {        this->RenameFile(gzname.c_str(), resname.c_str());        }      cmSystemTools::RemoveFile(gzname);      }    else      {      this->RenameFile(this->TempName.c_str(), resname.c_str());      }    replaced = true;    }  // Else, the destination was not replaced.  //  // Always delete the temporary file. We never want it to stay around.  cmSystemTools::RemoveFile(this->TempName);  return replaced;}//----------------------------------------------------------------------------#ifdef CMAKE_BUILD_WITH_CMAKEint cmGeneratedFileStreamBase::CompressFile(const char* oldname,                                            const char* newname){  gzFile gf = gzopen(newname, "w");  if ( !gf )    {    return 0;    }  FILE* ifs = cmsys::SystemTools::Fopen(oldname, "r");  if ( !ifs )    {    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;}#elseint cmGeneratedFileStreamBase::CompressFile(const char*, const char*){  return 0;}#endif//----------------------------------------------------------------------------int cmGeneratedFileStreamBase::RenameFile(const char* oldname,                                          const char* newname){  return cmSystemTools::RenameFile(oldname, newname);}//----------------------------------------------------------------------------void cmGeneratedFileStream::SetName(const std::string& fname){  this->Name = fname;}
 |