Logo
~Apps~
~Projects~
~Contact~


FileManager Class Reference

Manages read/write/verification of files defined in metainfo file. More...

#include <FileManager.h>

Collaboration diagram for FileManager:

Collaboration graph
[legend]
List of all members.

Public Types

typedef std::vector< FIL * > fil_v

Public Member Functions

 FileManager (PeerHandler &, const std::string &hash)
 ~FileManager ()
size_t ReadPiece (size_t index, unsigned char *buf, size_t length)
size_t ReadNextPiece (unsigned char *buf, size_t length)
void Write (size_t index, unsigned char *buf, size_t length, size_t begin)
PeerHandlerHandler ()
void OpenFiles ()
size_t GetFilesize (const std::string &)
uint64_t GetTotalLength ()
bool Verify (size_t piece, size_t length)
bool CompareHash (unsigned char *h1, unsigned char *h2)

Private Member Functions

void GetFiles (fil_v &files)

Private Attributes

std::string m_hash
PeerHandlerm_handler
std::string m_basename
fil_v m_files
int64_t m_length
FILE * m_single_file

Classes

struct  FIL
 File handle + information for one file in metainfo block. More...

Detailed Description

Manages read/write/verification of files defined in metainfo file.

Definition at line 42 of file FileManager.h.


Member Typedef Documentation

typedef std::vector<FIL *> FileManager::fil_v

Definition at line 52 of file FileManager.h.


Constructor & Destructor Documentation

FileManager::FileManager ( PeerHandler ,
const std::string &  hash 
)

Definition at line 45 of file FileManager.cpp.

References DEB, GetFiles(), PeerHandler::GetSession(), PeerHandler::GetTorrentDirectory(), m_basename, m_files, m_length, and OpenFiles().

00046 :m_hash(hash)
00047 ,m_handler(h)
00048 ,m_single_file(NULL)
00049 {
00050 DEB(    printf("FileManager()\n");)
00051         Session *sess = h.GetSession(hash);
00052         if (sess)
00053         {
00054                 m_basename = h.GetTorrentDirectory() + "/" + sess -> GetInfoHash() + "/" + sess -> GetName();
00055                 GetFiles(m_files);
00056                 m_length = sess -> GetLength();
00057 
00058 DEB(            printf("OpenFiles()\n");)
00059                 OpenFiles();
00060         }
00061 }

FileManager::~FileManager (  ) 

Definition at line 64 of file FileManager.cpp.

References DEB, m_files, and m_single_file.

00065 {
00066 DEB(    printf("~FileManager()\n");)
00067         if (m_single_file)
00068         {
00069                 fclose(m_single_file);
00070         }
00071         for (fil_v::iterator it = m_files.begin(); it != m_files.end(); it++)
00072         {
00073                 FIL *p = *it;
00074                 if (p -> fil)
00075                 {
00076                         fclose(p -> fil);
00077                 }
00078                 delete p;
00079         }
00080 }


Member Function Documentation

size_t FileManager::ReadPiece ( size_t  index,
unsigned char *  buf,
size_t  length 
)

Definition at line 123 of file FileManager.cpp.

References DEB, PeerHandler::GetSession(), Handler(), m_files, m_hash, m_length, and m_single_file.

Referenced by Verify().

00124 {
00125         Session *sess = Handler().GetSession(m_hash);
00126         if (!sess)
00127                 return 0;
00128         size_t piece_length = sess -> GetPieceLength();
00129         if (m_length)
00130         {
00131                 long offset = index * piece_length;
00132                 if (fseek(m_single_file,offset,SEEK_SET))
00133                 {
00134 DEB(                    perror("fseek() failed");)
00135                 }
00136                 size_t n = fread(buf,1,length,m_single_file);
00137                 buf[0]++;
00138                 return n;
00139         }
00140         int64_t start = index * piece_length;
00141         size_t bufset = 0; // offset in buf
00142         size_t left = piece_length;
00143         int64_t ptr = 0;
00144         size_t read_length = 0;
00145 //DEB(printf("ReadPiece(%d, ptr = %lld)\n", index, ptr);)
00146         for (fil_v::iterator it = m_files.begin(); it != m_files.end() && left; it++)
00147         {
00148                 FIL *p = *it;
00149                 // start within this file?
00150                 if (start < ptr + p -> length)
00151                 {
00152                         long offset = start - ptr;
00153                         size_t len = p -> length - offset;
00154                         if (len > left)
00155                         {
00156                                 len = left;
00157                         }
00158                         if (fseek(p -> fil,offset,SEEK_SET))
00159                         {
00160 DEB(                            perror("fseek() failed");)
00161                         }
00162                         read_length += fread(buf + bufset,1,len,p -> fil);
00163                         // update
00164                         start += len;
00165                         bufset += len;
00166                         left -= len;
00167                         if (!left)
00168                                 return read_length;
00169                 }
00170                 ptr += p -> length;
00171         }
00172         buf[0]++;
00173         return read_length;
00174 }

size_t FileManager::ReadNextPiece ( unsigned char *  buf,
size_t  length 
)

void FileManager::Write ( size_t  index,
unsigned char *  buf,
size_t  length,
size_t  begin 
)

Definition at line 177 of file FileManager.cpp.

References DEB, PeerHandler::GetSession(), Handler(), m_files, m_hash, m_length, and m_single_file.

00178 {
00179         Session *sess = Handler().GetSession(m_hash);
00180         if (!sess)
00181                 return;
00182         size_t piece_length = sess -> GetPieceLength();
00183         if (m_length)
00184         {
00185                 long offset = index * piece_length + begin;
00186                 if (fseek(m_single_file,offset,SEEK_SET))
00187                 {
00188 DEB(                    perror("fseek() failed");)
00189                 }
00190                 long pos = ftell(m_single_file);
00191                 if (pos < offset)
00192                 {
00193                         long diff = offset - pos;
00194                         char *tmp = new char[diff];
00195                         memset(tmp,0,diff);
00196                         fwrite(tmp,1,diff,m_single_file);
00197                         delete tmp;
00198                 }
00199                 fwrite(buf,1,length,m_single_file);
00200                 fflush(m_single_file);
00201                 return;
00202         }
00203         int64_t start = index * piece_length + begin;
00204         size_t bufset = 0; // offset in buf
00205         size_t left = length;
00206         int64_t ptr = 0;
00207         for (fil_v::iterator it = m_files.begin(); it != m_files.end() && left; it++)
00208         {
00209                 FIL *p = *it;
00210                 // start within this file?
00211                 if (start < ptr + p -> length)
00212                 {
00213                         long offset = start - ptr;
00214                         size_t len = p -> length - offset; // length of file remaining from start of this write
00215                         if (len > left)
00216                         {
00217                                 len = left;
00218                         }
00219 //DEB(printf("writing@%08x length %04x\n",offset,len);)
00220                         if (fseek(p -> fil,offset,SEEK_SET))
00221                         {
00222 DEB(                            perror("fseek() failed");)
00223                         }
00224 
00225                         long pos = ftell(p -> fil);
00226                         if (pos < offset)
00227                         {
00228                                 long diff = offset - pos;
00229                                 char *tmp = new char[diff];
00230                                 memset(tmp,0,diff);
00231                                 fwrite(tmp,1,diff,p -> fil);
00232                                 delete tmp;
00233 DEB(printf(" adding %ld bytes\n",diff);)
00234                         }
00235 
00236                         if (fwrite(buf + bufset,1,len,p -> fil) != len)
00237                         {
00238 DEB(                            printf(" * short write!!!!!!\n");)
00239                         }
00240                         fflush(p -> fil);
00241                         // update
00242                         start += len;
00243                         bufset += len;
00244                         left -= len;
00245                 }
00246                 ptr += p -> length;
00247         }
00248 }

PeerHandler& FileManager::Handler (  )  [inline]

Definition at line 60 of file FileManager.h.

References m_handler.

Referenced by GetFiles(), OpenFiles(), ReadPiece(), Verify(), and Write().

00060 { return m_handler; }

void FileManager::OpenFiles (  ) 

Definition at line 83 of file FileManager.cpp.

References DEB, GetFilesize(), Handler(), m_basename, m_files, m_length, m_single_file, and PeerHandler::mkpath().

Referenced by FileManager().

00084 {
00085         if (m_length) // single file
00086         {
00087                 std::string full = m_basename;
00088 //DEB(printf("single file: %s\n", full.c_str());)
00089                 Handler().mkpath( full );
00090                 m_single_file = fopen(full.c_str(),"r+b");
00091                 if (!m_single_file)
00092                 {
00093                         m_single_file = fopen(full.c_str(),"w+b");
00094                 }
00095                 size_t size = GetFilesize(full);
00096                 if (size > m_length)
00097                 {
00098 DEB(                    printf("Single file already too large - aborting\n");)
00099                 }
00100                 return;
00101         }
00102         // multi file
00103         for (fil_v::iterator it = m_files.begin(); it != m_files.end(); it++)
00104         {
00105                 FIL *p = *it;
00106                 std::string full = p -> path;
00107 //DEB(printf("multifile: %s\n", full.c_str());)
00108                 Handler().mkpath( full );
00109                 p -> fil = fopen(full.c_str(),"r+b");
00110                 if (!p -> fil)
00111                 {
00112                         p -> fil = fopen(full.c_str(),"w+b");
00113                 }
00114                 size_t size = GetFilesize(full);
00115                 if (size > p -> length)
00116                 {
00117 DEB(                    printf("File '%s' too large - aborting\n",full.c_str());)
00118                 }
00119         }
00120 }

size_t FileManager::GetFilesize ( const std::string &   ) 

Definition at line 251 of file FileManager.cpp.

Referenced by OpenFiles().

00252 {
00253         struct stat st;
00254         stat(path.c_str(),&st);
00255         return st.st_size;
00256 }

uint64_t FileManager::GetTotalLength (  ) 

Definition at line 259 of file FileManager.cpp.

References m_files.

00260 {
00261         uint64_t l = 0;
00262         for (fil_v::iterator it = m_files.begin(); it != m_files.end(); it++)
00263         {
00264                 FIL *p = *it;
00265                 l += p -> length;
00266         }
00267         return l;
00268 }

bool FileManager::Verify ( size_t  piece,
size_t  length 
)

Definition at line 287 of file FileManager.cpp.

References CompareHash(), DEB, PeerHandler::GetSession(), Handler(), m_hash, and ReadPiece().

00288 {
00289         Session *sess = Handler().GetSession(m_hash);
00290         if (!sess)
00291         {
00292 DEB(printf("Verify: no session\n");)
00293                 return false;
00294         }
00295         Piece *ptr = sess -> GetIncomplete(index);
00296         if (!ptr)
00297         {
00298 DEB(printf("Verify: no piece ptr\n");)
00299                 return false;
00300         }
00301         unsigned char *p = new unsigned char[length];
00302         unsigned char hash[20];
00303         size_t read_length;
00304         read_length = ReadPiece(index, p, length );
00305         if (read_length != length)
00306         {
00307 //DEB(          printf(" *** Verify(): only read %d bytes out of %d\n",read_length,length);)
00308                 delete[] p;
00309                 return false;
00310         }
00311         SHA1( p, read_length, hash );
00312         delete[] p;
00313         if (CompareHash(hash,(unsigned char *)sess -> GetPieces().substr(index * 20,20).c_str()))
00314         {
00315 DEB(            printf("Verify OK!\n");)
00316                 return true;
00317         }
00318 //DEB(  printf("Verify failed\n");)
00319         return false;
00320 }

bool FileManager::CompareHash ( unsigned char *  h1,
unsigned char *  h2 
)

Definition at line 323 of file FileManager.cpp.

Referenced by Verify().

00324 {
00325         for (size_t i = 0; i < 20; i++)
00326                 if (h1[i] != h2[i])
00327                         return false;
00328         return true;
00329 }

void FileManager::GetFiles ( fil_v files  )  [private]

Definition at line 271 of file FileManager.cpp.

References PeerHandler::GetSession(), PeerHandler::GetTorrentDirectory(), Handler(), and m_hash.

Referenced by FileManager().

00272 {
00273         Session *sess = Handler().GetSession(m_hash);
00274         if (!sess)
00275                 return;
00276         file_v& ref = sess -> GetFiles();
00277         for (file_v::iterator it = ref.begin(); it != ref.end(); it++)
00278         {
00279                 file_t *f = *it; // name, offset, length
00280                 std::string full = Handler().GetTorrentDirectory() + "/" + sess -> GetInfoHash() + "/" + f -> name;
00281                 FIL *p2 = new FIL(f -> length, full);
00282                 files.push_back(p2);
00283         }
00284 }


Member Data Documentation

std::string FileManager::m_hash [private]

Definition at line 71 of file FileManager.h.

Referenced by GetFiles(), ReadPiece(), Verify(), and Write().

Definition at line 72 of file FileManager.h.

Referenced by Handler().

std::string FileManager::m_basename [private]

Definition at line 73 of file FileManager.h.

Referenced by FileManager(), and OpenFiles().

int64_t FileManager::m_length [private]

Definition at line 75 of file FileManager.h.

Referenced by FileManager(), OpenFiles(), ReadPiece(), and Write().

FILE* FileManager::m_single_file [private]

Definition at line 76 of file FileManager.h.

Referenced by OpenFiles(), ReadPiece(), Write(), and ~FileManager().


The documentation for this class was generated from the following files:
Page, code, and content Copyright (C) 2006 by Anders Hedström
Generated on Mon Aug 29 20:21:47 2005 for C++ Sockets by  doxygen 1.4.4