summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2001-06-22 16:19:34 (GMT)
committerBrad King <brad.king@kitware.com>2001-06-22 16:19:34 (GMT)
commit373c1663cffbc5c4ca7230f05465ce0f4207430c (patch)
treed463f88d2f540ee915de4eeb737f55df2810c08a /Source
parent10e0197054c469269259da047d60f85bcf292fe7 (diff)
downloadCMake-373c1663cffbc5c4ca7230f05465ce0f4207430c.zip
CMake-373c1663cffbc5c4ca7230f05465ce0f4207430c.tar.gz
CMake-373c1663cffbc5c4ca7230f05465ce0f4207430c.tar.bz2
BUG: Wrote correct implementation of cmCopyFile.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmSystemTools.cxx53
1 files changed, 40 insertions, 13 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index c05238a..556bacc 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -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,
- const char* destination)
+ const char* destination)
{
- std::ifstream fin(source);
- char buff[4096];
- std::ofstream fout(destination);
- if(!fout )
+ // Buffer length is only for block size. Any file would still be copied
+ // correctly if this were as small as 2.
+ const int buffer_length = 4096;
+ char buffer[buffer_length];
+ std::ifstream fin(source,
+ std::ios::binary | std::ios::in);
+ if(!fin)
{
- cmSystemTools::Error("CopyFile failed to open input file", source);
+ cmSystemTools::Error("CopyFile failed to open input file \"",
+ source, "\"");
}
- if(!fin)
+ std::ofstream fout(destination,
+ std::ios::binary | std::ios::out | std::ios::trunc);
+ if(!fout)
{
- cmSystemTools::Error("CopyFile failed to open output file", destination);
+ cmSystemTools::Error("CopyFile failed to open output file \"",
+ destination, "\"");
}
- while(fin)
+ while(fin.getline(buffer, buffer_length, '\n') || fin.gcount())
{
- fin.getline(buff, 4096);
- if(fin)
+ 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
{
- fout << buff << "\n";
+ // Line on which a newline was encountered. It was read from
+ // the stream, but not stored.
+ --count;
+ fout.write(buffer, count);
+ fout << '\n';
}
}
}