BUG: Wrote correct implementation of cmCopyFile.
This commit is contained in:
parent
10e0197054
commit
373c1663cf
|
@ -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';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue