summaryrefslogtreecommitdiff
path: root/cpp/src/IcePatch2Lib
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2015-02-17 17:08:54 +0100
committerJose <jose@zeroc.com>2015-02-17 17:08:54 +0100
commit21c1ba295bc813f35a638b3867234c63dac1816e (patch)
treed4e82f25daf0030375094f734cf4c5ad2d55fdf2 /cpp/src/IcePatch2Lib
parentICE-6306 added checks to javascript for byte/short/int (diff)
downloadice-21c1ba295bc813f35a638b3867234c63dac1816e.tar.bz2
ice-21c1ba295bc813f35a638b3867234c63dac1816e.tar.xz
ice-21c1ba295bc813f35a638b3867234c63dac1816e.zip
Fixed (ICE-5740) - IcePatch2 has issues with 'large' files.
Diffstat (limited to 'cpp/src/IcePatch2Lib')
-rwxr-xr-xcpp/src/IcePatch2Lib/.depend.mak5
-rw-r--r--cpp/src/IcePatch2Lib/ClientUtil.cpp575
-rw-r--r--cpp/src/IcePatch2Lib/Makefile2
-rwxr-xr-xcpp/src/IcePatch2Lib/Makefile.mak2
-rw-r--r--cpp/src/IcePatch2Lib/Util.cpp212
-rw-r--r--cpp/src/IcePatch2Lib/Util.h207
6 files changed, 694 insertions, 309 deletions
diff --git a/cpp/src/IcePatch2Lib/.depend.mak b/cpp/src/IcePatch2Lib/.depend.mak
index 3ac917cdeac..7593b4c14c3 100755
--- a/cpp/src/IcePatch2Lib/.depend.mak
+++ b/cpp/src/IcePatch2Lib/.depend.mak
@@ -129,7 +129,7 @@ ClientUtil.obj: \
"$(includedir)\IcePatch2\FileServer.h" \
"$(includedir)\IcePatch2\FileInfo.h" \
"$(includedir)\IcePatch2\Config.h" \
- "$(includedir)\IcePatch2\Util.h" \
+ "Util.h" \
Util.obj: \
Util.cpp \
@@ -164,7 +164,7 @@ Util.obj: \
"$(includedir)\IceUtil\StringUtil.h" \
"..\..\src\IceUtil\FileUtil.h" \
"$(includedir)\IceUtil\SHA1.h" \
- "$(includedir)\IcePatch2\Util.h" \
+ "Util.h" \
"$(includedir)\Ice\Ice.h" \
"$(includedir)\Ice\Config.h" \
"$(includedir)\Ice\DeprecatedStringConverter.h" \
@@ -260,6 +260,7 @@ Util.obj: \
"$(includedir)\Ice\Service.h" \
"$(includedir)\IcePatch2\FileInfo.h" \
"$(includedir)\IcePatch2\Config.h" \
+ "$(includedir)\IcePatch2\FileServer.h" \
FileInfo.obj: \
FileInfo.cpp \
diff --git a/cpp/src/IcePatch2Lib/ClientUtil.cpp b/cpp/src/IcePatch2Lib/ClientUtil.cpp
index 89eda0a3c30..eaa381722ef 100644
--- a/cpp/src/IcePatch2Lib/ClientUtil.cpp
+++ b/cpp/src/IcePatch2Lib/ClientUtil.cpp
@@ -11,7 +11,7 @@
#include <IceUtil/FileUtil.h>
#define ICE_PATCH2_API_EXPORTS
#include <IcePatch2/ClientUtil.h>
-#include <IcePatch2/Util.h>
+#include <IcePatch2Lib/Util.h>
#include <list>
#include <iterator>
@@ -19,175 +19,194 @@ using namespace std;
using namespace Ice;
using namespace IceUtil;
using namespace IcePatch2;
+using namespace IcePatch2Internal;
-namespace IcePatch2
+namespace
{
class Decompressor : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex>
{
public:
- Decompressor(const string& dataDir) :
- _dataDir(dataDir),
- _destroy(false)
- {
- }
+ Decompressor(const string&);
+ virtual ~Decompressor();
- virtual ~Decompressor()
- {
- assert(_destroy);
- }
+ void destroy();
+ void add(const LargeFileInfo&);
+ void exception() const;
+ void log(FILE* fp);
+ virtual void run();
- void
- destroy()
- {
- IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
- _destroy = true;
- notify();
- }
-
- void
- add(const FileInfo& info)
- {
- IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
- if(!_exception.empty())
- {
- throw _exception;
- }
- _files.push_back(info);
- notify();
- }
+private:
- void
- exception() const
- {
- IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
- if(!_exception.empty())
- {
- throw _exception;
- }
- }
+ const string _dataDir;
- void
- log(FILE* fp)
- {
- IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ string _exception;
+ list<LargeFileInfo> _files;
+ LargeFileInfoSeq _filesDone;
+ bool _destroy;
+};
+typedef IceUtil::Handle<Decompressor> DecompressorPtr;
- for(FileInfoSeq::const_iterator p = _filesDone.begin(); p != _filesDone.end(); ++p)
- {
- if(fputc('+', fp) == EOF || !writeFileInfo(fp, *p))
- {
- throw "error writing log file:\n" + IceUtilInternal::lastErrorToString();
- }
- }
+class PatcherI : public Patcher
+{
+public:
- _filesDone.clear();
- }
+ PatcherI(const Ice::CommunicatorPtr&, const PatcherFeedbackPtr&);
+ PatcherI(const FileServerPrx&, const PatcherFeedbackPtr&, const std::string&, bool, Ice::Int, Ice::Int);
+ virtual ~PatcherI();
- virtual void
- run()
- {
- FileInfo info;
-
- while(true)
- {
- {
- IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
-
- if(!info.path.empty())
- {
- _filesDone.push_back(info);
- }
-
- while(!_destroy && _files.empty())
- {
- wait();
- }
-
- if(!_files.empty())
- {
- info = _files.front();
- _files.pop_front();
- }
- else
- {
- return;
- }
- }
-
- try
- {
- decompressFile(_dataDir + '/' + info.path);
- setFileFlags(_dataDir + '/' + info.path, info);
- remove(_dataDir + '/' + info.path + ".bz2");
- }
- catch(const string& ex)
- {
- IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
- _destroy = true;
- _exception = ex;
- return;
- }
- }
- }
+ virtual bool prepare();
+ virtual bool patch(const std::string&);
+ virtual void finish();
private:
- const string _dataDir;
-
- string _exception;
- list<FileInfo> _files;
- FileInfoSeq _filesDone;
+ void init(const FileServerPrx&);
+ bool removeFiles(const LargeFileInfoSeq&);
+ bool updateFiles(const LargeFileInfoSeq&);
+ bool updateFilesInternal(const LargeFileInfoSeq&, const DecompressorPtr&);
+ bool updateFlags(const LargeFileInfoSeq&);
- bool _destroy;
+ const PatcherFeedbackPtr _feedback;
+ const std::string _dataDir;
+ const bool _thorough;
+ const Ice::Int _chunkSize;
+ const Ice::Int _remove;
+ const FileServerPrx _serverCompress;
+ const FileServerPrx _serverNoCompress;
+
+ LargeFileInfoSeq _localFiles;
+ LargeFileInfoSeq _updateFiles;
+ LargeFileInfoSeq _updateFlags;
+ LargeFileInfoSeq _removeFiles;
+
+ FILE* _log;
+ bool _useSmallFileAPI;
};
+Decompressor::Decompressor(const string& dataDir) :
+ _dataDir(dataDir),
+ _destroy(false)
+{
}
-namespace
+Decompressor::~Decompressor()
{
+ assert(_destroy);
+}
-string
-getDataDir(const CommunicatorPtr& communicator, const string& defaultValue)
+void
+Decompressor::destroy()
{
- return communicator->getProperties()->getPropertyWithDefault("IcePatch2Client.Directory", defaultValue);
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ _destroy = true;
+ notify();
}
-int
-getThorough(const CommunicatorPtr& communicator, int defaultValue)
+void
+Decompressor::add(const LargeFileInfo& info)
{
- return communicator->getProperties()->getPropertyAsIntWithDefault("IcePatch2Client.Thorough", defaultValue);
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ if(!_exception.empty())
+ {
+ throw _exception;
+ }
+ _files.push_back(info);
+ notify();
}
-int
-getChunkSize(const CommunicatorPtr& communicator, int defaultValue)
+void
+Decompressor::exception() const
{
- return communicator->getProperties()->getPropertyAsIntWithDefault("IcePatch2Client.ChunkSize", defaultValue);
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ if(!_exception.empty())
+ {
+ throw _exception;
+ }
}
-int
-getRemove(const CommunicatorPtr& communicator, int defaultValue)
+void
+Decompressor::log(FILE* fp)
{
- return communicator->getProperties()->getPropertyAsIntWithDefault("IcePatch2Client.Remove", defaultValue);
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+
+ for(LargeFileInfoSeq::const_iterator p = _filesDone.begin(); p != _filesDone.end(); ++p)
+ {
+ if(fputc('+', fp) == EOF || !writeFileInfo(fp, *p))
+ {
+ throw "error writing log file:\n" + IceUtilInternal::lastErrorToString();
+ }
+ }
+
+ _filesDone.clear();
}
+void
+Decompressor::run()
+{
+ LargeFileInfo info;
+
+ while(true)
+ {
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+
+ if(!info.path.empty())
+ {
+ _filesDone.push_back(info);
+ }
+
+ while(!_destroy && _files.empty())
+ {
+ wait();
+ }
+
+ if(!_files.empty())
+ {
+ info = _files.front();
+ _files.pop_front();
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ try
+ {
+ decompressFile(_dataDir + '/' + info.path);
+ setFileFlags(_dataDir + '/' + info.path, info);
+ remove(_dataDir + '/' + info.path + ".bz2");
+ }
+ catch(const string& ex)
+ {
+ IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
+ _destroy = true;
+ _exception = ex;
+ return;
+ }
+ }
}
-IcePatch2::Patcher::Patcher(const CommunicatorPtr& communicator, const PatcherFeedbackPtr& feedback) :
+PatcherI::PatcherI(const CommunicatorPtr& communicator, const PatcherFeedbackPtr& feedback) :
_feedback(feedback),
- _dataDir(getDataDir(communicator, ".")),
- _thorough(getThorough(communicator, 0) > 0),
- _chunkSize(getChunkSize(communicator, 100)),
- _remove(getRemove(communicator, 1)),
- _log(0)
+ _dataDir(communicator->getProperties()->getPropertyWithDefault("IcePatch2Client.Directory", ".")),
+ _thorough(communicator->getProperties()->getPropertyAsIntWithDefault("IcePatch2Client.Thorough", 0) > 0),
+ _chunkSize(communicator->getProperties()->getPropertyAsIntWithDefault("IcePatch2Client.ChunkSize", 100)),
+ _remove(communicator->getProperties()->getPropertyAsIntWithDefault("IcePatch2Client.Remove", 1)),
+ _log(0),
+ _useSmallFileAPI(false)
{
- const PropertiesPtr properties = communicator->getProperties();
const char* clientProxyProperty = "IcePatch2Client.Proxy";
- std::string clientProxy = properties->getProperty(clientProxyProperty);
- ObjectPrx serverBase = communicator->stringToProxy(clientProxy);
+ string clientProxy = communicator->getProperties()->getProperty(clientProxyProperty);
+ if(clientProxy.empty())
+ {
+ throw "property `IcePatch2Client.Proxy' is not set";
+ }
- FileServerPrx server = FileServerPrx::checkedCast(serverBase);
+ FileServerPrx server = FileServerPrx::checkedCast(communicator->stringToProxy(clientProxy));
if(!server)
{
throw "proxy `" + clientProxy + "' is not a file server.";
@@ -196,22 +215,23 @@ IcePatch2::Patcher::Patcher(const CommunicatorPtr& communicator, const PatcherFe
init(server);
}
-IcePatch2::Patcher::Patcher(const FileServerPrx& server,
- const PatcherFeedbackPtr& feedback,
- const string& dataDir,
- bool thorough,
- Ice::Int chunkSize,
- Ice::Int remove) :
+PatcherI::PatcherI(const FileServerPrx& server,
+ const PatcherFeedbackPtr& feedback,
+ const string& dataDir,
+ bool thorough,
+ Ice::Int chunkSize,
+ Ice::Int remove) :
_feedback(feedback),
_dataDir(dataDir),
_thorough(thorough),
_chunkSize(chunkSize),
- _remove(remove)
+ _remove(remove),
+ _useSmallFileAPI(false)
{
init(server);
}
-IcePatch2::Patcher::~Patcher()
+PatcherI::~PatcherI()
{
if(_log != 0)
{
@@ -220,9 +240,6 @@ IcePatch2::Patcher::~Patcher()
}
}
-namespace
-{
-
class PatcherGetFileInfoSeqCB : public GetFileInfoSeqCB
{
public:
@@ -255,10 +272,8 @@ private:
const PatcherFeedbackPtr _feedback;
};
-}
-
bool
-IcePatch2::Patcher::prepare()
+PatcherI::prepare()
{
_localFiles.clear();
@@ -316,95 +331,122 @@ IcePatch2::Patcher::prepare()
{
throw string("server returned illegal value");
}
-
- AsyncResultPtr curCB;
- AsyncResultPtr nxtCB;
- for(int node0 = 0; node0 < 256; ++node0)
+ while(true)
{
- if(tree0.nodes[node0].checksum != checksumSeq[node0])
+ AsyncResultPtr curCB;
+ AsyncResultPtr nxtCB;
+ try
{
- if(!curCB)
- {
- assert(!nxtCB);
- curCB = _serverCompress->begin_getFileInfoSeq(node0);
- }
- else
- {
- assert(nxtCB);
- swap(nxtCB, curCB);
- }
-
- int node0Nxt = node0;
-
- do
+ for(int node0 = 0; node0 < 256; ++node0)
{
- ++node0Nxt;
- }
- while(node0Nxt < 256 && tree0.nodes[node0Nxt].checksum == checksumSeq[node0Nxt]);
+ if(tree0.nodes[node0].checksum != checksumSeq[node0])
+ {
+ if(!curCB)
+ {
+ assert(!nxtCB);
+ curCB = _useSmallFileAPI ? _serverCompress->begin_getFileInfoSeq(node0) :
+ _serverCompress->begin_getLargeFileInfoSeq(node0);
+ }
+ else
+ {
+ assert(nxtCB);
+ swap(nxtCB, curCB);
+ }
+
+ int node0Nxt = node0;
+
+ do
+ {
+ ++node0Nxt;
+ }
+ while(node0Nxt < 256 && tree0.nodes[node0Nxt].checksum == checksumSeq[node0Nxt]);
- if(node0Nxt < 256)
- {
- nxtCB = _serverCompress->begin_getFileInfoSeq(node0Nxt);
- }
+ if(node0Nxt < 256)
+ {
+ nxtCB = _useSmallFileAPI ? _serverCompress->begin_getFileInfoSeq(node0Nxt) :
+ _serverCompress->begin_getLargeFileInfoSeq(node0Nxt);
+ }
- FileInfoSeq files = _serverCompress->end_getFileInfoSeq(curCB);
-
- sort(files.begin(), files.end(), FileInfoLess());
- files.erase(unique(files.begin(), files.end(), FileInfoEqual()), files.end());
-
- //
- // Compute the set of files which were removed.
- //
- set_difference(tree0.nodes[node0].files.begin(),
- tree0.nodes[node0].files.end(),
- files.begin(),
- files.end(),
- back_inserter(_removeFiles),
- FileInfoWithoutFlagsLess()); // NOTE: We ignore the flags here.
-
- //
- // Compute the set of files which were updated (either the file contents, flags or both).
- //
- FileInfoSeq updatedFiles;
- updatedFiles.reserve(files.size());
-
- set_difference(files.begin(),
- files.end(),
- tree0.nodes[node0].files.begin(),
- tree0.nodes[node0].files.end(),
- back_inserter(updatedFiles),
- FileInfoLess());
-
- //
- // Compute the set of files whose contents was updated.
- //
- FileInfoSeq contentsUpdatedFiles;
- contentsUpdatedFiles.reserve(files.size());
-
- set_difference(files.begin(),
- files.end(),
- tree0.nodes[node0].files.begin(),
- tree0.nodes[node0].files.end(),
- back_inserter(contentsUpdatedFiles),
- FileInfoWithoutFlagsLess()); // NOTE: We ignore the flags here.
- copy(contentsUpdatedFiles.begin(), contentsUpdatedFiles.end(), back_inserter(_updateFiles));
-
- //
- // Compute the set of files whose flags were updated.
- //
- set_difference(updatedFiles.begin(),
- updatedFiles.end(),
- contentsUpdatedFiles.begin(),
- contentsUpdatedFiles.end(),
- back_inserter(_updateFlags),
- FileInfoLess());
- }
+ LargeFileInfoSeq files;
+ if(_useSmallFileAPI)
+ {
+ FileInfoSeq smallFiles = _serverCompress->end_getFileInfoSeq(curCB);
+ files.resize(smallFiles.size());
+ transform(smallFiles.begin(), smallFiles.end(), files.begin(), toLargeFileInfo);
+ }
+ else
+ {
+ files = _serverCompress->end_getLargeFileInfoSeq(curCB);
+ }
+
+ sort(files.begin(), files.end(), FileInfoLess());
+ files.erase(unique(files.begin(), files.end(), FileInfoEqual()), files.end());
+
+ //
+ // Compute the set of files which were removed.
+ //
+ set_difference(tree0.nodes[node0].files.begin(),
+ tree0.nodes[node0].files.end(),
+ files.begin(),
+ files.end(),
+ back_inserter(_removeFiles),
+ FileInfoWithoutFlagsLess()); // NOTE: We ignore the flags here.
+
+ //
+ // Compute the set of files which were updated (either the file contents, flags or both).
+ //
+ LargeFileInfoSeq updatedFiles;
+ updatedFiles.reserve(files.size());
+
+ set_difference(files.begin(),
+ files.end(),
+ tree0.nodes[node0].files.begin(),
+ tree0.nodes[node0].files.end(),
+ back_inserter(updatedFiles),
+ FileInfoLess());
+
+ //
+ // Compute the set of files whose contents was updated.
+ //
+ LargeFileInfoSeq contentsUpdatedFiles;
+ contentsUpdatedFiles.reserve(files.size());
+
+ set_difference(files.begin(),
+ files.end(),
+ tree0.nodes[node0].files.begin(),
+ tree0.nodes[node0].files.end(),
+ back_inserter(contentsUpdatedFiles),
+ FileInfoWithoutFlagsLess()); // NOTE: We ignore the flags here.
+ copy(contentsUpdatedFiles.begin(), contentsUpdatedFiles.end(), back_inserter(_updateFiles));
+
+ //
+ // Compute the set of files whose flags were updated.
+ //
+ set_difference(updatedFiles.begin(),
+ updatedFiles.end(),
+ contentsUpdatedFiles.begin(),
+ contentsUpdatedFiles.end(),
+ back_inserter(_updateFlags),
+ FileInfoLess());
+ }
- if(!_feedback->fileListProgress((node0 + 1) * 100 / 256))
+ if(!_feedback->fileListProgress((node0 + 1) * 100 / 256))
+ {
+ return false;
+ }
+ }
+ }
+ catch(const Ice::OperationNotExistException&)
{
- return false;
+ if(!_useSmallFileAPI)
+ {
+ _useSmallFileAPI = true;
+ continue;
+ }
+ throw;
}
+ break;
}
if(!_feedback->fileListEnd())
@@ -428,7 +470,7 @@ IcePatch2::Patcher::prepare()
}
bool
-IcePatch2::Patcher::patch(const string& d)
+PatcherI::patch(const string& d)
{
string dir = simplify(d);
@@ -464,8 +506,8 @@ IcePatch2::Patcher::patch(const string& d)
{
string dirWithSlash = simplify(dir + '/');
- FileInfoSeq remove;
- for(FileInfoSeq::const_iterator p = _removeFiles.begin(); p != _removeFiles.end(); ++p)
+ LargeFileInfoSeq remove;
+ for(LargeFileInfoSeq::const_iterator p = _removeFiles.begin(); p != _removeFiles.end(); ++p)
{
if(p->path == dir)
{
@@ -477,8 +519,8 @@ IcePatch2::Patcher::patch(const string& d)
}
}
- FileInfoSeq update;
- for(FileInfoSeq::const_iterator p = _updateFiles.begin(); p != _updateFiles.end(); ++p)
+ LargeFileInfoSeq update;
+ for(LargeFileInfoSeq::const_iterator p = _updateFiles.begin(); p != _updateFiles.end(); ++p)
{
if(p->path == dir)
{
@@ -490,8 +532,8 @@ IcePatch2::Patcher::patch(const string& d)
}
}
- FileInfoSeq updateFlag;
- for(FileInfoSeq::const_iterator p = _updateFlags.begin(); p != _updateFlags.end(); ++p)
+ LargeFileInfoSeq updateFlag;
+ for(LargeFileInfoSeq::const_iterator p = _updateFlags.begin(); p != _updateFlags.end(); ++p)
{
if(p->path == dir)
{
@@ -532,7 +574,7 @@ IcePatch2::Patcher::patch(const string& d)
}
void
-IcePatch2::Patcher::finish()
+PatcherI::finish()
{
if(_log != 0)
{
@@ -544,7 +586,7 @@ IcePatch2::Patcher::finish()
}
void
-IcePatch2::Patcher::init(const FileServerPrx& server)
+PatcherI::init(const FileServerPrx& server)
{
if(_dataDir.empty())
{
@@ -592,14 +634,14 @@ IcePatch2::Patcher::init(const FileServerPrx& server)
}
bool
-IcePatch2::Patcher::removeFiles(const FileInfoSeq& files)
+PatcherI::removeFiles(const LargeFileInfoSeq& files)
{
if(_remove < 1)
{
return true;
}
- for(FileInfoSeq::const_reverse_iterator p = files.rbegin(); p != files.rend(); ++p)
+ for(LargeFileInfoSeq::const_reverse_iterator p = files.rbegin(); p != files.rend(); ++p)
{
try
{
@@ -618,7 +660,7 @@ IcePatch2::Patcher::removeFiles(const FileInfoSeq& files)
}
}
- FileInfoSeq newLocalFiles;
+ LargeFileInfoSeq newLocalFiles;
newLocalFiles.reserve(_localFiles.size());
set_difference(_localFiles.begin(),
@@ -630,7 +672,7 @@ IcePatch2::Patcher::removeFiles(const FileInfoSeq& files)
_localFiles.swap(newLocalFiles);
- FileInfoSeq newRemoveFiles;
+ LargeFileInfoSeq newRemoveFiles;
set_difference(_removeFiles.begin(),
_removeFiles.end(),
@@ -643,9 +685,9 @@ IcePatch2::Patcher::removeFiles(const FileInfoSeq& files)
return true;
}
-
+
bool
-IcePatch2::Patcher::updateFiles(const FileInfoSeq& files)
+PatcherI::updateFiles(const LargeFileInfoSeq& files)
{
DecompressorPtr decompressor = new Decompressor(_dataDir);
#if defined(__hppa)
@@ -680,12 +722,12 @@ IcePatch2::Patcher::updateFiles(const FileInfoSeq& files)
}
bool
-IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files, const DecompressorPtr& decompressor)
+PatcherI::updateFilesInternal(const LargeFileInfoSeq& files, const DecompressorPtr& decompressor)
{
Long total = 0;
Long updated = 0;
- for(FileInfoSeq::const_iterator p = files.begin(); p != files.end(); ++p)
+ for(LargeFileInfoSeq::const_iterator p = files.begin(); p != files.end(); ++p)
{
if(p->size > 0) // Regular, non-empty file?
{
@@ -696,7 +738,7 @@ IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files, const Decompre
AsyncResultPtr curCB;
AsyncResultPtr nxtCB;
- for(FileInfoSeq::const_iterator p = files.begin(); p != files.end(); ++p)
+ for(LargeFileInfoSeq::const_iterator p = files.begin(); p != files.end(); ++p)
{
if(p->size < 0) // Directory?
{
@@ -749,14 +791,16 @@ IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files, const Decompre
try
{
- Int pos = 0;
+ Ice::Long pos = 0;
while(pos < p->size)
{
if(!curCB)
{
assert(!nxtCB);
- curCB = _serverNoCompress->begin_getFileCompressed(p->path, pos, _chunkSize);
+ curCB = _useSmallFileAPI ?
+ _serverNoCompress->begin_getFileCompressed(p->path, static_cast<Ice::Int>(pos), _chunkSize) :
+ _serverNoCompress->begin_getLargeFileCompressed(p->path, pos, _chunkSize);
}
else
{
@@ -766,11 +810,13 @@ IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files, const Decompre
if(pos + _chunkSize < p->size)
{
- nxtCB = _serverNoCompress->begin_getFileCompressed(p->path, pos + _chunkSize, _chunkSize);
+ nxtCB = _useSmallFileAPI ?
+ _serverNoCompress->begin_getFileCompressed(p->path, static_cast<Ice::Int>(pos + _chunkSize), _chunkSize) :
+ _serverNoCompress->begin_getLargeFileCompressed(p->path, pos + _chunkSize, _chunkSize);
}
else
{
- FileInfoSeq::const_iterator q = p + 1;
+ LargeFileInfoSeq::const_iterator q = p + 1;
while(q != files.end() && q->size <= 0)
{
@@ -779,7 +825,9 @@ IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files, const Decompre
if(q != files.end())
{
- nxtCB = _serverNoCompress->begin_getFileCompressed(q->path, 0, _chunkSize);
+ nxtCB = _useSmallFileAPI ?
+ _serverNoCompress->begin_getFileCompressed(q->path, 0, _chunkSize) :
+ _serverNoCompress->begin_getLargeFileCompressed(q->path, 0, _chunkSize);
}
}
@@ -787,7 +835,8 @@ IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files, const Decompre
try
{
- bytes = _serverNoCompress->end_getFileCompressed(curCB);
+ bytes = _useSmallFileAPI ? _serverNoCompress->end_getFileCompressed(curCB) :
+ _serverNoCompress->end_getLargeFileCompressed(curCB);
}
catch(const FileAccessException& ex)
{
@@ -804,7 +853,7 @@ IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files, const Decompre
throw ": cannot write `" + pathBZ2 + "':\n" + IceUtilInternal::lastErrorToString();
}
- pos += static_cast<int>(bytes.size());
+ pos += bytes.size();
updated += bytes.size();
if(!_feedback->patchProgress(pos, p->size, updated, total))
@@ -833,7 +882,7 @@ IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files, const Decompre
}
}
- FileInfoSeq newLocalFiles;
+ LargeFileInfoSeq newLocalFiles;
newLocalFiles.reserve(_localFiles.size());
set_union(_localFiles.begin(),
@@ -845,7 +894,7 @@ IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files, const Decompre
_localFiles.swap(newLocalFiles);
- FileInfoSeq newUpdateFiles;
+ LargeFileInfoSeq newUpdateFiles;
set_difference(_updateFiles.begin(),
_updateFiles.end(),
@@ -860,9 +909,9 @@ IcePatch2::Patcher::updateFilesInternal(const FileInfoSeq& files, const Decompre
}
bool
-IcePatch2::Patcher::updateFlags(const FileInfoSeq& files)
+PatcherI::updateFlags(const LargeFileInfoSeq& files)
{
- for(FileInfoSeq::const_iterator p = files.begin(); p != files.end(); ++p)
+ for(LargeFileInfoSeq::const_iterator p = files.begin(); p != files.end(); ++p)
{
if(p->size >= 0) // Regular file?
{
@@ -874,7 +923,7 @@ IcePatch2::Patcher::updateFlags(const FileInfoSeq& files)
// Remove the old files whose flags were updated from the set of
// local files.
//
- FileInfoSeq localFiles;
+ LargeFileInfoSeq localFiles;
localFiles.reserve(_localFiles.size());
set_difference(_localFiles.begin(),
_localFiles.end(),
@@ -894,7 +943,7 @@ IcePatch2::Patcher::updateFlags(const FileInfoSeq& files)
back_inserter(_localFiles),
FileInfoLess());
- FileInfoSeq newUpdateFlags;
+ LargeFileInfoSeq newUpdateFlags;
set_difference(_updateFlags.begin(),
_updateFlags.end(),
@@ -908,3 +957,25 @@ IcePatch2::Patcher::updateFlags(const FileInfoSeq& files)
return true;
}
+}
+
+PatcherPtr
+PatcherFactory::create(const Ice::CommunicatorPtr& communicator, const PatcherFeedbackPtr& feedback)
+{
+ return new PatcherI(communicator, feedback);
+}
+
+//
+// Create a patcher with the given parameters. These parameters
+// are equivalent to the configuration properties described above.
+//
+PatcherPtr
+PatcherFactory::create(const FileServerPrx& server,
+ const PatcherFeedbackPtr& feedback,
+ const string& dataDir,
+ bool thorough,
+ Ice::Int chunkSize,
+ Ice::Int remove)
+{
+ return new PatcherI(server, feedback, dataDir, thorough, chunkSize, remove);
+}
diff --git a/cpp/src/IcePatch2Lib/Makefile b/cpp/src/IcePatch2Lib/Makefile
index 871a9ed02e9..80a59f38bfb 100644
--- a/cpp/src/IcePatch2Lib/Makefile
+++ b/cpp/src/IcePatch2Lib/Makefile
@@ -27,7 +27,7 @@ SDIR = $(slicedir)/IcePatch2
include $(top_srcdir)/config/Make.rules
-CPPFLAGS := -I. -I.. $(CPPFLAGS) $(OPENSSL_FLAGS) $(BZIP2_FLAGS)
+CPPFLAGS := -I. -I.. $(CPPFLAGS) $(OPENSSL_FLAGS) $(BZIP2_FLAGS) -Wno-deprecated-declarations
SLICE2CPPFLAGS := --ice --include-dir IcePatch2 --dll-export ICE_PATCH2_API $(SLICE2CPPFLAGS)
LINKWITH := $(BZIP2_RPATH_LINK) -lIce -lIceUtil $(OPENSSL_LIBS) $(BZIP2_LIBS)
diff --git a/cpp/src/IcePatch2Lib/Makefile.mak b/cpp/src/IcePatch2Lib/Makefile.mak
index a2c29ccbf84..ec9456261d9 100755
--- a/cpp/src/IcePatch2Lib/Makefile.mak
+++ b/cpp/src/IcePatch2Lib/Makefile.mak
@@ -26,7 +26,7 @@ SDIR = $(slicedir)\IcePatch2
!include $(top_srcdir)\config\Make.rules.mak
-CPPFLAGS = -I. -I.. $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN
+CPPFLAGS = -I. -I.. $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN -wd4996
SLICE2CPPFLAGS = --ice --include-dir IcePatch2 --dll-export ICE_PATCH2_API $(SLICE2CPPFLAGS)
diff --git a/cpp/src/IcePatch2Lib/Util.cpp b/cpp/src/IcePatch2Lib/Util.cpp
index ab27759d87a..948a3646d5c 100644
--- a/cpp/src/IcePatch2Lib/Util.cpp
+++ b/cpp/src/IcePatch2Lib/Util.cpp
@@ -20,9 +20,11 @@
#include <IceUtil/StringUtil.h>
#include <IceUtil/FileUtil.h>
#include <IceUtil/SHA1.h>
+#include <IceUtil/Exception.h>
#define ICE_PATCH2_API_EXPORTS
-#include <IcePatch2/Util.h>
+#include <IcePatch2Lib/Util.h>
+#include <IcePatch2/FileServer.h>
#include <bzlib.h>
#include <iomanip>
@@ -40,17 +42,54 @@
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
-const char* IcePatch2::checksumFile = "IcePatch2.sum";
-const char* IcePatch2::logFile = "IcePatch2.log";
+const char* IcePatch2Internal::checksumFile = "IcePatch2.sum";
+const char* IcePatch2Internal::logFile = "IcePatch2.log";
using namespace std;
using namespace Ice;
using namespace IcePatch2;
+using namespace IcePatch2Internal;
+
+FileInfo
+IcePatch2Internal::toFileInfo(const LargeFileInfo& largeInfo)
+{
+ if(largeInfo.size > 0x7FFFFFFF)
+ {
+ ostringstream os;
+ os << "cannot encode size `" << largeInfo.size << "' for file `" << largeInfo.path << "' as Ice::Int" << endl;
+ throw FileSizeRangeException(os.str());
+ }
+
+ FileInfo info;
+ info.path = largeInfo.path;
+ info.checksum = largeInfo.checksum;
+ info.size = static_cast<Ice::Int>(largeInfo.size),
+ info.executable = largeInfo.executable;
+
+ return info;
+}
+
+LargeFileInfo
+IcePatch2Internal::toLargeFileInfo(const FileInfo& info)
+{
+ LargeFileInfo largeInfo;
+ largeInfo.path = info.path;
+ largeInfo.checksum = info.checksum;
+ largeInfo.size = info.size;
+ largeInfo.executable = info.executable;
+ return largeInfo;
+}
+
+bool
+IcePatch2Internal::writeFileInfo(FILE* fp, const FileInfo& info)
+{
+ return writeFileInfo(fp, toLargeFileInfo(info));
+}
bool
-IcePatch2::writeFileInfo(FILE* fp, const FileInfo& info)
+IcePatch2Internal::writeFileInfo(FILE* fp, const LargeFileInfo& info)
{
- int rc = fprintf(fp, "%s\t%s\t%d\t%d\n",
+ int rc = fprintf(fp, "%s\t%s\t%ld\t%d\n",
IceUtilInternal::escapeString(info.path, "").c_str(),
bytesToString(info.checksum).c_str(),
info.size,
@@ -59,7 +98,19 @@ IcePatch2::writeFileInfo(FILE* fp, const FileInfo& info)
}
bool
-IcePatch2::readFileInfo(FILE* fp, FileInfo& info)
+IcePatch2Internal::readFileInfo(FILE* fp, FileInfo& info)
+{
+ LargeFileInfo largeInfo;
+ bool retval = readFileInfo(fp, largeInfo);
+ if(retval)
+ {
+ info = toFileInfo(largeInfo);
+ }
+ return retval;
+}
+
+bool
+IcePatch2Internal::readFileInfo(FILE* fp, LargeFileInfo& info)
{
string data;
char buf[BUFSIZ];
@@ -101,7 +152,7 @@ IcePatch2::readFileInfo(FILE* fp, FileInfo& info)
}
string
-IcePatch2::bytesToString(const ByteSeq& bytes)
+IcePatch2Internal::bytesToString(const ByteSeq& bytes)
{
/*
ostringstream s;
@@ -129,7 +180,7 @@ IcePatch2::bytesToString(const ByteSeq& bytes)
}
ByteSeq
-IcePatch2::stringToBytes(const string& str)
+IcePatch2Internal::stringToBytes(const string& str)
{
ByteSeq bytes;
bytes.reserve((str.size() + 1) / 2);
@@ -174,7 +225,7 @@ IcePatch2::stringToBytes(const string& str)
}
string
-IcePatch2::simplify(const string& path)
+IcePatch2Internal::simplify(const string& path)
{
string result = path;
@@ -250,7 +301,7 @@ IcePatch2::simplify(const string& path)
}
bool
-IcePatch2::isRoot(const string& pa)
+IcePatch2Internal::isRoot(const string& pa)
{
string path = simplify(pa);
#ifdef _WIN32
@@ -262,7 +313,7 @@ IcePatch2::isRoot(const string& pa)
}
string
-IcePatch2::getSuffix(const string& pa)
+IcePatch2Internal::getSuffix(const string& pa)
{
const string path = simplify(pa);
@@ -278,7 +329,7 @@ IcePatch2::getSuffix(const string& pa)
}
string
-IcePatch2::getWithoutSuffix(const string& pa)
+IcePatch2Internal::getWithoutSuffix(const string& pa)
{
const string path = simplify(pa);
@@ -294,7 +345,7 @@ IcePatch2::getWithoutSuffix(const string& pa)
}
bool
-IcePatch2::ignoreSuffix(const string& path)
+IcePatch2Internal::ignoreSuffix(const string& path)
{
string suffix = getSuffix(path);
return suffix == "md5" // For legacy IcePatch.
@@ -304,7 +355,7 @@ IcePatch2::ignoreSuffix(const string& path)
}
string
-IcePatch2::getBasename(const string& pa)
+IcePatch2Internal::getBasename(const string& pa)
{
const string path = simplify(pa);
@@ -320,7 +371,7 @@ IcePatch2::getBasename(const string& pa)
}
string
-IcePatch2::getDirname(const string& pa)
+IcePatch2Internal::getDirname(const string& pa)
{
const string path = simplify(pa);
@@ -336,7 +387,7 @@ IcePatch2::getDirname(const string& pa)
}
void
-IcePatch2::rename(const string& fromPa, const string& toPa)
+IcePatch2Internal::rename(const string& fromPa, const string& toPa)
{
const string fromPath = simplify(fromPa);
@@ -350,7 +401,7 @@ IcePatch2::rename(const string& fromPa, const string& toPa)
}
void
-IcePatch2::remove(const string& pa)
+IcePatch2Internal::remove(const string& pa)
{
const string path = simplify(pa);
@@ -381,7 +432,7 @@ IcePatch2::remove(const string& pa)
}
void
-IcePatch2::removeRecursive(const string& pa)
+IcePatch2Internal::removeRecursive(const string& pa)
{
const string path = simplify(pa);
@@ -417,7 +468,7 @@ IcePatch2::removeRecursive(const string& pa)
}
StringSeq
-IcePatch2::readDirectory(const string& pa)
+IcePatch2Internal::readDirectory(const string& pa)
{
const string path = simplify(pa);
@@ -498,7 +549,7 @@ IcePatch2::readDirectory(const string& pa)
}
void
-IcePatch2::createDirectory(const string& pa)
+IcePatch2Internal::createDirectory(const string& pa)
{
const string path = simplify(pa);
@@ -512,7 +563,7 @@ IcePatch2::createDirectory(const string& pa)
}
void
-IcePatch2::createDirectoryRecursive(const string& pa)
+IcePatch2Internal::createDirectoryRecursive(const string& pa)
{
const string path = simplify(pa);
@@ -544,7 +595,7 @@ IcePatch2::createDirectoryRecursive(const string& pa)
}
void
-IcePatch2::compressBytesToFile(const string& pa, const ByteSeq& bytes, Int pos)
+IcePatch2Internal::compressBytesToFile(const string& pa, const ByteSeq& bytes, Int pos)
{
const string path = simplify(pa);
@@ -596,11 +647,11 @@ IcePatch2::compressBytesToFile(const string& pa, const ByteSeq& bytes, Int pos)
}
void
-IcePatch2::decompressFile(const string& pa)
+IcePatch2Internal::decompressFile(const string& pa)
{
const string path = simplify(pa);
const string pathBZ2 = path + ".bz2";
-
+
FILE* fp = 0;
FILE* stdioFileBZ2 = 0;
int bzError;
@@ -695,9 +746,15 @@ IcePatch2::decompressFile(const string& pa)
fclose(fp);
}
+void
+IcePatch2Internal::setFileFlags(const string& pa, const FileInfo& info)
+{
+ setFileFlags(pa, toLargeFileInfo(info));
+}
+
#ifndef _WIN32
void
-IcePatch2::setFileFlags(const string& pa, const FileInfo& info)
+IcePatch2Internal::setFileFlags(const string& pa, const LargeFileInfo& info)
{
const string path = simplify(pa);
IceUtilInternal::structstat buf;
@@ -709,14 +766,17 @@ IcePatch2::setFileFlags(const string& pa, const FileInfo& info)
}
#else // Windows doesn't support the executable flag
void
-IcePatch2::setFileFlags(const string&, const FileInfo&)
+IcePatch2Internal::setFileFlags(const string&, const LargeFileInfo&)
{
}
#endif
+namespace
+{
+
static bool
-getFileInfoSeqInt(const string& basePath, const string& relPath, int compress, GetFileInfoSeqCB* cb,
- FileInfoSeq& infoSeq)
+getFileInfoSeqInternal(const string& basePath, const string& relPath, int compress, GetFileInfoSeqCB* cb,
+ LargeFileInfoSeq& infoSeq)
{
if(relPath == checksumFile || relPath == logFile)
{
@@ -779,7 +839,7 @@ getFileInfoSeqInt(const string& basePath, const string& relPath, int compress, G
if(S_ISDIR(buf.st_mode))
{
- FileInfo info;
+ LargeFileInfo info;
info.path = relPath;
info.size = -1;
info.executable = false;
@@ -803,7 +863,7 @@ getFileInfoSeqInt(const string& basePath, const string& relPath, int compress, G
StringSeq content = readDirectory(path);
for(StringSeq::const_iterator p = content.begin(); p != content.end() ; ++p)
{
- if(!getFileInfoSeqInt(basePath, simplify(relPath + '/' + *p), compress, cb, infoSeq))
+ if(!getFileInfoSeqInternal(basePath, simplify(relPath + '/' + *p), compress, cb, infoSeq))
{
return false;
}
@@ -811,7 +871,7 @@ getFileInfoSeqInt(const string& basePath, const string& relPath, int compress, G
}
else if(S_ISREG(buf.st_mode))
{
- FileInfo info;
+ LargeFileInfo info;
info.path = relPath;
info.size = 0;
#ifdef _WIN32
@@ -841,7 +901,7 @@ getFileInfoSeqInt(const string& basePath, const string& relPath, int compress, G
}
else
{
- info.size = static_cast<Int>(bufBZ2.st_size);
+ info.size = bufBZ2.st_size;
}
}
@@ -900,10 +960,10 @@ getFileInfoSeqInt(const string& basePath, const string& relPath, int compress, G
}
}
- unsigned int bytesLeft = static_cast<unsigned int>(buf.st_size);
+ long bytesLeft = buf.st_size;
while(bytesLeft > 0)
{
- ByteSeq bytes(min(bytesLeft, 1024u*1024));
+ ByteSeq bytes(min(bytesLeft, 1024l*1024));
if(
#if defined(_MSC_VER)
_read(fd, &bytes[0], static_cast<unsigned int>(bytes.size()))
@@ -921,7 +981,6 @@ getFileInfoSeqInt(const string& basePath, const string& relPath, int compress, G
throw "cannot read from `" + path + "':\n" + IceUtilInternal::lastErrorToString();
}
bytesLeft -= static_cast<unsigned int>(bytes.size());
-
if(doCompress)
{
BZ2_bzWrite(&bzError, bzFile, const_cast<Byte*>(&bytes[0]), static_cast<int>(bytes.size()));
@@ -967,7 +1026,7 @@ getFileInfoSeqInt(const string& basePath, const string& relPath, int compress, G
throw "cannot stat `" + pathBZ2 + "':\n" + IceUtilInternal::lastErrorToString();
}
- info.size = static_cast<Int>(bufBZ2.st_size);
+ info.size = bufBZ2.st_size;
}
}
hasher.finalize(bytesSHA);
@@ -982,21 +1041,44 @@ getFileInfoSeqInt(const string& basePath, const string& relPath, int compress, G
return true;
}
+}
+
+bool
+IcePatch2Internal::getFileInfoSeq(const string& basePath, int compress, GetFileInfoSeqCB* cb, FileInfoSeq& infoSeq)
+{
+ LargeFileInfoSeq largeInfoSeq;
+ bool retval = getFileInfoSeq(basePath, compress, cb, largeInfoSeq);
+ infoSeq.resize(largeInfoSeq.size());
+ transform(largeInfoSeq.begin(), largeInfoSeq.end(), infoSeq.begin(), toFileInfo);
+ return retval;
+}
+
bool
-IcePatch2::getFileInfoSeq(const string& basePath, int compress, GetFileInfoSeqCB* cb,
- FileInfoSeq& infoSeq)
+IcePatch2Internal::getFileInfoSeq(const string& basePath, int compress, GetFileInfoSeqCB* cb,
+ LargeFileInfoSeq& infoSeq)
{
return getFileInfoSeqSubDir(basePath, ".", compress, cb, infoSeq);
}
bool
-IcePatch2::getFileInfoSeqSubDir(const string& basePa, const string& relPa, int compress, GetFileInfoSeqCB* cb,
- FileInfoSeq& infoSeq)
+IcePatch2Internal::getFileInfoSeqSubDir(const string& basePa, const string& relPa, int compress, GetFileInfoSeqCB* cb,
+ FileInfoSeq& infoSeq)
+{
+ LargeFileInfoSeq largeInfoSeq;
+ bool retval = getFileInfoSeqSubDir(basePa, relPa, compress, cb, largeInfoSeq);
+ infoSeq.resize(largeInfoSeq.size());
+ transform(largeInfoSeq.begin(), largeInfoSeq.end(), infoSeq.begin(), toFileInfo);
+ return retval;
+}
+
+bool
+IcePatch2Internal::getFileInfoSeqSubDir(const string& basePa, const string& relPa, int compress, GetFileInfoSeqCB* cb,
+ LargeFileInfoSeq& infoSeq)
{
const string basePath = simplify(basePa);
const string relPath = simplify(relPa);
- if(!getFileInfoSeqInt(basePath, relPath, compress, cb, infoSeq))
+ if(!getFileInfoSeqInternal(basePath, relPath, compress, cb, infoSeq))
{
return false;
}
@@ -1008,11 +1090,18 @@ IcePatch2::getFileInfoSeqSubDir(const string& basePa, const string& relPa, int c
}
void
-IcePatch2::saveFileInfoSeq(const string& pa, const FileInfoSeq& infoSeq)
+IcePatch2Internal::saveFileInfoSeq(const string& pa, const FileInfoSeq& infoSeq)
+{
+ LargeFileInfoSeq largeInfoSeq(infoSeq.size());
+ transform(infoSeq.begin(), infoSeq.end(), largeInfoSeq.begin(), toLargeFileInfo);
+ saveFileInfoSeq(pa, largeInfoSeq);
+}
+
+void
+IcePatch2Internal::saveFileInfoSeq(const string& pa, const LargeFileInfoSeq& infoSeq)
{
{
const string path = simplify(pa + '/' + checksumFile);
-
FILE* fp = IceUtilInternal::fopen(path, "w");
if(!fp)
{
@@ -1020,7 +1109,7 @@ IcePatch2::saveFileInfoSeq(const string& pa, const FileInfoSeq& infoSeq)
}
try
{
- for(FileInfoSeq::const_iterator p = infoSeq.begin(); p != infoSeq.end(); ++p)
+ for(LargeFileInfoSeq::const_iterator p = infoSeq.begin(); p != infoSeq.end(); ++p)
{
if(!writeFileInfo(fp, *p))
{
@@ -1050,7 +1139,16 @@ IcePatch2::saveFileInfoSeq(const string& pa, const FileInfoSeq& infoSeq)
}
void
-IcePatch2::loadFileInfoSeq(const string& pa, FileInfoSeq& infoSeq)
+IcePatch2Internal::loadFileInfoSeq(const string& pa, FileInfoSeq& infoSeq)
+{
+ LargeFileInfoSeq largeInfoSeq;
+ loadFileInfoSeq(pa, largeInfoSeq);
+ infoSeq.resize(largeInfoSeq.size());
+ transform(largeInfoSeq.begin(), largeInfoSeq.end(), infoSeq.begin(), toFileInfo);
+}
+
+void
+IcePatch2Internal::loadFileInfoSeq(const string& pa, LargeFileInfoSeq& infoSeq)
{
{
const string path = simplify(pa + '/' + checksumFile);
@@ -1063,7 +1161,7 @@ IcePatch2::loadFileInfoSeq(const string& pa, FileInfoSeq& infoSeq)
while(true)
{
- FileInfo info;
+ LargeFileInfo info;
if(readFileInfo(fp, info))
{
infoSeq.push_back(info);
@@ -1085,8 +1183,8 @@ IcePatch2::loadFileInfoSeq(const string& pa, FileInfoSeq& infoSeq)
FILE* fp = IceUtilInternal::fopen(pathLog, "r");
if(fp != 0)
{
- FileInfoSeq remove;
- FileInfoSeq update;
+ LargeFileInfoSeq remove;
+ LargeFileInfoSeq update;
while(true)
{
@@ -1096,7 +1194,7 @@ IcePatch2::loadFileInfoSeq(const string& pa, FileInfoSeq& infoSeq)
break;
}
- FileInfo info;
+ LargeFileInfo info;
if(!readFileInfo(fp, info))
{
break;
@@ -1119,7 +1217,7 @@ IcePatch2::loadFileInfoSeq(const string& pa, FileInfoSeq& infoSeq)
sort(update.begin(), update.end(), FileInfoLess());
update.erase(unique(update.begin(), update.end(), FileInfoEqual()), update.end());
- FileInfoSeq newInfoSeq;
+ LargeFileInfoSeq newInfoSeq;
newInfoSeq.reserve(infoSeq.size());
set_difference(infoSeq.begin(),
@@ -1149,7 +1247,15 @@ IcePatch2::loadFileInfoSeq(const string& pa, FileInfoSeq& infoSeq)
}
void
-IcePatch2::getFileTree0(const FileInfoSeq& infoSeq, FileTree0& tree0)
+IcePatch2Internal::getFileTree0(const FileInfoSeq& infoSeq, FileTree0& tree0)
+{
+ LargeFileInfoSeq largeInfoSeq(infoSeq.size());
+ transform(infoSeq.begin(), infoSeq.end(), largeInfoSeq.begin(), toLargeFileInfo);
+ getFileTree0(largeInfoSeq, tree0);
+}
+
+void
+IcePatch2Internal::getFileTree0(const LargeFileInfoSeq& infoSeq, FileTree0& tree0)
{
tree0.nodes.resize(256);
tree0.checksum.resize(20);
@@ -1165,7 +1271,7 @@ IcePatch2::getFileTree0(const FileInfoSeq& infoSeq, FileTree0& tree0)
tree1.files.clear();
tree1.checksum.resize(20);
- for(FileInfoSeq::const_iterator p = infoSeq.begin(); p != infoSeq.end(); ++p)
+ for(LargeFileInfoSeq::const_iterator p = infoSeq.begin(); p != infoSeq.end(); ++p)
{
if(i == static_cast<int>(p->checksum[0]))
{
@@ -1177,7 +1283,7 @@ IcePatch2::getFileTree0(const FileInfoSeq& infoSeq, FileTree0& tree0)
allChecksums1.resize(tree1.files.size() * 21); // 20 bytes for the checksum + 1 byte for the flag
ByteSeq::iterator c1 = allChecksums1.begin();
- for(FileInfoSeq::const_iterator p = tree1.files.begin(); p != tree1.files.end(); ++p, c1 += 21)
+ for(LargeFileInfoSeq::const_iterator p = tree1.files.begin(); p != tree1.files.end(); ++p, c1 += 21)
{
copy(p->checksum.begin(), p->checksum.end(), c1);
*(c1 + 20) = p->executable;
diff --git a/cpp/src/IcePatch2Lib/Util.h b/cpp/src/IcePatch2Lib/Util.h
new file mode 100644
index 00000000000..4f243a5d640
--- /dev/null
+++ b/cpp/src/IcePatch2Lib/Util.h
@@ -0,0 +1,207 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 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_UTIL_H
+#define ICE_PATCH2_UTIL_H
+
+#include <Ice/Ice.h>
+#include <IcePatch2/FileInfo.h>
+#include <stdio.h>
+
+namespace IcePatch2Internal
+{
+
+ICE_PATCH2_API extern const char* checksumFile;
+ICE_PATCH2_API extern const char* logFile;
+
+ICE_PATCH2_API std::string lastError();
+
+ICE_PATCH2_API std::string bytesToString(const Ice::ByteSeq&);
+ICE_PATCH2_API Ice::ByteSeq stringToBytes(const std::string&);
+
+ICE_PATCH2_API std::string simplify(const std::string&);
+
+ICE_PATCH2_API bool isRoot(const std::string&);
+
+ICE_PATCH2_API std::string getSuffix(const std::string&);
+ICE_PATCH2_API std::string getWithoutSuffix(const std::string&);
+ICE_PATCH2_API bool ignoreSuffix(const std::string&);
+
+ICE_PATCH2_API std::string getBasename(const std::string&);
+ICE_PATCH2_API std::string getDirname(const std::string&);
+
+ICE_PATCH2_API void rename(const std::string&, const std::string&);
+
+ICE_PATCH2_API void remove(const std::string&);
+ICE_PATCH2_API void removeRecursive(const std::string&);
+
+ICE_PATCH2_API Ice::StringSeq readDirectory(const std::string&);
+
+ICE_PATCH2_API void createDirectory(const std::string&);
+ICE_PATCH2_API void createDirectoryRecursive(const std::string&);
+
+ICE_PATCH2_API void compressBytesToFile(const std::string&, const Ice::ByteSeq&, Ice::Int);
+ICE_PATCH2_API void decompressFile(const std::string&);
+
+ICE_PATCH2_API void setFileFlags(const std::string&, const IcePatch2::FileInfo&);
+ICE_PATCH2_API void setFileFlags(const std::string&, const IcePatch2::LargeFileInfo&);
+
+struct FileInfoEqual : public std::binary_function<const IcePatch2::LargeFileInfo&, const IcePatch2::LargeFileInfo&, bool>
+{
+ bool
+ operator()(const IcePatch2::LargeFileInfo& lhs, const IcePatch2::LargeFileInfo& rhs)
+ {
+ if(lhs.path != rhs.path)
+ {
+ return false;
+ }
+
+ //
+ // For the size portion of the comparison, we only distinquish
+ // between file (size >= 0) and directory (size == -1). We do
+ // not take the actual size into account, as it might be set
+ // to 0 if no compressed file is available.
+ //
+ Ice::Long lsz = lhs.size > 0 ? 0 : lhs.size;
+ Ice::Long rsz = rhs.size > 0 ? 0 : rhs.size;
+ if(lsz != rsz)
+ {
+ return false;
+ }
+
+ if(lhs.executable != rhs.executable)
+ {
+ return false;
+ }
+
+ return lhs.checksum == rhs.checksum;
+ }
+};
+
+struct FileInfoWithoutFlagsLess : public std::binary_function<const IcePatch2::LargeFileInfo&, const IcePatch2::LargeFileInfo&, bool>
+{
+ bool
+ operator()(const IcePatch2::LargeFileInfo& lhs, const IcePatch2::LargeFileInfo& rhs)
+ {
+ return compareWithoutFlags(lhs, rhs) < 0;
+ }
+
+ int
+ compareWithoutFlags(const IcePatch2::LargeFileInfo& lhs, const IcePatch2::LargeFileInfo& rhs)
+ {
+ if(lhs.path < rhs.path)
+ {
+ return -1;
+ }
+ else if(rhs.path < lhs.path)
+ {
+ return 1;
+ }
+
+ //
+ // For the size portion of the comparison, we only distinquish
+ // between file (size >= 0) and directory (size == -1). We do
+ // not take the actual size into account, as it might be set
+ // to 0 if no compressed file is available.
+ //
+ Ice::Long lsz = lhs.size > 0 ? 0 : lhs.size;
+ Ice::Long rsz = rhs.size > 0 ? 0 : rhs.size;
+ if(lsz < rsz)
+ {
+ return -1;
+ }
+ else if(rsz < lsz)
+ {
+ return 1;
+ }
+
+ if(lhs.checksum < rhs.checksum)
+ {
+ return -1;
+ }
+ else if(rhs.checksum < lhs.checksum)
+ {
+ return 1;
+ }
+
+ return 0;
+ }
+};
+
+struct FileInfoLess : public FileInfoWithoutFlagsLess
+{
+ bool
+ operator()(const IcePatch2::LargeFileInfo& lhs, const IcePatch2::LargeFileInfo& rhs)
+ {
+ int rc = compareWithoutFlags(lhs, rhs);
+ if(rc < 0)
+ {
+ return true;
+ }
+ else if(rc > 0)
+ {
+ return false;
+ }
+
+ return lhs.executable < rhs.executable;
+ }
+};
+
+class ICE_PATCH2_API GetFileInfoSeqCB
+{
+public:
+
+ virtual ~GetFileInfoSeqCB() { }
+
+ virtual bool remove(const std::string&) = 0;
+ virtual bool checksum(const std::string&) = 0;
+ virtual bool compress(const std::string&) = 0;
+};
+
+ICE_PATCH2_API bool getFileInfoSeq(const std::string&, int, GetFileInfoSeqCB*, IcePatch2::FileInfoSeq&);
+ICE_PATCH2_API bool getFileInfoSeq(const std::string&, int, GetFileInfoSeqCB*, IcePatch2::LargeFileInfoSeq&);
+
+ICE_PATCH2_API bool getFileInfoSeqSubDir(const std::string&, const std::string&, int, GetFileInfoSeqCB*, IcePatch2::FileInfoSeq&);
+ICE_PATCH2_API bool getFileInfoSeqSubDir(const std::string&, const std::string&, int, GetFileInfoSeqCB*, IcePatch2::LargeFileInfoSeq&);
+
+ICE_PATCH2_API void saveFileInfoSeq(const std::string&, const IcePatch2::FileInfoSeq&);
+ICE_PATCH2_API void saveFileInfoSeq(const std::string&, const IcePatch2::LargeFileInfoSeq&);
+
+ICE_PATCH2_API void loadFileInfoSeq(const std::string&, IcePatch2::FileInfoSeq&);
+ICE_PATCH2_API void loadFileInfoSeq(const std::string&, IcePatch2::LargeFileInfoSeq&);
+
+ICE_PATCH2_API bool readFileInfo(FILE*, IcePatch2::FileInfo&);
+ICE_PATCH2_API bool readFileInfo(FILE*, IcePatch2::LargeFileInfo&);
+
+ICE_PATCH2_API IcePatch2::FileInfo toFileInfo(const IcePatch2::LargeFileInfo&);
+ICE_PATCH2_API IcePatch2::LargeFileInfo toLargeFileInfo(const IcePatch2::FileInfo&);
+
+ICE_PATCH2_API bool writeFileInfo(FILE*, const IcePatch2::FileInfo&);
+ICE_PATCH2_API bool writeFileInfo(FILE*, const IcePatch2::LargeFileInfo&);
+
+struct FileTree1
+{
+ IcePatch2::LargeFileInfoSeq files;
+ Ice::ByteSeq checksum;
+};
+
+typedef std::vector<FileTree1> FileTree1Seq;
+
+struct FileTree0
+{
+ FileTree1Seq nodes;
+ Ice::ByteSeq checksum;
+};
+
+ICE_PATCH2_API void getFileTree0(const IcePatch2::FileInfoSeq&, FileTree0&);
+ICE_PATCH2_API void getFileTree0(const IcePatch2::LargeFileInfoSeq&, FileTree0&);
+
+}
+
+#endif