diff options
author | Brad King <brad.king@kitware.com> | 2001-06-22 16:19:34 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2001-06-22 16:19:34 (GMT) |
commit | 373c1663cffbc5c4ca7230f05465ce0f4207430c (patch) | |
tree | d463f88d2f540ee915de4eeb737f55df2810c08a /Source | |
parent | 10e0197054c469269259da047d60f85bcf292fe7 (diff) | |
download | CMake-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.cxx | 53 |
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'; } } } |