simplified the file interface

This commit is contained in:
Arvid Norberg 2008-10-19 05:03:17 +00:00
parent 54eb378a1e
commit 535f668c5d
6 changed files with 56 additions and 97 deletions

View File

@ -52,6 +52,18 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/size_type.hpp" #include "libtorrent/size_type.hpp"
#include "libtorrent/config.hpp" #include "libtorrent/config.hpp"
#ifdef TORRENT_WINDOWS
// windows part
#include <windows.h>
#include <winioctl.h>
#else
// posix part
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif
namespace libtorrent namespace libtorrent
{ {
namespace fs = boost::filesystem; namespace fs = boost::filesystem;
@ -60,53 +72,28 @@ namespace libtorrent
{ {
public: public:
class seek_mode enum
{ {
friend class file; #ifdef TORRENT_WINDOWS
private: read_only = GENERIC_READ,
seek_mode(int v): m_val(v) {} write_only = GENERIC_WRITE,
int m_val; read_write = GENERIC_READ | GENERIC_WRITE,
begin = FILE_BEGIN,
end = FILE_END,
#else
begin = SEEK_SET,
end = SEEK_END,
read_only = O_RDONLY,
write_only = O_WRONLY | O_CREAT,
read_write = O_RDWR | O_CREAT,
#endif
}; };
static const seek_mode begin;
static const seek_mode end;
class open_mode
{
friend class file;
public:
open_mode(): m_mask(0) {}
open_mode operator|(open_mode m) const
{ return open_mode(m.m_mask | m_mask); }
open_mode operator&(open_mode m) const
{ return open_mode(m.m_mask & m_mask); }
open_mode operator|=(open_mode m)
{
m_mask |= m.m_mask;
return *this;
}
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:
open_mode(int val): m_mask(val) {}
int m_mask;
};
static const open_mode in;
static const open_mode out;
file(); file();
file(fs::path const& p, open_mode m, error_code& ec); file(fs::path const& p, int m, error_code& ec);
~file(); ~file();
bool open(fs::path const& p, open_mode m, error_code& ec); bool open(fs::path const& p, int m, error_code& ec);
bool is_open() const; bool is_open() const;
void close(); void close();
bool set_size(size_type size, error_code& ec); bool set_size(size_type size, error_code& ec);
@ -114,7 +101,7 @@ namespace libtorrent
size_type write(const char*, size_type num_bytes, error_code& ec); size_type write(const char*, size_type num_bytes, error_code& ec);
size_type read(char*, size_type num_bytes, error_code& ec); size_type read(char*, size_type num_bytes, error_code& ec);
size_type seek(size_type pos, seek_mode m, error_code& ec); size_type seek(size_type pos, int m, error_code& ec);
size_type tell(error_code& ec); size_type tell(error_code& ec);
private: private:
@ -125,7 +112,7 @@ namespace libtorrent
int m_fd; int m_fd;
#endif #endif
#ifndef NDEBUG #ifndef NDEBUG
open_mode m_open_mode; int m_open_mode;
#endif #endif
}; };

View File

@ -66,7 +66,7 @@ namespace libtorrent
file_pool(int size = 40): m_size(size) {} file_pool(int size = 40): m_size(size) {}
boost::shared_ptr<file> open_file(void* st, fs::path const& p boost::shared_ptr<file> open_file(void* st, fs::path const& p
, file::open_mode m, error_code& ec); , int m, error_code& ec);
void release(void* st); void release(void* st);
void release(fs::path const& p); void release(fs::path const& p);
void resize(int size); void resize(int size);
@ -81,7 +81,7 @@ namespace libtorrent
fs::path file_path; fs::path file_path;
void* key; void* key;
ptime last_use; ptime last_use;
file::open_mode mode; int mode;
}; };
typedef multi_index_container< typedef multi_index_container<

View File

@ -67,14 +67,6 @@ BOOST_STATIC_ASSERT(sizeof(lseek(0, 0, 0)) >= 8);
#include <cstring> #include <cstring>
#include <vector> #include <vector>
#ifndef O_BINARY
#define O_BINARY 0
#endif
#ifndef O_RANDOM
#define O_RANDOM 0
#endif
#ifdef UNICODE #ifdef UNICODE
#include "libtorrent/storage.hpp" #include "libtorrent/storage.hpp"
#endif #endif
@ -104,18 +96,6 @@ namespace
return s; return s;
} }
} }
#else
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;
}
#endif #endif
} }
@ -124,18 +104,6 @@ namespace libtorrent
{ {
namespace fs = boost::filesystem; 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
file::file() file::file()
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
: m_file_handle(INVALID_HANDLE_VALUE) : m_file_handle(INVALID_HANDLE_VALUE)
@ -147,7 +115,7 @@ namespace libtorrent
#endif #endif
{} {}
file::file(fs::path const& path, open_mode mode, error_code& ec) file::file(fs::path const& path, int mode, error_code& ec)
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
: m_file_handle(INVALID_HANDLE_VALUE) : m_file_handle(INVALID_HANDLE_VALUE)
#else #else
@ -165,7 +133,7 @@ namespace libtorrent
close(); close();
} }
bool file::open(fs::path const& path, open_mode mode, error_code& ec) bool file::open(fs::path const& path, int mode, error_code& ec)
{ {
close(); close();
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
@ -178,10 +146,10 @@ namespace libtorrent
m_file_handle = CreateFile( m_file_handle = CreateFile(
file_path.c_str() file_path.c_str()
, mode.m_mask , mode
, FILE_SHARE_READ , FILE_SHARE_READ
, 0 , 0
, (mode & out)?OPEN_ALWAYS:OPEN_EXISTING , (mode == read_write || mode == write_only)?OPEN_ALWAYS:OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL , FILE_ATTRIBUTE_NORMAL
, 0); , 0);
@ -192,7 +160,7 @@ namespace libtorrent
} }
// try to make the file sparse if supported // try to make the file sparse if supported
if (mode & out) if (mode == write_only || mode == read_write)
{ {
DWORD temp; DWORD temp;
::DeviceIoControl(m_file_handle, FSCTL_SET_SPARSE, 0, 0 ::DeviceIoControl(m_file_handle, FSCTL_SET_SPARSE, 0, 0
@ -206,7 +174,7 @@ namespace libtorrent
| S_IROTH | S_IWOTH; | S_IROTH | S_IWOTH;
m_fd = ::open(path.native_file_string().c_str() m_fd = ::open(path.native_file_string().c_str()
, map_open_mode(mode.m_mask), permissions); , mode, permissions);
if (m_fd == -1) if (m_fd == -1)
{ {
@ -248,7 +216,7 @@ namespace libtorrent
size_type file::read(char* buf, size_type num_bytes, error_code& ec) size_type file::read(char* buf, size_type num_bytes, error_code& ec)
{ {
TORRENT_ASSERT((m_open_mode & in) == in); TORRENT_ASSERT(m_open_mode == read_only || m_open_mode == read_write);
TORRENT_ASSERT(buf); TORRENT_ASSERT(buf);
TORRENT_ASSERT(num_bytes >= 0); TORRENT_ASSERT(num_bytes >= 0);
TORRENT_ASSERT(is_open()); TORRENT_ASSERT(is_open());
@ -274,7 +242,7 @@ namespace libtorrent
size_type file::write(const char* buf, size_type num_bytes, error_code& ec) size_type file::write(const char* buf, size_type num_bytes, error_code& ec)
{ {
TORRENT_ASSERT((m_open_mode & out) == out); TORRENT_ASSERT(m_open_mode == write_only || m_open_mode == read_write);
TORRENT_ASSERT(buf); TORRENT_ASSERT(buf);
TORRENT_ASSERT(num_bytes >= 0); TORRENT_ASSERT(num_bytes >= 0);
TORRENT_ASSERT(is_open()); TORRENT_ASSERT(is_open());
@ -322,21 +290,21 @@ namespace libtorrent
return true; return true;
} }
size_type file::seek(size_type offset, seek_mode m, error_code& ec) size_type file::seek(size_type offset, int m, error_code& ec)
{ {
TORRENT_ASSERT(is_open()); TORRENT_ASSERT(is_open());
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
LARGE_INTEGER offs; LARGE_INTEGER offs;
offs.QuadPart = offset; offs.QuadPart = offset;
if (SetFilePointerEx(m_file_handle, offs, &offs, m.m_val) == FALSE) if (SetFilePointerEx(m_file_handle, offs, &offs, m) == FALSE)
{ {
ec = error_code(GetLastError(), get_system_category()); ec = error_code(GetLastError(), get_system_category());
return -1; return -1;
} }
return offs.QuadPart; return offs.QuadPart;
#else #else
size_type ret = lseek(m_fd, offset, m.m_val); size_type ret = lseek(m_fd, offset, m);
if (ret < 0) ec = error_code(errno, get_posix_category()); if (ret < 0) ec = error_code(errno, get_posix_category());
return ret; return ret;
#endif #endif

View File

@ -43,11 +43,11 @@ namespace libtorrent
using boost::multi_index::get; using boost::multi_index::get;
boost::shared_ptr<file> file_pool::open_file(void* st, fs::path const& p boost::shared_ptr<file> file_pool::open_file(void* st, fs::path const& p
, file::open_mode m, error_code& ec) , int m, error_code& ec)
{ {
TORRENT_ASSERT(st != 0); TORRENT_ASSERT(st != 0);
TORRENT_ASSERT(p.is_complete()); TORRENT_ASSERT(p.is_complete());
TORRENT_ASSERT(m == file::in || m == (file::in | file::out)); TORRENT_ASSERT(m == file::read_only || m == file::read_write);
boost::mutex::scoped_lock l(m_mutex); boost::mutex::scoped_lock l(m_mutex);
typedef nth_index<file_set, 0>::type path_view; typedef nth_index<file_set, 0>::type path_view;
path_view& pt = get<0>(m_files); path_view& pt = get<0>(m_files);
@ -68,7 +68,11 @@ namespace libtorrent
} }
e.key = st; e.key = st;
if ((e.mode & m) != m) // if we asked for a file in write mode,
// and the cached file is is not opened in
// write mode, re-open it
if ((e.mode != file::read_write)
&& (m == file::read_write))
{ {
// close the file before we open it with // close the file before we open it with
// the new read/write privilages // the new read/write privilages

View File

@ -530,7 +530,7 @@ namespace libtorrent
|| m_file_priority[file_index] > 0)) || m_file_priority[file_index] > 0))
{ {
boost::shared_ptr<file> f = m_pool.open_file(this boost::shared_ptr<file> f = m_pool.open_file(this
, m_save_path / file_iter->path, file::in | file::out, ec); , m_save_path / file_iter->path, file::read_write, ec);
if (ec) if (ec)
{ {
set_error(m_save_path / file_iter->path, ec); set_error(m_save_path / file_iter->path, ec);
@ -550,7 +550,7 @@ namespace libtorrent
{ {
error_code ec; error_code ec;
boost::shared_ptr<file> f = m_pool.open_file(this boost::shared_ptr<file> f = m_pool.open_file(this
, m_save_path / file_iter->path, file::in | file::out, ec); , m_save_path / file_iter->path, file::read_write, ec);
if (ec) set_error(m_save_path / file_iter->path, ec); if (ec) set_error(m_save_path / file_iter->path, ec);
else if (f) else if (f)
{ {
@ -1083,7 +1083,7 @@ namespace libtorrent
fs::path path = m_save_path / file_iter->path; fs::path path = m_save_path / file_iter->path;
error_code ec; error_code ec;
in = m_pool.open_file(this, path, file::in, ec); in = m_pool.open_file(this, path, file::read_only, ec);
if (!in || ec) if (!in || ec)
{ {
set_error(path, ec); set_error(path, ec);
@ -1200,7 +1200,7 @@ namespace libtorrent
fs::path path = m_save_path / file_iter->path; fs::path path = m_save_path / file_iter->path;
error_code ec; error_code ec;
out = m_pool.open_file(this, path, file::in | file::out, ec); out = m_pool.open_file(this, path, file::read_write, ec);
if (!out || ec) if (!out || ec)
{ {
set_error(path, ec); set_error(path, ec);

View File

@ -222,7 +222,7 @@ namespace libtorrent
{ {
file f; file f;
error_code ec; error_code ec;
if (!f.open(filename, file::in, ec)) return -1; if (!f.open(filename, file::read_only, ec)) return -1;
f.seek(0, file::end, ec); f.seek(0, file::end, ec);
if (ec) return -1; if (ec) return -1;
size_type s = f.tell(ec); size_type s = f.tell(ec);