From 417855848fdfb72cdcb7c79cbe9bfc3567724652 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 20 Jul 2008 11:14:54 +0000 Subject: [PATCH] merged file_win.cpp and file.cpp (removed the need for file_win.cpp). The file is no longer a pimpl --- Jamfile | 10 +- Makefile.am | 2 +- include/libtorrent/error_code.hpp | 3 + include/libtorrent/file.hpp | 13 +- src/file.cpp | 421 ++++++++++++++++-------------- src/file_win.cpp | 392 ---------------------------- 6 files changed, 239 insertions(+), 602 deletions(-) delete mode 100644 src/file_win.cpp diff --git a/Jamfile b/Jamfile index d3734f7b0..e25cb810c 100755 --- a/Jamfile +++ b/Jamfile @@ -173,15 +173,6 @@ rule building ( properties * ) } } - if windows in $(properties) - { - result += src/file_win.cpp ; - } - else - { - result += src/file.cpp ; - } - if on in $(properties) { result += src/memdebug.cpp ; @@ -291,6 +282,7 @@ SOURCES = file_storage lazy_bdecode escape_string + file gzip http_connection http_stream diff --git a/Makefile.am b/Makefile.am index b344b2d76..1f3db3ed3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -32,7 +32,7 @@ docs/moopolice_thumb.gif \ docs/qbittorrent_thumb.jpg \ docs/ziptorrent_thumb.gif \ docs/unicode_support.png docs/client_test.png docs/style.css Jamfile project-root.jam \ -src/file_win.cpp libtorrent-rasterbar.pc \ +libtorrent-rasterbar.pc \ bindings/README.txt \ bindings/python/Jamfile \ bindings/python/client.py \ diff --git a/include/libtorrent/error_code.hpp b/include/libtorrent/error_code.hpp index 7b82a5b9d..ffc7d662e 100644 --- a/include/libtorrent/error_code.hpp +++ b/include/libtorrent/error_code.hpp @@ -56,6 +56,7 @@ namespace libtorrent #if BOOST_VERSION < 103500 typedef asio::error_code error_code; inline asio::error::error_category get_posix_category() { return asio::error::system_category; } + inline asio::error::error_category get_system_category() { return asio::error::system_category; } #else struct libtorrent_error_category : boost::system::error_category @@ -69,6 +70,8 @@ namespace libtorrent extern libtorrent_error_category libtorrent_category; using boost::system::error_code; + inline boost::system::error_category const& get_system_category() + { return boost::system::get_system_category(); } inline boost::system::error_category const& get_posix_category() { return boost::system::get_posix_category(); } #endif diff --git a/include/libtorrent/file.hpp b/include/libtorrent/file.hpp index 907149052..c1f70b50c 100644 --- a/include/libtorrent/file.hpp +++ b/include/libtorrent/file.hpp @@ -77,7 +77,6 @@ namespace libtorrent public: open_mode(): m_mask(0) {} - open_mode operator|(open_mode m) const { return open_mode(m.m_mask | m_mask); } @@ -92,6 +91,7 @@ namespace libtorrent bool operator==(open_mode m) const { return m_mask == m.m_mask; } bool operator!=(open_mode m) const { return m_mask != m.m_mask; } + operator bool() const { return m_mask != 0; } private: @@ -107,6 +107,7 @@ namespace libtorrent ~file(); bool open(fs::path const& p, open_mode m, error_code& ec); + bool is_open() const; void close(); bool set_size(size_type size, error_code& ec); @@ -118,8 +119,14 @@ namespace libtorrent private: - struct impl; - const std::auto_ptr m_impl; +#ifdef TORRENT_WINDOWS + HANDLE m_file_handle; +#else + int m_fd; +#endif +#ifndef NDEBUG + open_mode m_open_mode; +#endif }; diff --git a/src/file.cpp b/src/file.cpp index c1b1a643c..edc52e9db 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -31,27 +31,22 @@ POSSIBILITY OF SUCH DAMAGE. */ #include "libtorrent/pch.hpp" +#include "libtorrent/config.hpp" #include -#ifdef _WIN32 +#ifdef TORRENT_WINDOWS // windows part #include "libtorrent/utf8.hpp" -#include -#include -#include -#include - -#ifndef _MODE_T_ -typedef int mode_t; -#endif +#include +#include #ifdef UNICODE #include "libtorrent/storage.hpp" #endif #else -// unix part +// posix part #define _FILE_OFFSET_BITS 64 #include #include @@ -88,18 +83,7 @@ BOOST_STATIC_ASSERT(sizeof(lseek(0, 0, 0)) >= 8); namespace { - enum { mode_in = 1, mode_out = 2 }; - - mode_t map_open_mode(int m) - { - if (m == (mode_in | mode_out)) return O_RDWR | O_CREAT | O_BINARY | O_RANDOM; - if (m == mode_out) return O_WRONLY | O_CREAT | O_BINARY | O_RANDOM; - if (m == mode_in) return O_RDONLY | O_BINARY | O_RANDOM; - TORRENT_ASSERT(false); - return 0; - } - -#ifdef WIN32 +#ifdef TORRENT_WINDOWS std::string utf8_native(std::string const& s) { try @@ -121,9 +105,16 @@ namespace } } #else - std::string const& utf8_native(std::string const& s) + + enum { mode_in = 1, mode_out = 2 }; + + mode_t map_open_mode(int m) { - return s; + if (m == (mode_in | mode_out)) return O_RDWR | O_CREAT | O_BINARY | O_RANDOM; + if (m == mode_out) return O_WRONLY | O_CREAT | O_BINARY | O_RANDOM; + if (m == mode_in) return O_RDONLY | O_BINARY | O_RANDOM; + TORRENT_ASSERT(false); + return 0; } #endif @@ -133,206 +124,242 @@ namespace libtorrent { namespace fs = boost::filesystem; +#ifdef TORRENT_WINDOWS + const file::open_mode file::in(GENERIC_READ); + const file::open_mode file::out(GENERIC_WRITE); + const file::seek_mode file::begin(FILE_BEGIN); + const file::seek_mode file::end(FILE_END); +#else const file::open_mode file::in(mode_in); const file::open_mode file::out(mode_out); + const file::seek_mode file::begin(SEEK_SET); + const file::seek_mode file::end(SEEK_END); +#endif - const file::seek_mode file::begin(1); - const file::seek_mode file::end(2); - - struct file::impl - { - impl() - : m_fd(-1) - , m_open_mode(0) - {} - - impl(fs::path const& path, int mode, error_code& ec) - : m_fd(-1) - , m_open_mode(0) - { - open(path, mode, ec); - } - - ~impl() - { - close(); - } - - bool open(fs::path const& path, int mode, error_code& ec) - { - close(); + file::file() #ifdef TORRENT_WINDOWS - - const int permissions = _S_IREAD | _S_IWRITE; - -#ifdef defined UNICODE -#define open _wopen - std::wstring file_path(safe_convert(path.native_file_string())); + : m_file_handle(INVALID_HANDLE_VALUE) #else -#define open _open - std::string const& file_path = path.native_file_string(); + : m_fd(-1) #endif -#else // if not windows - // rely on default umask to filter x and w permissions - // for group and others - const mode_t permissions = S_IRWXU | S_IRWXG | S_IRWXO; - std::string const& file_path = path.native_file_string(); +#ifndef NDEBUG + , m_open_mode(0) #endif - m_fd = ::open(file_path.c_str(), map_open_mode(mode), permissions); - -#ifdef TORRENT_WINDOWS -#undef open -#endif - - if (m_fd == -1) - { - ec = error_code(errno, get_posix_category()); - return false; - } - m_open_mode = mode; - return true; - } - - void close() - { - if (m_fd == -1) return; - -#ifdef _WIN32 - ::_close(m_fd); -#else - ::close(m_fd); -#endif - m_fd = -1; - m_open_mode = 0; - } - - size_type read(char* buf, size_type num_bytes, error_code& ec) - { - TORRENT_ASSERT(m_open_mode & mode_in); - TORRENT_ASSERT(m_fd != -1); - -#ifdef _WIN32 - size_type ret = ::_read(m_fd, buf, num_bytes); -#else - size_type ret = ::read(m_fd, buf, num_bytes); -#endif - if (ret == -1) ec = error_code(errno, get_posix_category()); - return ret; - } - - size_type write(const char* buf, size_type num_bytes, error_code& ec) - { - TORRENT_ASSERT(m_open_mode & mode_out); - TORRENT_ASSERT(m_fd != -1); - - // TODO: Test this a bit more, what happens with random failures in - // the files? -// if ((rand() % 100) > 80) -// throw file_error("debug"); - -#ifdef _WIN32 - size_type ret = ::_write(m_fd, buf, num_bytes); -#else - size_type ret = ::write(m_fd, buf, num_bytes); -#endif - if (ret == -1) ec = error_code(errno, get_posix_category()); - return ret; - } - - bool set_size(size_type s, error_code& ec) - { -#ifdef _WIN32 -#error file.cpp is for posix systems only. use file_win.cpp on windows -#else - if (ftruncate(m_fd, s) < 0) - { - ec = error_code(errno, get_posix_category()); - return false; - } - return true; -#endif - } - - size_type seek(size_type offset, int m, error_code& ec) - { - TORRENT_ASSERT(m_open_mode); - TORRENT_ASSERT(m_fd != -1); - - int seekdir = (m == 1)?SEEK_SET:SEEK_END; -#ifdef _WIN32 - size_type ret = _lseeki64(m_fd, offset, seekdir); -#else - size_type ret = lseek(m_fd, offset, seekdir); -#endif - - // For some strange reason this fails - // on win32. Use windows specific file - // wrapper instead. - if (ret < 0) ec = error_code(errno, get_posix_category()); - return ret; - } - - size_type tell(error_code& ec) - { - TORRENT_ASSERT(m_open_mode); - TORRENT_ASSERT(m_fd != -1); - - size_type ret; -#ifdef _WIN32 - ret = _telli64(m_fd); -#else - ret = lseek(m_fd, 0, SEEK_CUR); -#endif - if (ret < 0) ec = error_code(errno, get_posix_category()); - return ret; - } - - int m_fd; - int m_open_mode; - }; - - // pimpl forwardings - - file::file() : m_impl(new impl()) {} - - file::file(fs::path const& p, file::open_mode m, error_code& ec) - : m_impl(new impl(p, m.m_mask, ec)) {} - file::~file() {} - - bool file::open(fs::path const& p, file::open_mode m, error_code& ec) + file::file(fs::path const& path, open_mode mode, error_code& ec) +#ifdef TORRENT_WINDOWS + : m_file_handle(INVALID_HANDLE_VALUE) +#else + : m_fd(-1) +#endif +#ifndef NDEBUG + , m_open_mode(0) +#endif { - return m_impl->open(p, m.m_mask, ec); + open(path, mode, ec); + } + + file::~file() + { + close(); + } + + bool file::open(fs::path const& path, open_mode mode, error_code& ec) + { + close(); +#ifdef TORRENT_WINDOWS + +#ifdef UNICODE + std::wstring file_path(safe_convert(path.native_file_string())); +#else + std::string file_path = utf8_native(path.native_file_string()); +#endif + + HANDLE m_file_handle = CreateFile( + file_path.c_str() + , mode.m_mask + , FILE_SHARE_READ + , 0 + , (mode & out)?OPEN_ALWAYS:OPEN_EXISTING + , FILE_ATTRIBUTE_NORMAL + , 0); + + if (m_file_handle == INVALID_HANDLE_VALUE) + { + ec = error_code(GetLastError(), get_system_category()); + return false; + } + + // try to make the file sparse if supported + if (mode & out) + { + DWORD temp; + ::DeviceIoControl(m_file_handle, FSCTL_SET_SPARSE, 0, 0 + , 0, 0, &temp, 0); + } +#else + // rely on default umask to filter x and w permissions + // for group and others + m_fd = ::open(path.native_file_string().c_str() + , map_open_mode(mode.m_mask), S_IRWXU | S_IRWXG | S_IRWXO); + + if (m_fd == -1) + { + ec = error_code(errno, get_posix_category()); + return false; + } +#endif +#ifndef NDEBUG + m_open_mode = mode; +#endif + return true; + } + + bool file::is_open() const + { +#ifdef TORRENT_WINDOWS + return m_file_handle != INVALID_HANDLE_VALUE; +#else + return m_fd != -1; +#endif } void file::close() { - m_impl->close(); - } - - size_type file::write(const char* buf, size_type num_bytes, error_code& ec) - { - return m_impl->write(buf, num_bytes, ec); +#ifdef TORRENT_WINDOWS + if (m_file_handle == INVALID_HANDLE_VALUE) return; + CloseHandle(m_file_handle); + m_file_handle = INVALID_HANDLE_VALUE; +#else + if (m_fd == -1) return; + ::close(m_fd); + m_fd = -1; +#endif +#ifndef NDEBUG + m_open_mode = 0; +#endif } size_type file::read(char* buf, size_type num_bytes, error_code& ec) { - return m_impl->read(buf, num_bytes, ec); + TORRENT_ASSERT((m_open_mode & in) == in); + TORRENT_ASSERT(buf); + TORRENT_ASSERT(num_bytes >= 0); + TORRENT_ASSERT(is_open()); + +#ifdef TORRENT_WINDOWS + + TORRENT_ASSERT(DWORD(num_bytes) == num_bytes); + DWORD ret = 0; + if (num_bytes != 0) + { + if (ReadFile(m_file_handle, buf, (DWORD)num_bytes, &ret, 0) == FALSE) + { + ec = error_code(GetLastError(), get_system_category()); + return -1; + } + } +#else + size_type ret = ::read(m_fd, buf, num_bytes); + if (ret == -1) ec = error_code(errno, get_posix_category()); +#endif + return ret; } - bool file::set_size(size_type s, error_code& ec) + size_type file::write(const char* buf, size_type num_bytes, error_code& ec) { - return m_impl->set_size(s, ec); + TORRENT_ASSERT((m_open_mode & out) == out); + TORRENT_ASSERT(buf); + TORRENT_ASSERT(num_bytes >= 0); + TORRENT_ASSERT(is_open()); + +#ifdef TORRENT_WINDOWS + + DWORD ret = 0; + if (num_bytes != 0) + { + if (WriteFile(m_file_handle, buf, (DWORD)num_bytes, &ret, 0) == FALSE) + { + ec = error_code(GetLastError(), get_system_category()); + return -1; + } + } +#else + size_type ret = ::write(m_fd, buf, num_bytes); + if (ret == -1) ec = error_code(errno, get_posix_category()); +#endif + return ret; } - size_type file::seek(size_type pos, file::seek_mode m, error_code& ec) + bool file::set_size(size_type s, error_code& ec) + { + TORRENT_ASSERT(is_open()); + TORRENT_ASSERT(s >= 0); + +#ifdef TORRENT_WINDOWS + size_type pos = tell(ec); + if (ec) return false; + seek(s, begin, ec); + if (ec) return false; + if (::SetEndOfFile(m_file_handle) == FALSE) + { + ec = error_code(GetLastError(), get_system_category()); + return false; + } +#else + if (ftruncate(m_fd, s) < 0) + { + ec = error_code(errno, get_posix_category()); + return false; + } +#endif + return true; + } + + size_type file::seek(size_type offset, seek_mode m, error_code& ec) { - return m_impl->seek(pos, m.m_val, ec); + TORRENT_ASSERT(is_open()); + +#ifdef TORRENT_WINDOWS + LARGE_INTEGER offs; + offs.QuadPart = offset; + if (SetFilePointerEx(m_file_handle, offs, &offs, m.m_val) == FALSE) + { + ec = error_code(GetLastError(), get_system_category()); + return -1; + } + return offs.QuadPart; +#else + size_type ret = lseek(m_fd, offset, m.m_val); + if (ret < 0) ec = error_code(errno, get_posix_category()); + return ret; +#endif } size_type file::tell(error_code& ec) { - return m_impl->tell(ec); + TORRENT_ASSERT(is_open()); + +#ifdef TORRENT_WINDOWS + LARGE_INTEGER offs; + offs.QuadPart = 0; + + // is there any other way to get offset? + if (SetFilePointerEx(m_file_handle, offs, &offs + , FILE_CURRENT) == FALSE) + { + ec = error_code(GetLastError(), get_system_category()); + return -1; + } + + return offs.QuadPart; +#else + size_type ret; + ret = lseek(m_fd, 0, SEEK_CUR); + if (ret < 0) ec = error_code(errno, get_posix_category()); + return ret; +#endif } } + diff --git a/src/file_win.cpp b/src/file_win.cpp deleted file mode 100644 index fb4f0ce9a..000000000 --- a/src/file_win.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/* - -Copyright (c) 2003, Magnus Jonsson & Arvid Norberg -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - * Neither the name of the author nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "libtorrent/file.hpp" -#include "libtorrent/utf8.hpp" -#include "libtorrent/assert.hpp" - -#ifdef UNICODE -#include "libtorrent/storage.hpp" -#endif - -#include -#include -#include -#include - -namespace -{ - // must be used to not leak memory in case something would throw - class auto_localfree - { - public: - auto_localfree(HLOCAL memory) - : m_memory(memory) - { - } - ~auto_localfree() - { - if (m_memory) - LocalFree(m_memory); - } - private: - HLOCAL m_memory; - }; - - std::string utf8_native(std::string const& s) - { - try - { - std::wstring ws; - libtorrent::utf8_wchar(s, ws); - std::size_t size = wcstombs(0, ws.c_str(), 0); - if (size == std::size_t(-1)) return s; - std::string ret; - ret.resize(size); - size = wcstombs(&ret[0], ws.c_str(), size + 1); - if (size == wchar_t(-1)) return s; - ret.resize(size); - return ret; - } - catch(std::exception) - { - return s; - } - } - } - -namespace libtorrent -{ - - struct file::impl : boost::noncopyable - { - enum open_flags - { - read_flag = 1, - write_flag = 2 - }; - - enum seek_mode - { - seek_begin = FILE_BEGIN, - seek_from_here = FILE_CURRENT, - seek_end = FILE_END - }; - - void set_error(const char* thrower) - { - DWORD err = GetLastError(); - -#ifdef UNICODE - wchar_t *wbuffer = 0; - FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM - |FORMAT_MESSAGE_ALLOCATE_BUFFER - , 0, err, 0, (LPWSTR)&wbuffer, 0, 0); - auto_localfree auto_free(wbuffer); - std::string tmp_utf8; - libtorrent::wchar_utf8(wbuffer, tmp_utf8); - char const* buffer = tmp_utf8.c_str(); -#else - char* buffer = 0; - FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM - |FORMAT_MESSAGE_ALLOCATE_BUFFER - , 0, err, 0, (LPSTR)&buffer, 0, 0); - auto_localfree auto_free(buffer); -#endif - - std::stringstream s; - s << (thrower ? thrower : "NULL") << ": " << (buffer ? buffer : "NULL"); - - if (!m_error) m_error.reset(new std::string); - *m_error = s.str(); - } - - impl() - { - m_file_handle = INVALID_HANDLE_VALUE; - } - - bool open(const char *file_name, open_flags flags) - { - TORRENT_ASSERT(file_name); - TORRENT_ASSERT(flags & (read_flag | write_flag)); - - DWORD access_mask = 0; - if (flags & read_flag) - access_mask |= GENERIC_READ; - if (flags & write_flag) - access_mask |= GENERIC_WRITE; - - TORRENT_ASSERT(access_mask & (GENERIC_READ | GENERIC_WRITE)); - - #ifdef UNICODE - std::wstring wfile_name(safe_convert(file_name)); - HANDLE new_handle = CreateFile( - wfile_name.c_str() - , access_mask - , FILE_SHARE_READ - , 0 - , (flags & write_flag)?OPEN_ALWAYS:OPEN_EXISTING - , FILE_ATTRIBUTE_NORMAL - , 0); - #else - HANDLE new_handle = CreateFile( - utf8_native(file_name).c_str() - , access_mask - , FILE_SHARE_READ - , 0 - , (flags & write_flag)?OPEN_ALWAYS:OPEN_EXISTING - , FILE_ATTRIBUTE_NORMAL - , 0); - #endif - - if (new_handle == INVALID_HANDLE_VALUE) - { - set_error(file_name); - return false; - } - // try to make the file sparse if supported - if (access_mask & GENERIC_WRITE) - { - DWORD temp; - ::DeviceIoControl(new_handle, FSCTL_SET_SPARSE, 0, 0 - , 0, 0, &temp, 0); - } - // will only close old file if the open succeeded - close(); - m_file_handle = new_handle; - return true; - } - - void close() - { - if (m_file_handle != INVALID_HANDLE_VALUE) - { - CloseHandle(m_file_handle); - m_file_handle = INVALID_HANDLE_VALUE; - } - } - - ~impl() - { - close(); - } - - size_type write(const char* buffer, size_type num_bytes) - { - TORRENT_ASSERT(buffer); - TORRENT_ASSERT((DWORD)num_bytes == num_bytes); - DWORD bytes_written = 0; - if (num_bytes != 0) - { - if (FALSE == WriteFile( - m_file_handle - , buffer - , (DWORD)num_bytes - , &bytes_written - , 0)) - { - set_error("file::write"); - return -1; - } - } - return bytes_written; - } - - size_type read(char* buffer, size_type num_bytes) - { - TORRENT_ASSERT(buffer); - TORRENT_ASSERT(num_bytes >= 0); - TORRENT_ASSERT((DWORD)num_bytes == num_bytes); - - DWORD bytes_read = 0; - if (num_bytes != 0) - { - if (FALSE == ReadFile( - m_file_handle - , buffer - , (DWORD)num_bytes - , &bytes_read - , 0)) - { - set_error("file::set_size"); - return -1; - } - } - return bytes_read; - } - - bool set_size(size_type s) - { - size_type pos = tell(); - seek(s, seek_begin); - if (FALSE == ::SetEndOfFile(m_file_handle)) - { - set_error("file::set_size"); - return false; - } - return true; - } - - size_type seek(size_type pos, seek_mode from_where) - { - TORRENT_ASSERT(pos >= 0 || from_where != seek_begin); - TORRENT_ASSERT(pos <= 0 || from_where != seek_end); - LARGE_INTEGER offs; - offs.QuadPart = pos; - if (FALSE == SetFilePointerEx( - m_file_handle - , offs - , &offs - , from_where)) - { - set_error("file::seek"); - return -1; - } - return offs.QuadPart; - } - - size_type tell() - { - LARGE_INTEGER offs; - offs.QuadPart = 0; - - // is there any other way to get offset? - if (FALSE == SetFilePointerEx( - m_file_handle - , offs - , &offs - , FILE_CURRENT)) - { - set_error("file::tell"); - return -1; - } - - size_type pos = offs.QuadPart; - TORRENT_ASSERT(pos >= 0); - return pos; - } -/* - size_type size() - { - LARGE_INTEGER s; - if (FALSE == GetFileSizeEx(m_file_handle, &s)) - { - throw_exception("file::size"); - } - - size_type size = s.QuadPart; - TORRENT_ASSERT(size >= 0); - return size; - } -*/ - - std::string const& error() const - { - if (!m_error) m_error.reset(new std::string); - return *m_error; - } - - private: - - HANDLE m_file_handle; - mutable boost::scoped_ptr m_error; - - }; -} - -namespace libtorrent -{ - - const file::seek_mode file::begin(file::impl::seek_begin); - const file::seek_mode file::end(file::impl::seek_end); - - const file::open_mode file::in(file::impl::read_flag); - const file::open_mode file::out(file::impl::write_flag); - - file::file() - : m_impl(new libtorrent::file::impl()) - { - } - file::file(boost::filesystem::path const& p, open_mode m) - : m_impl(new libtorrent::file::impl()) - { - open(p,m); - } - - file::~file() - { - } - - bool file::open(boost::filesystem::path const& p, open_mode m) - { - TORRENT_ASSERT(p.is_complete()); - return m_impl->open(p.native_file_string().c_str(), impl::open_flags(m.m_mask)); - } - - void file::close() - { - m_impl->close(); - } - - size_type file::write(const char* buffer, size_type num_bytes) - { - return m_impl->write(buffer, num_bytes); - } - - size_type file::read(char* buffer, size_type num_bytes) - { - return m_impl->read(buffer, num_bytes); - } - - bool file::set_size(size_type s) - { - return m_impl->set_size(s); - } - - size_type file::seek(size_type pos, seek_mode m) - { - return m_impl->seek(pos,impl::seek_mode(m.m_val)); - } - - size_type file::tell() - { - return m_impl->tell(); - } - - std::string const& file::error() const - { - return m_impl->error(); - } -}