BUG: Wrote correct implementation of cmCopyFile.

This commit is contained in:
Brad King 2001-06-22 12:19:34 -04:00
parent 10e0197054
commit 373c1663cf
1 changed files with 41 additions and 14 deletions

View File

@ -657,27 +657,54 @@ bool cmSystemTools::FilesDiffer(const char* source,
} }
/**
* Copy a file named by "source" to the file named by "destination". This
* implementation makes correct use of the C++ standard file streams to
* perfectly copy any file with lines of any length (even binary files).
*/
void cmSystemTools::cmCopyFile(const char* source, void cmSystemTools::cmCopyFile(const char* source,
const char* destination) const char* destination)
{ {
std::ifstream fin(source); // Buffer length is only for block size. Any file would still be copied
char buff[4096]; // correctly if this were as small as 2.
std::ofstream fout(destination); const int buffer_length = 4096;
if(!fout ) char buffer[buffer_length];
{ std::ifstream fin(source,
cmSystemTools::Error("CopyFile failed to open input file", source); std::ios::binary | std::ios::in);
}
if(!fin) if(!fin)
{ {
cmSystemTools::Error("CopyFile failed to open output file", destination); cmSystemTools::Error("CopyFile failed to open input file \"",
source, "\"");
} }
while(fin) std::ofstream fout(destination,
std::ios::binary | std::ios::out | std::ios::trunc);
if(!fout)
{ {
fin.getline(buff, 4096); cmSystemTools::Error("CopyFile failed to open output file \"",
if(fin) destination, "\"");
}
while(fin.getline(buffer, buffer_length, '\n') || fin.gcount())
{ {
fout << buff << "\n"; std::streamsize count = fin.gcount();
if(fin.eof())
{
// Final line, but with no newline.
fout.write(buffer, count);
}
else if(fin.fail())
{
// Part of a line longer than our buffer, clear the fail bit of
// the stream so that we can continue.
fin.clear(fin.rdstate() & ~std::ios::failbit);
fout.write(buffer, count);
}
else
{
// Line on which a newline was encountered. It was read from
// the stream, but not stored.
--count;
fout.write(buffer, count);
fout << '\n';
} }
} }
} }