summaryrefslogtreecommitdiff
path: root/cpp/src/IcePatch2/FileServerI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/IcePatch2/FileServerI.cpp')
-rw-r--r--cpp/src/IcePatch2/FileServerI.cpp155
1 files changed, 155 insertions, 0 deletions
diff --git a/cpp/src/IcePatch2/FileServerI.cpp b/cpp/src/IcePatch2/FileServerI.cpp
new file mode 100644
index 00000000000..c9b81ecfec9
--- /dev/null
+++ b/cpp/src/IcePatch2/FileServerI.cpp
@@ -0,0 +1,155 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 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 <IceUtil/DisableWarnings.h>
+#include <IceUtil/FileUtil.h>
+#include <IceUtil/ScopedArray.h>
+#include <IceUtil/Unicode.h>
+#include <IcePatch2/FileServerI.h>
+
+#ifdef _WIN32
+# include <io.h>
+#else
+# include <unistd.h>
+#endif
+
+using namespace std;
+using namespace Ice;
+using namespace IcePatch2;
+
+IcePatch2::FileServerI::FileServerI(const std::string& dataDir, const FileInfoSeq& infoSeq) :
+ _dataDir(dataDir), _tree0(FileTree0())
+{
+ FileTree0& tree0 = const_cast<FileTree0&>(_tree0);
+ getFileTree0(infoSeq, tree0);
+}
+
+FileInfoSeq
+IcePatch2::FileServerI::getFileInfoSeq(Int node0, const Current&) const
+{
+ if(node0 < 0 || node0 > 255)
+ {
+ throw PartitionOutOfRangeException();
+ }
+
+ return _tree0.nodes[node0].files;
+}
+
+ByteSeqSeq
+IcePatch2::FileServerI::getChecksumSeq(const Current&) const
+{
+ ByteSeqSeq checksums(256);
+
+ for(int node0 = 0; node0 < 256; ++node0)
+ {
+ checksums[node0] = _tree0.nodes[node0].checksum;
+ }
+
+ return checksums;
+}
+
+ByteSeq
+IcePatch2::FileServerI::getChecksum(const Current&) const
+{
+ return _tree0.checksum;
+}
+
+void
+IcePatch2::FileServerI::getFileCompressed_async(const AMD_FileServer_getFileCompressedPtr& cb,
+ const string& pa, Int pos, Int num, const Current&) const
+{
+ if(IceUtilInternal::isAbsolutePath(pa))
+ {
+ FileAccessException ex;
+ ex.reason = "illegal absolute path `" + pa + "'";
+ cb->ice_exception(ex);
+ return;
+ }
+
+ string path = simplify(pa);
+
+ if(path == ".." ||
+ path.find("/../") != string::npos ||
+ (path.size() >= 3 && (path.substr(0, 3) == "../" || path.substr(path.size() - 3, 3) == "/..")))
+ {
+ FileAccessException ex;
+ ex.reason = "illegal `..' component in path `" + path + "'";
+ cb->ice_exception(ex);
+ return;
+ }
+
+#if (defined(_MSC_VER) && (_MSC_VER >= 1600))
+ pair<const Byte*, const Byte*> ret(nullptr, nullptr);
+#else
+ pair<const Byte*, const Byte*> ret(0, 0);
+#endif
+
+ if(num <= 0 || pos < 0)
+ {
+ cb->ice_response(ret);
+ return;
+ }
+
+ int fd = IceUtilInternal::open(_dataDir + '/' + path + ".bz2", O_RDONLY|O_BINARY);
+ if(fd == -1)
+ {
+ FileAccessException ex;
+ ex.reason = "cannot open `" + path + "' for reading: " + strerror(errno);
+ cb->ice_exception(ex);
+ return;
+ }
+
+ if(
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+ _lseek(fd, static_cast<off_t>(pos), SEEK_SET)
+#else
+ lseek(fd, static_cast<off_t>(pos), SEEK_SET)
+#endif
+ != static_cast<off_t>(pos))
+ {
+ IceUtilInternal::close(fd);
+
+ ostringstream posStr;
+ posStr << pos;
+
+ FileAccessException ex;
+ ex.reason = "cannot seek position " + posStr.str() + " in file `" + path + "': " + strerror(errno);
+ cb->ice_exception(ex);
+ return;
+ }
+
+ IceUtil::ScopedArray<Byte> bytes(new Byte[num]);
+#ifdef _WIN32
+ int r;
+ if((r =
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+ _read(fd, bytes.get(), static_cast<unsigned int>(num))
+#else
+ read(fd, bytes.get(), static_cast<unsigned int>(num))
+#endif
+ ) == -1)
+#else
+ ssize_t r;
+ if((r = read(fd, bytes.get(), static_cast<size_t>(num))) == -1)
+#endif
+ {
+ IceUtilInternal::close(fd);
+
+ FileAccessException ex;
+ ex.reason = "cannot read `" + path + "': " + strerror(errno);
+ cb->ice_exception(ex);
+ return;
+ }
+
+ IceUtilInternal::close(fd);
+
+ ret.first = bytes.get();
+ ret.second = ret.first + r;
+ cb->ice_response(ret);
+}