summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/IcePatch2/Client.cpp461
-rwxr-xr-xcpp/src/IcePatch2/ClientUtil.cpp428
-rw-r--r--cpp/src/IcePatch2/Util.cpp86
-rwxr-xr-xcpp/src/IcePatch2/icepatch2.dsp8
4 files changed, 525 insertions, 458 deletions
diff --git a/cpp/src/IcePatch2/Client.cpp b/cpp/src/IcePatch2/Client.cpp
index c9007287fc6..3331e4b5440 100644
--- a/cpp/src/IcePatch2/Client.cpp
+++ b/cpp/src/IcePatch2/Client.cpp
@@ -8,13 +8,8 @@
// **********************************************************************
#include <Ice/Application.h>
-#include <IcePatch2/FileServerI.h>
#include <IcePatch2/Util.h>
-#include <fstream>
-
-#ifdef _WIN32
-# include <direct.h>
-#endif
+#include <IcePatch2/ClientUtil.h>
using namespace std;
using namespace Ice;
@@ -37,32 +32,98 @@ private:
};
-class DecompressorDestroyer
+class TextPatcherFeedback : public PatcherFeedback
{
public:
- DecompressorDestroyer(DecompressorPtr decompressor) :
- _decompressor(decompressor)
+ virtual bool
+ noFileSummary(const string& reason)
+ {
+ cout << "Cannot load file summary:\n" << reason << endl;
+ string answer;
+ do
+ {
+ cout << "Do a thorough patch? (yes/no)" << endl;
+ cin >> answer;
+ transform(answer.begin(), answer.end(), answer.begin(), ::tolower);
+ if(answer == "no")
+ {
+ return false;
+ }
+ }
+ while(answer != "yes");
+ return true;
+ }
+
+ virtual bool
+ fileListStart()
+ {
+ _lastProgress = "0%";
+ cout << "Getting list of files to patch: " << _lastProgress << flush;
+ return true;
+ }
+
+ virtual bool
+ fileListProgress(Int percent)
+ {
+ for(unsigned int i = 0; i < _lastProgress.size(); ++i)
+ {
+ cout << '\b';
+ }
+ ostringstream s;
+ s << percent << '%';
+ _lastProgress = s.str();
+ cout << _lastProgress << flush;
+ return true;
+ }
+
+ virtual bool
+ fileListEnd()
+ {
+ cout << endl;
+ return true;
+ }
+
+ virtual bool
+ patchStart(const string& path, Long size, Long totalProgress, Long totalSize)
{
+ ostringstream s;
+ s << "0/" << size << " (" << totalProgress << '/' << totalSize << ')';
+ _lastProgress = s.str();
+ cout << getBasename(path) << ' ' << _lastProgress << flush;
+ return true;
}
- ~DecompressorDestroyer()
+ virtual bool
+ patchProgress(Long progress, Long size, Long totalProgress, Long totalSize)
{
- _decompressor->destroy();
- _decompressor->getThreadControl().join();
+ for(unsigned int i = 0; i < _lastProgress.size(); ++i)
+ {
+ cout << '\b';
+ }
+ ostringstream s;
+ s << progress << '/' << size << " (" << totalProgress << '/' << totalSize << ')';
+ _lastProgress = s.str();
+ cout << _lastProgress << flush;
+ return true;
+ }
+
+ virtual bool
+ patchEnd()
+ {
+ cout << endl;
+ return true;
}
private:
- const DecompressorPtr _decompressor;
+ string _lastProgress;
};
int
IcePatch2::Client::run(int argc, char* argv[])
{
- bool thorough = false;
- bool dry = false;
- string dataDir;
+ PropertiesPtr properties = communicator()->getProperties();
for(int i = 1; i < argc; ++i)
{
@@ -78,11 +139,11 @@ IcePatch2::Client::run(int argc, char* argv[])
}
else if(strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--thorough") == 0)
{
- thorough = true;
+ properties->setProperty("IcePatch2.Thorough", "1");
}
else if(strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--dry") == 0)
{
- dry = true;
+ properties->setProperty("IcePatch2.DryRun", "1");
}
else if(argv[i][0] == '-')
{
@@ -92,9 +153,9 @@ IcePatch2::Client::run(int argc, char* argv[])
}
else
{
- if(dataDir.empty())
+ if(properties->getProperty("IcePatch2.Directory").empty())
{
- dataDir = argv[i];
+ properties->setProperty("IcePatch2.Directory", argv[i]);
}
else
{
@@ -105,366 +166,22 @@ IcePatch2::Client::run(int argc, char* argv[])
}
}
- PropertiesPtr properties = communicator()->getProperties();
-
- if(dataDir.empty())
- {
- string dataDir = properties->getProperty("IcePatch2.Directory");
- if(dataDir.empty())
- {
- cerr << argv[0] << ": no data directory specified" << endl;
- usage(argv[0]);
- return EXIT_FAILURE;
- }
- }
-
- Int chunk = properties->getPropertyAsIntWithDefault("IcePatch2.ChunkSize", 100000);
- if(chunk < 1)
- {
- chunk = 1;
- }
-
try
{
- FileInfoSeq infoSeq;
-
-#ifdef _WIN32
- char cwd[_MAX_PATH];
- if(_getcwd(cwd, _MAX_PATH) == NULL)
-#else
- char cwd[PATH_MAX];
- if(getcwd(cwd, PATH_MAX) == NULL)
-#endif
- {
- throw string("cannot get the current directory: ") + strerror(errno);
- }
-
- dataDir = normalize(string(cwd) + '/' + dataDir);
-
- if(chdir(dataDir.c_str()) == -1)
- {
- throw "cannot change directory to `" + dataDir + "': " + strerror(errno);
- }
-
- if(!thorough)
- {
- try
- {
- loadFileInfoSeq(dataDir, infoSeq);
- }
- catch(const string& ex)
- {
- cout << "Cannot load file summary:\n" << ex << endl;
- string answer;
- do
- {
- cout << "Do a thorough patch? (yes/no)" << endl;
- cin >> answer;
- transform(answer.begin(), answer.end(), answer.begin(), ::tolower);
- if(answer == "no")
- {
- return EXIT_SUCCESS;
- }
- }
- while(answer != "yes");
- thorough = true;
- }
- }
-
- if(thorough)
- {
- getFileInfoSeq(".", infoSeq, false, false, false);
- saveFileInfoSeq(dataDir, infoSeq);
- }
-
- const char* endpointsProperty = "IcePatch2.Endpoints";
- const string endpoints = properties->getProperty(endpointsProperty);
- if(endpoints.empty())
- {
- cerr << argv[0] << ": property `" << endpointsProperty << "' is not set" << endl;
- return EXIT_FAILURE;
- }
-
- const char* idProperty = "IcePatch2.Identity";
- const Identity id = stringToIdentity(properties->getPropertyWithDefault(idProperty, "IcePatch2/server"));
-
- ObjectPrx fileServerBase = communicator()->stringToProxy(identityToString(id) + ':' + endpoints);
- FileServerPrx fileServer = FileServerPrx::checkedCast(fileServerBase);
- if(!fileServer)
- {
- cerr << argv[0] << ": proxy `" << identityToString(id) << ':' << endpoints << "' is not a file server."
- << endl;
- return EXIT_FAILURE;
- }
-
- FileTree0 tree0;
- getFileTree0(infoSeq, tree0);
-
- FileInfoSeq removeFiles;
- FileInfoSeq updateFiles;
-
- ByteSeq empty(20, 0);
-
- if(tree0.checksum != fileServer->getChecksum())
- {
- string progress = "0%";
- cout << "Getting list of files to patch: " << progress << flush;
-
- ByteSeqSeq checksum0Seq = fileServer->getChecksum0Seq();
- if(checksum0Seq.size() != 256)
- {
- cerr << argv[0] << ": server returned illegal value" << endl;
- return EXIT_FAILURE;
- }
-
- for(int node0 = 0; node0 < 256; ++node0)
- {
- if(tree0.nodes[node0].checksum != checksum0Seq[node0])
- {
- FileInfoSeq fileSeq = fileServer->getFileInfo1Seq(node0);
-
- sort(fileSeq.begin(), fileSeq.end(), FileInfoLess());
- fileSeq.erase(unique(fileSeq.begin(), fileSeq.end(), FileInfoEqual()), fileSeq.end());
-
- set_difference(tree0.nodes[node0].files.begin(),
- tree0.nodes[node0].files.end(),
- fileSeq.begin(),
- fileSeq.end(),
- back_inserter(removeFiles),
- FileInfoLess());
-
- set_difference(fileSeq.begin(),
- fileSeq.end(),
- tree0.nodes[node0].files.begin(),
- tree0.nodes[node0].files.end(),
- back_inserter(updateFiles),
- FileInfoLess());
- }
-
- for(unsigned int i = 0; i < progress.size(); ++i)
- {
- cout << '\b';
- }
- ostringstream s;
- s << (node0 + 1) * 100 / 256 << '%';
- progress = s.str();
- cout << progress << flush;
- }
- }
-
- cout << endl;
-
- sort(removeFiles.begin(), removeFiles.end(), FileInfoLess());
- sort(updateFiles.begin(), updateFiles.end(), FileInfoLess());
-
- FileInfoSeq::const_iterator p;
-
- if(!removeFiles.empty())
- {
- p = removeFiles.begin();
- while(p != removeFiles.end())
- {
- cout << "remove: " << getBasename(p->path) << endl;
-
- if(!dry)
- {
- try
- {
- removeRecursive(p->path);
- }
- catch(const string&)
- {
- }
- }
-
- string dir = p->path + '/';
-
- do
- {
- ++p;
- }
- while(p != removeFiles.end() && p->path.size() > dir.size() &&
- p->path.compare(0, dir.size(), dir) == 0);
- }
-
- if(!dry)
- {
- FileInfoSeq newInfoSeq;
- newInfoSeq.reserve(infoSeq.size());
-
- set_difference(infoSeq.begin(),
- infoSeq.end(),
- removeFiles.begin(),
- removeFiles.end(),
- back_inserter(newInfoSeq),
- FileInfoLess());
-
- infoSeq.swap(newInfoSeq);
-
- saveFileInfoSeq(dataDir, infoSeq);
- }
- }
-
- if(!updateFiles.empty())
- {
- string pathLog = dataDir + ".log";
- ofstream fileLog;
-
- if(!dry)
- {
- fileLog.open(pathLog.c_str());
- if(!fileLog)
- {
- cerr << argv[0] << ": cannot open `" + pathLog + "' for writing: " + strerror(errno);
- return EXIT_FAILURE;
- }
- }
-
- Long total = 0;
- Long updated = 0;
-
- for(p = updateFiles.begin(); p != updateFiles.end(); ++p)
- {
- if(p->size > 0) // Regular, non-empty file?
- {
- total += p->size;
- }
- }
-
- DecompressorPtr decompressor = new Decompressor;
- DecompressorDestroyer decompressorDestroyer(decompressor);
- decompressor->start();
-
- for(p = updateFiles.begin(); p != updateFiles.end(); ++p)
- {
- cout << "update: " << getBasename(p->path) << ' ' << flush;
-
- if(p->size < 0) // Directory?
- {
- if(!dry)
- {
- createDirectoryRecursive(p->path);
- fileLog << *p << endl;
- }
- }
- else // Regular file.
- {
- string pathBZ2 = p->path + ".bz2";
- ofstream fileBZ2;
-
- if(!dry)
- {
- string dir = getDirname(pathBZ2);
- if(!dir.empty())
- {
- createDirectoryRecursive(dir);
- }
-
- try
- {
- removeRecursive(pathBZ2);
- }
- catch(...)
- {
- }
-
- fileBZ2.open(pathBZ2.c_str(), ios::binary);
- if(!fileBZ2)
- {
- cerr << argv[0] << ": cannot open `" + pathBZ2 + "' for writing: " + strerror(errno);
- return EXIT_FAILURE;
- }
- }
-
- Int pos = 0;
- string progress;
-
- while(pos < p->size)
- {
- ByteSeq bytes;
-
- try
- {
- bytes = fileServer->getFileCompressed(p->path, pos, chunk);
- }
- catch(const FileAccessException& ex)
- {
- cerr << argv[0] << ": server error for `" << p->path << "':" << ex.reason << endl;
- return EXIT_FAILURE;
- }
-
- if(bytes.empty())
- {
- cerr << argv[0] << ": size mismatch for `" << p->path << "'" << endl;
- return EXIT_FAILURE;
- }
-
- if(!dry)
- {
- fileBZ2.write(reinterpret_cast<char*>(&bytes[0]), bytes.size());
-
- if(!fileBZ2)
- {
- cerr << argv[0] << ": cannot write `" + pathBZ2 + "': " + strerror(errno);
- return EXIT_FAILURE;
- }
- }
-
- pos += bytes.size();
- updated += bytes.size();
-
- for(unsigned int i = 0; i < progress.size(); ++i)
- {
- cout << '\b';
- }
- ostringstream s;
- s << pos << '/' << p->size << " (" << updated << '/' << total << ')';
- progress = s.str();
- cout << progress << flush;
- }
-
- if(!dry)
- {
- fileBZ2.close();
- fileLog << *p << endl;
-
- decompressor->checkForException();
- decompressor->add(p->path);
- }
- }
-
- cout << endl;
- }
-
- decompressor->destroy();
- decompressor->getThreadControl().join();
- decompressor->checkForException();
-
- if(!dry)
- {
- fileLog.close();
-
- FileInfoSeq newInfoSeq;
- newInfoSeq.reserve(infoSeq.size());
-
- set_union(infoSeq.begin(),
- infoSeq.end(),
- updateFiles.begin(),
- updateFiles.end(),
- back_inserter(newInfoSeq),
- FileInfoLess());
-
- infoSeq.swap(newInfoSeq);
-
- saveFileInfoSeq(dataDir, infoSeq);
- }
- }
+ PatcherFeedbackPtr feedback = new TextPatcherFeedback;
+ PatcherPtr patcher = new Patcher(communicator(), feedback);
+ patcher->patch();
}
catch(const string& ex)
{
cerr << argv[0] << ": " << ex << endl;
return EXIT_FAILURE;
}
+ catch(const char* ex)
+ {
+ cerr << argv[0] << ": " << ex << endl;
+ return EXIT_FAILURE;
+ }
return EXIT_SUCCESS;
}
diff --git a/cpp/src/IcePatch2/ClientUtil.cpp b/cpp/src/IcePatch2/ClientUtil.cpp
new file mode 100755
index 00000000000..fa47fb55f8f
--- /dev/null
+++ b/cpp/src/IcePatch2/ClientUtil.cpp
@@ -0,0 +1,428 @@
+// **********************************************************************
+//
+// Copyright (c) 2004 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IcePatch2/ClientUtil.h>
+#include <IcePatch2/Util.h>
+#include <IcePatch2/FileServerI.h>
+
+#ifdef _WIN32
+# include <direct.h>
+#endif
+
+using namespace std;
+using namespace Ice;
+using namespace IcePatch2;
+
+IcePatch2::Patcher::Patcher(const CommunicatorPtr& communicator, const PatcherFeedbackPtr& feedback) :
+ _communicator(communicator),
+ _feedback(feedback),
+ _stop(false)
+{
+}
+
+IcePatch2::Patcher::~Patcher()
+{
+ assert(_stop);
+}
+
+void
+IcePatch2::Patcher::patch()
+{
+ PropertiesPtr properties = _communicator->getProperties();
+
+ string dataDir = properties->getProperty("IcePatch2.Directory");
+ bool dryRun = properties->getPropertyAsInt("IcePatch2.DryRun") > 0;
+ bool thorough = properties->getPropertyAsInt("IcePatch2.Thorough") > 0;
+ Int chunkSize = properties->getPropertyAsIntWithDefault("IcePatch2.ChunkSize", 100000);
+
+ if(dataDir.empty())
+ {
+ throw "no data directory specified";
+ }
+
+ if(chunkSize < 1)
+ {
+ chunkSize = 1;
+ }
+
+ FileInfoSeq infoSeq;
+
+#ifdef _WIN32
+ char cwd[_MAX_PATH];
+ if(_getcwd(cwd, _MAX_PATH) == NULL)
+#else
+ char cwd[PATH_MAX];
+ if(getcwd(cwd, PATH_MAX) == NULL)
+#endif
+ {
+ throw string("cannot get the current directory: ") + strerror(errno);
+ }
+
+ dataDir = normalize(string(cwd) + '/' + dataDir);
+
+ if(chdir(dataDir.c_str()) == -1)
+ {
+ throw "cannot change directory to `" + dataDir + "': " + strerror(errno);
+ }
+
+ if(!thorough)
+ {
+ try
+ {
+ loadFileInfoSeq(dataDir, infoSeq);
+ }
+ catch(const string& ex)
+ {
+ thorough = _feedback->noFileSummary(ex);
+ }
+ }
+
+ if(thorough)
+ {
+ getFileInfoSeq(".", infoSeq, false, false, false);
+ saveFileInfoSeq(dataDir, infoSeq);
+ }
+
+ const char* endpointsProperty = "IcePatch2.Endpoints";
+ const string endpoints = properties->getProperty(endpointsProperty);
+ if(endpoints.empty())
+ {
+ throw "property `" + endpointsProperty + "' is not set";
+ }
+
+ const char* idProperty = "IcePatch2.Identity";
+ const Identity id = stringToIdentity(properties->getPropertyWithDefault(idProperty, "IcePatch2/server"));
+
+ ObjectPrx fileServerBase = _communicator->stringToProxy(identityToString(id) + ':' + endpoints);
+ FileServerPrx fileServer = FileServerPrx::checkedCast(fileServerBase);
+ if(!fileServer)
+ {
+ throw "proxy `" + identityToString(id) + ':' + endpoints + "' is not a file server.";
+ }
+
+ FileTree0 tree0;
+ getFileTree0(infoSeq, tree0);
+
+ FileInfoSeq removeFiles;
+ FileInfoSeq updateFiles;
+
+ ByteSeq empty(20, 0);
+
+ if(tree0.checksum != fileServer->getChecksum())
+ {
+ _feedback->fileListStart();
+
+ ByteSeqSeq checksum0Seq = fileServer->getChecksum0Seq();
+ if(checksum0Seq.size() != 256)
+ {
+ throw "server returned illegal value";
+ }
+
+ for(int node0 = 0; node0 < 256; ++node0)
+ {
+ if(tree0.nodes[node0].checksum != checksum0Seq[node0])
+ {
+ FileInfoSeq fileSeq = fileServer->getFileInfo1Seq(node0);
+
+ sort(fileSeq.begin(), fileSeq.end(), FileInfoLess());
+ fileSeq.erase(unique(fileSeq.begin(), fileSeq.end(), FileInfoEqual()), fileSeq.end());
+
+ set_difference(tree0.nodes[node0].files.begin(),
+ tree0.nodes[node0].files.end(),
+ fileSeq.begin(),
+ fileSeq.end(),
+ back_inserter(removeFiles),
+ FileInfoLess());
+
+ set_difference(fileSeq.begin(),
+ fileSeq.end(),
+ tree0.nodes[node0].files.begin(),
+ tree0.nodes[node0].files.end(),
+ back_inserter(updateFiles),
+ FileInfoLess());
+ }
+
+ _feedback->fileListProgress((node0 + 1) * 100 / 256);
+ }
+
+ _feedback->fileListEnd();
+ }
+
+ sort(removeFiles.begin(), removeFiles.end(), FileInfoLess());
+ sort(updateFiles.begin(), updateFiles.end(), FileInfoLess());
+
+ FileInfoSeq::const_iterator p;
+
+ if(!removeFiles.empty())
+ {
+ p = removeFiles.begin();
+ while(p != removeFiles.end())
+ {
+ if(!dryRun)
+ {
+ try
+ {
+ removeRecursive(p->path);
+ }
+ catch(const string&)
+ {
+ }
+ }
+
+ string dir = p->path + '/';
+
+ do
+ {
+ ++p;
+ }
+ while(p != removeFiles.end() && p->path.size() > dir.size() &&
+ p->path.compare(0, dir.size(), dir) == 0);
+ }
+
+ if(!dryRun)
+ {
+ FileInfoSeq newInfoSeq;
+ newInfoSeq.reserve(infoSeq.size());
+
+ set_difference(infoSeq.begin(),
+ infoSeq.end(),
+ removeFiles.begin(),
+ removeFiles.end(),
+ back_inserter(newInfoSeq),
+ FileInfoLess());
+
+ infoSeq.swap(newInfoSeq);
+
+ saveFileInfoSeq(dataDir, infoSeq);
+ }
+ }
+
+ try
+ {
+ if(!updateFiles.empty())
+ {
+ Long total = 0;
+ Long updated = 0;
+
+ for(p = updateFiles.begin(); p != updateFiles.end(); ++p)
+ {
+ if(p->size > 0) // Regular, non-empty file?
+ {
+ total += p->size;
+ }
+ }
+
+ if(!dryRun)
+ {
+ string pathLog = dataDir + ".log";
+ _fileLog.open(pathLog.c_str());
+ if(!_fileLog)
+ {
+ throw "cannot open `" + pathLog + "' for writing: " + strerror(errno);
+ }
+
+ start();
+ }
+
+ for(p = updateFiles.begin(); p != updateFiles.end(); ++p)
+ {
+ if(p->size < 0) // Directory?
+ {
+ if(!dryRun)
+ {
+ createDirectoryRecursive(p->path);
+
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ _fileLog << *p << endl;
+ }
+ }
+ }
+ else // Regular file.
+ {
+ string pathBZ2 = p->path + ".bz2";
+ ofstream fileBZ2;
+
+ if(!dryRun)
+ {
+ string dir = getDirname(pathBZ2);
+ if(!dir.empty())
+ {
+ createDirectoryRecursive(dir);
+ }
+
+ try
+ {
+ removeRecursive(pathBZ2);
+ }
+ catch(...)
+ {
+ }
+
+ fileBZ2.open(pathBZ2.c_str(), ios::binary);
+ if(!fileBZ2)
+ {
+ throw "cannot open `" + pathBZ2 + "' for writing: " + strerror(errno);
+ }
+
+ _feedback->patchStart(p->path, p->size, updated, total);
+ }
+
+ Int pos = 0;
+ string progress;
+
+ while(pos < p->size)
+ {
+ ByteSeq bytes;
+
+ try
+ {
+ bytes = fileServer->getFileCompressed(p->path, pos, chunkSize);
+ }
+ catch(const FileAccessException& ex)
+ {
+ throw "server error for `" + p->path + "':" + ex.reason;
+ }
+
+ if(bytes.empty())
+ {
+ throw "size mismatch for `" + p->path + "'";
+ }
+
+ if(!dryRun)
+ {
+ fileBZ2.write(reinterpret_cast<char*>(&bytes[0]), bytes.size());
+
+ if(!fileBZ2)
+ {
+ throw ": cannot write `" + pathBZ2 + "': " + strerror(errno);
+ }
+ }
+
+ pos += bytes.size();
+ updated += bytes.size();
+
+ _feedback->patchProgress(pos, p->size, updated, total);
+ }
+
+ if(!dryRun)
+ {
+ fileBZ2.close();
+
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+
+ if(!_exception.empty())
+ {
+ throw _exception;
+ }
+
+ _infoSeq.push_back(*p);
+ notify();
+ }
+ }
+ }
+
+ _feedback->patchEnd();
+ }
+
+ if(!dryRun)
+ {
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+
+ if(!_exception.empty())
+ {
+ throw _exception;
+ }
+
+ _stop = true;
+ notify();
+ }
+
+ getThreadControl().join();
+
+ _fileLog.close();
+
+ FileInfoSeq newInfoSeq;
+ newInfoSeq.reserve(infoSeq.size());
+
+ set_union(infoSeq.begin(),
+ infoSeq.end(),
+ updateFiles.begin(),
+ updateFiles.end(),
+ back_inserter(newInfoSeq),
+ FileInfoLess());
+
+ infoSeq.swap(newInfoSeq);
+
+ saveFileInfoSeq(dataDir, infoSeq);
+ }
+ }
+ }
+ catch(...)
+ {
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ _stop = true;
+ notify();
+ }
+
+ getThreadControl().join();
+
+ throw;
+ }
+}
+
+void
+IcePatch2::Patcher::run()
+{
+ FileInfo info;
+
+ while(true)
+ {
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+
+ if(!info.path.empty())
+ {
+ _fileLog << info << endl;
+ }
+
+ while(!_stop && _infoSeq.empty())
+ {
+ wait();
+ }
+
+ if(!_infoSeq.empty())
+ {
+ info = _infoSeq.front();
+ _infoSeq.pop_front();
+ }
+ else
+ {
+ assert(_stop);
+ return;
+ }
+ }
+
+ try
+ {
+ decompressFile(info.path);
+ remove(info.path + ".bz2");
+ }
+ catch(const string& ex)
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ _stop = true;
+ _exception = ex;
+ return;
+ }
+ }
+}
diff --git a/cpp/src/IcePatch2/Util.cpp b/cpp/src/IcePatch2/Util.cpp
index fb2308c6cec..1614b1e8fbc 100644
--- a/cpp/src/IcePatch2/Util.cpp
+++ b/cpp/src/IcePatch2/Util.cpp
@@ -870,89 +870,3 @@ IcePatch2::operator>>(istream& is, FileInfo& info)
return is;
}
-
-IcePatch2::Decompressor::Decompressor() :
- _destroy(false)
-{
-}
-
-IcePatch2::Decompressor::~Decompressor()
-{
- assert(_destroy);
-}
-
-void
-IcePatch2::Decompressor::destroy()
-{
- IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
-
- _destroy = true;
-
- notify();
-}
-void
-IcePatch2::Decompressor::add(const string& file)
-{
- IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
-
- assert(!_destroy);
-
- if(_files.empty())
- {
- notify();
- }
-
- _files.push_back(file);
-}
-
-void
-IcePatch2::Decompressor::checkForException() const
-{
- IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
-
- if(!_exception.empty())
- {
- assert(_destroy);
- throw _exception;
- }
-}
-
-void
-IcePatch2::Decompressor::run()
-{
- while(true)
- {
- std::string file;
-
- {
- IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
-
- while(!_destroy && _files.empty())
- {
- wait();
- }
-
- if(_destroy && _files.empty())
- {
- return;
- }
-
- assert(!_files.empty());
- file = _files.front();
- _files.pop_front();
- }
-
- try
- {
- decompressFile(file);
- remove(file + ".bz2");
- }
- catch(const string& ex)
- {
- IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
- _destroy = true;
- _exception = ex;
- return;
- }
- }
-}
diff --git a/cpp/src/IcePatch2/icepatch2.dsp b/cpp/src/IcePatch2/icepatch2.dsp
index ed205002d71..05f2d46a6dd 100755
--- a/cpp/src/IcePatch2/icepatch2.dsp
+++ b/cpp/src/IcePatch2/icepatch2.dsp
@@ -106,6 +106,10 @@ PostBuild_Cmds=copy $(OutDir)\icepatch2d.lib ..\..\lib copy $(OutDir)\icepatch22
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
+SOURCE=.\ClientUtil.cpp
+# End Source File
+# Begin Source File
+
SOURCE=.\FileInfo.cpp
# End Source File
# Begin Source File
@@ -122,6 +126,10 @@ SOURCE=.\Util.cpp
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
+SOURCE=..\..\include\IcePatch2\ClientUtil.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\include\IcePatch2\FileInfo.h
# End Source File
# Begin Source File