diff options
author | Marc Laukien <marc@zeroc.com> | 2004-11-28 22:57:21 +0000 |
---|---|---|
committer | Marc Laukien <marc@zeroc.com> | 2004-11-28 22:57:21 +0000 |
commit | 30172b32f4560d346f30e745088dda6428041415 (patch) | |
tree | 511283ad4d992f792928b3649f44bdbb623dae42 /cpp | |
parent | Glacier2 was missing from Slice directories (diff) | |
download | ice-30172b32f4560d346f30e745088dda6428041415.tar.bz2 ice-30172b32f4560d346f30e745088dda6428041415.tar.xz ice-30172b32f4560d346f30e745088dda6428041415.zip |
IcePatch2 for WIN32
Diffstat (limited to 'cpp')
-rwxr-xr-x | cpp/include/IcePatch2/ClientUtil.h | 65 | ||||
-rw-r--r-- | cpp/include/IcePatch2/Util.h | 28 | ||||
-rw-r--r-- | cpp/src/IcePatch2/Client.cpp | 461 | ||||
-rwxr-xr-x | cpp/src/IcePatch2/ClientUtil.cpp | 428 | ||||
-rw-r--r-- | cpp/src/IcePatch2/Util.cpp | 86 | ||||
-rwxr-xr-x | cpp/src/IcePatch2/icepatch2.dsp | 8 |
6 files changed, 592 insertions, 484 deletions
diff --git a/cpp/include/IcePatch2/ClientUtil.h b/cpp/include/IcePatch2/ClientUtil.h new file mode 100755 index 00000000000..c967e558920 --- /dev/null +++ b/cpp/include/IcePatch2/ClientUtil.h @@ -0,0 +1,65 @@ +// **********************************************************************
+//
+// Copyright (c) 2003-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.
+//
+// **********************************************************************
+
+#ifndef ICE_PATCH2_CLIENT_UTIL_H
+#define ICE_PATCH2_CLIENT_UTIL_H
+
+#include <Ice/Ice.h>
+#include <IceUtil/Thread.h>
+#include <IcePatch2/FileServer.h>
+#include <fstream>
+#include <list>
+
+namespace IcePatch2
+{
+
+class ICE_PATCH2_API PatcherFeedback : public IceUtil::Shared
+{
+public:
+
+ virtual bool noFileSummary(const std::string&) = 0;
+
+ virtual bool fileListStart() = 0;
+ virtual bool fileListProgress(Ice::Int) = 0;
+ virtual bool fileListEnd() = 0;
+
+ virtual bool patchStart(const std::string&, Ice::Long, Ice::Long, Ice::Long) = 0;
+ virtual bool patchProgress(Ice::Long, Ice::Long, Ice::Long, Ice::Long) = 0;
+ virtual bool patchEnd() = 0;
+};
+
+typedef IceUtil::Handle<PatcherFeedback> PatcherFeedbackPtr;
+
+class ICE_PATCH2_API Patcher : public IceUtil::Thread, IceUtil::Monitor<IceUtil::Mutex>
+{
+public:
+
+ Patcher(const Ice::CommunicatorPtr&, const PatcherFeedbackPtr&);
+ ~Patcher();
+
+ void patch();
+
+ virtual void run();
+
+private:
+
+ const Ice::CommunicatorPtr _communicator;
+ const PatcherFeedbackPtr _feedback;
+
+ bool _stop;
+ std::string _exception;
+ std::list<FileInfo> _infoSeq;
+ std::ofstream _fileLog;
+};
+
+typedef IceUtil::Handle<Patcher> PatcherPtr;
+
+}
+
+#endif
diff --git a/cpp/include/IcePatch2/Util.h b/cpp/include/IcePatch2/Util.h index da189191e80..ea2cc2468e2 100644 --- a/cpp/include/IcePatch2/Util.h +++ b/cpp/include/IcePatch2/Util.h @@ -7,13 +7,11 @@ // // ********************************************************************** -#ifndef ICE_PATCH2_UPDATE_H -#define ICE_PATCH2_UPDATE_H +#ifndef ICE_PATCH2_UTIL_H +#define ICE_PATCH2_UTIL_H #include <Ice/Ice.h> -#include <IceUtil/Thread.h> #include <IcePatch2/FileInfo.h> -#include <list> namespace IcePatch2 { @@ -100,28 +98,6 @@ struct FileTree0 ICE_PATCH2_API void getFileTree1(const FileInfoSeq&, FileTree1&); ICE_PATCH2_API void getFileTree0(const FileInfoSeq&, FileTree0&); -class ICE_PATCH2_API Decompressor : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex> -{ -public: - - Decompressor(); - virtual ~Decompressor(); - - void destroy(); - void add(const std::string&); - void checkForException() const; - - virtual void run(); - -private: - - bool _destroy; - std::string _exception; - std::list<std::string> _files; -}; - -typedef IceUtil::Handle<Decompressor> DecompressorPtr; - } #endif 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
|