diff options
Diffstat (limited to 'cpp/src/IcePatch2/FileServerI.cpp')
-rw-r--r-- | cpp/src/IcePatch2/FileServerI.cpp | 155 |
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); +} |