summaryrefslogtreecommitdiffstats
path: root/Source/kwsys/SystemTools.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/kwsys/SystemTools.cxx')
-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;
}