summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2006-04-14 02:56:32 (GMT)
committerBrad King <brad.king@kitware.com>2006-04-14 02:56:32 (GMT)
commitb8a589bb1d5e4d1e10d0da77048ca9522755095c (patch)
treee43d73ef06cb4d737b2c8b25276fce2eda361dfe /Source
parent58d0c5e17670a61d7fb9b4be5978e1b29f801bb4 (diff)
downloadCMake-b8a589bb1d5e4d1e10d0da77048ca9522755095c.zip
CMake-b8a589bb1d5e4d1e10d0da77048ca9522755095c.tar.gz
CMake-b8a589bb1d5e4d1e10d0da77048ca9522755095c.tar.bz2
ENH: Improved implementation of FilesDiffer to avoid allocating enough memory for the entire file twice. Instead using a block-at-a-time comparison.
Diffstat (limited to 'Source')
-rw-r--r--Source/kwsys/SystemTools.cxx47
1 files changed, 28 insertions, 19 deletions
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index b404914..93cc5b3 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -1419,7 +1419,8 @@ bool SystemTools::CopyFileIfDifferent(const char* source,
return true;
}
-
+#define KWSYS_ST_BUFFER 4096
+
bool SystemTools::FilesDiffer(const char* source,
const char* destination)
{
@@ -1459,28 +1460,36 @@ bool SystemTools::FilesDiffer(const char* source,
return true;
}
- char* source_buf = new char[statSource.st_size];
- char* dest_buf = new char[statSource.st_size];
+ // Compare the files a block at a time.
+ char source_buf[KWSYS_ST_BUFFER];
+ char dest_buf[KWSYS_ST_BUFFER];
+ long nleft = statSource.st_size;
+ while(nleft > 0)
+ {
+ // Read a block from each file.
+ long nnext = (nleft > KWSYS_ST_BUFFER)? KWSYS_ST_BUFFER : nleft;
+ finSource.read(source_buf, nnext);
+ finDestination.read(dest_buf, nnext);
- finSource.read(source_buf, statSource.st_size);
- finDestination.read(dest_buf, statSource.st_size);
+ // If either failed to read assume they are different.
+ if(static_cast<long>(finSource.gcount()) != nnext ||
+ static_cast<long>(finDestination.gcount()) != nnext)
+ {
+ return true;
+ }
- if(statSource.st_size != static_cast<long>(finSource.gcount()) ||
- statSource.st_size != static_cast<long>(finDestination.gcount()))
- {
- // Failed to read files.
- delete [] source_buf;
- delete [] dest_buf;
- return true;
- }
- int ret = memcmp((const void*)source_buf,
- (const void*)dest_buf,
- statSource.st_size);
+ // If this block differs the file differs.
+ if(memcmp((const void*)source_buf, (const void*)dest_buf, nnext) != 0)
+ {
+ return true;
+ }
- delete [] dest_buf;
- delete [] source_buf;
+ // Update the byte count remaining.
+ nleft -= nnext;
+ }
- return ret != 0;
+ // No differences found.
+ return false;
}