1 #ifndef BTCONTENT_H
2 #define BTCONTENT_H
3 
4 #include "def.h"
5 #include <inttypes.h>
6 #include <sys/types.h>
7 
8 #include <time.h>
9 #include "bitfield.h"
10 #include "btfiles.h"
11 
12 typedef struct _btcache{
13   uint64_t bc_off;
14   size_t bc_len;
15 
16   unsigned char bc_f_flush:1;
17   unsigned char bc_f_reserved:7;
18 
19   char *bc_buf;
20 
21   struct _btcache *bc_next;
22   struct _btcache *bc_prev;
23   struct _btcache *age_next;
24   struct _btcache *age_prev;
25 }BTCACHE;
26 
27 typedef struct _btflush{
28   size_t idx;
29   struct _btflush *next;
30 }BTFLUSH;
31 
32 typedef struct _bfnode{
33   char *name;
34   BitField bitfield;
35   struct _bfnode *next;
36 
_bfnode_bfnode37   _bfnode(){
38     name = (char *)0;
39     next = (struct _bfnode *)0;
40   }
~_bfnode_bfnode41   ~_bfnode(){
42     if(name) delete []name;
43   }
44 }BFNODE;
45 
46 class btContent
47 {
48   //METAINFO��Ա
49   char *m_announce;
50   unsigned char *m_hash_table;
51   unsigned char m_shake_buffer[68];
52   char *m_announcelist[9];
53   char *m_comment, *m_created_by;
54 
55   size_t m_hashtable_length;
56   size_t m_piece_length;
57   size_t m_npieces, m_check_piece;
58   time_t m_create_date, m_seed_timestamp, m_start_timestamp;
59   size_t m_private;
60 
61   uint64_t m_left_bytes;
62   btFiles m_btfiles;
63 
64   time_t m_flush_failed, m_flush_tried;
65 
66   BTCACHE **m_cache, *m_cache_oldest, *m_cache_newest;
67   size_t m_cache_size, m_cache_used;
68   size_t m_cache_hit, m_cache_miss, m_cache_pre;
69   time_t m_cache_eval_time;
70   BTFLUSH *m_flushq;
71 
72   BFNODE *m_filters, *m_current_filter;
73 
74   size_t m_prevdlrate;
75   size_t m_hash_failures, m_dup_blocks, m_unwanted_blocks;
76 
77   void _Set_InfoHash(unsigned char buf[20]);
78   char* _file2mem(const char *fname, size_t *psiz);
79 
ReleaseHashTable()80   void ReleaseHashTable(){
81     if(m_hash_table){
82       delete []m_hash_table;
83       m_hash_table = (unsigned char*) 0;
84     }
85   }
86 
87   int CheckExist();
88   void CacheClean(size_t need);
89   void CacheEval();
max_uint64_t(uint64_t a,uint64_t b)90   uint64_t max_uint64_t(uint64_t a,uint64_t b) { return (a > b) ? a : b; }
min_uint64_t(uint64_t a,uint64_t b)91   uint64_t min_uint64_t(uint64_t a,uint64_t b) { return (a > b) ? b : a; }
92   ssize_t CacheIO(char *buf, uint64_t off, size_t len, int method);
93   void FlushEntry(BTCACHE *p);
94 
95  public:
96   BitField *pBF;
97   BitField *pBMasterFilter;
98   BitField *pBRefer;
99   BitField *pBChecked;
100   BitField *pBMultPeer;
101   char *global_piece_buffer;
102   size_t global_buffer_size;
103 
104   btContent();
105   ~btContent();
106 
107   void CacheConfigure();
108   void FlushCache();
109   void FlushPiece(size_t idx);
110   void Uncache(size_t idx);
111   void FlushQueue();
112   int NeedFlush() const;
FlushFailed()113   int FlushFailed() const { return m_flush_failed ? 1 : 0 ; }
114 
115   int CreateMetainfoFile(const char *mifn);
116   int InitialFromFS(const char *pathname, char *ann_url, size_t piece_length);
117   int InitialFromMI(const char *metainfo_fname,const char *saveas);
118 
119   int CheckNextPiece();
CheckedPieces()120   size_t CheckedPieces() const { return m_check_piece; }
121 
GetAnnounce()122   char* GetAnnounce() { return m_announce;}
123 
GetShakeBuffer()124   unsigned char* GetShakeBuffer() {return m_shake_buffer;}
GetInfoHash()125   unsigned char* GetInfoHash() {return (m_shake_buffer + 28);}
GetPeerId()126   unsigned char* GetPeerId() {return (m_shake_buffer + 48); }
127 
128   size_t GetPieceLength(size_t idx);
GetPieceLength()129   size_t GetPieceLength() const { return m_piece_length; }
GetNPieces()130   size_t GetNPieces() const { return m_npieces; }
131 
GetTotalFilesLength()132   uint64_t GetTotalFilesLength() const { return m_btfiles.GetTotalLength(); }
GetLeftBytes()133   uint64_t GetLeftBytes() const { return m_left_bytes; }
134 
135   int APieceComplete(size_t idx);
136   int GetHashValue(size_t idx,unsigned char *md);
137 
138   int CachePrep(size_t idx);
139   ssize_t ReadSlice(char *buf,size_t idx,size_t off,size_t len);
140   ssize_t WriteSlice(char *buf,size_t idx,size_t off,size_t len);
141   ssize_t ReadPiece(char *buf,size_t idx);
142 
143   int PrintOut();
144   int PrintFiles();
145   int SeedTimeout();
146   void CompletionCommand();
147   void SaveBitfield();
148 
149   void CheckFilter();
150   void SetFilter();
GetFilter()151   BitField *GetFilter() const {
152     return m_current_filter ? &(m_current_filter->bitfield) : (BitField *)0;
153   }
GetNextFilter()154   BitField *GetNextFilter() const { return GetNextFilter((BitField *)0); }
155   BitField *GetNextFilter(BitField *pfilter) const;
GetFilterName()156   char *GetFilterName() const { return m_current_filter->name; }
SetTmpFilter(int nfile,BitField * pFilter)157   void SetTmpFilter(int nfile, BitField *pFilter){
158     m_btfiles.SetFilter(nfile, pFilter, m_piece_length);
159   }
160 
GetNFiles()161   size_t GetNFiles() const { return m_btfiles.GetNFiles(); }
GetFileName(size_t nfile)162   char *GetFileName(size_t nfile) const {
163     return m_btfiles.GetFileName(nfile);
164   }
GetFileSize(size_t nfile)165   uint64_t GetFileSize(size_t nfile) const {
166     return m_btfiles.GetFileSize(nfile);
167   }
GetFilePieces(size_t nfile)168   size_t GetFilePieces(size_t nfile) const {
169     return m_btfiles.GetFilePieces(nfile);
170   }
171 
GetStartTime()172   time_t GetStartTime() const { return m_start_timestamp; }
GetSeedTime()173   time_t GetSeedTime() const { return m_seed_timestamp; }
174 
GetHashFailures()175   size_t GetHashFailures() const { return m_hash_failures; }
GetDupBlocks()176   size_t GetDupBlocks() const { return m_dup_blocks; }
GetUnwantedBlocks()177   size_t GetUnwantedBlocks() const { return m_unwanted_blocks; }
CountHashFailure()178   void CountHashFailure() { m_hash_failures++; }
179   void CountDupBlock(size_t len);
CountUnwantedBlock()180   void CountUnwantedBlock() { m_unwanted_blocks++; }
181 
IsFull()182   int IsFull() const { return pBF->IsFull(); }
183   int Seeding() const;
184 
CacheHits()185   size_t CacheHits() const { return m_cache_hit; }
186   // "miss" does not count prefetch reads from disk
CacheMiss()187   size_t CacheMiss() const { return m_cache_miss; }
188   // instead, "pre" does
CachePre()189   size_t CachePre() const { return m_cache_pre; }
CacheSize()190   size_t CacheSize() const { return m_cache_size; }
CacheUsed()191   size_t CacheUsed() const { return m_cache_used; }
192 
193   void DumpCache();
194 };
195 
196 extern btContent BTCONTENT;
197 
198 #endif
199