?? btcontent.cpp
字號:
int flg_rescan; BTCACHE *p = m_cache; for( ; p && (offset + len) > p->bc_off && !CACHE_FIT(p,offset,len); p = p->bc_next) ; for( ; len && p && CACHE_FIT(p, offset, len);){ flg_rescan = 0; if( offset < p->bc_off ){ len2 = p->bc_off - offset; if( CacheIO(buf, offset, len2, 0) < 0) return -1; flg_rescan = 1; }else if( offset > p->bc_off ){ len2 = p->bc_off + p->bc_len - offset; if( len2 > len ) len2 = len; memcpy(buf, p->bc_buf + offset - p->bc_off, len2); }else{ len2 = (len > p->bc_len) ? p->bc_len : len; memcpy(buf, p->bc_buf, len2); } buf += len2; offset += len2; len -= len2; if( len ){ if( flg_rescan ){ for( p = m_cache; p && (offset + len) > p->bc_off && !CACHE_FIT(p,offset,len); p = p->bc_next) ; }else{ time(&p->bc_last_timestamp); p = p->bc_next; } } }// end for; if( len ) return CacheIO(buf, offset, len, 0); } return 0;}void btContent::CacheClean(){ BTCACHE *p, *pp, *prm, *prmp; again: pp = prm = prmp = (BTCACHE*) 0; for( p = m_cache; p; p = p->bc_next){ if( !p->bc_f_flush ){ if( !prm || prm->bc_last_timestamp > p->bc_last_timestamp){ prm = p; prmp = pp;} } pp = p; } if( !prm ){ if( m_cache_used ) { FlushCache(); goto again; } else return; } if( prmp ) prmp->bc_next = prm->bc_next; else m_cache = prm->bc_next; m_cache_used -= prm->bc_len; delete []prm->bc_buf; delete prm;}void btContent::CacheConfigure(){ if( cfg_cache_size ){ if( cfg_cache_size > 128 ) cfg_cache_size = 128; m_cache_size = cfg_cache_size * 1024 * 1024; if( m_cache_size < 4 * m_piece_length ) m_cache_size = 4 * m_piece_length; }}void btContent::FlushCache(){ BTCACHE *p = m_cache; for( ; p; p = p->bc_next) if( p->bc_f_flush ){ p->bc_f_flush = 0; if(m_btfiles.IO(p->bc_buf, p->bc_off, p->bc_len, 1) < 0) fprintf(stderr,"warn, write file failed while flush cache.\n"); }}ssize_t btContent::WriteSlice(char *buf,size_t idx,size_t off,size_t len){ //u_int64_t offset = (u_int64_t)(idx * m_piece_length + off); //changed u_int64_t offset = (u_int64_t)idx * (u_int64_t)m_piece_length + (u_int64_t)off; // printf("\nOffset-write: %lu - Piece:%lu\n",offset,(unsigned long)idx); if( !m_cache_size ) return m_btfiles.IO(buf, offset, len, 1); else{ size_t len2; int flg_rescan; BTCACHE *p; for(p = m_cache ; p && (offset + len) > p->bc_off && !CACHE_FIT(p,offset,len); p = p->bc_next) ; for( ; len && p && CACHE_FIT(p, offset, len);){ flg_rescan = 0; if( offset < p->bc_off ){ len2 = p->bc_off - offset; if( CacheIO(buf, offset, len2, 1) < 0) return -1; flg_rescan = 1; }else if( offset > p->bc_off ){ len2 = p->bc_off + p->bc_len - offset; if( len2 > len ) len2 = len; memcpy(p->bc_buf + offset - p->bc_off, buf, len2); p->bc_f_flush = 1; }else{ len2 = (len > p->bc_len) ? p->bc_len : len; memcpy(p->bc_buf, buf, len2); p->bc_f_flush = 1; } buf += len2; offset += len2; len -= len2; if( len ){ if( flg_rescan ){ for( p = m_cache; p && (offset + len) > p->bc_off && !CACHE_FIT(p,offset,len); p = p->bc_next) ; }else{ time(&p->bc_last_timestamp); p = p->bc_next; } } }// end for; if( len ) return CacheIO(buf, offset, len, 1); } return 0;}ssize_t btContent::CacheIO(char *buf, u_int64_t off, size_t len, int method){ BTCACHE *p; BTCACHE *pp = (BTCACHE*) 0; BTCACHE *pnew = (BTCACHE*) 0; for( ; m_cache_size < (m_cache_used + len); ) CacheClean(); if( 0 == method && m_btfiles.IO(buf, off, len, method) < 0) return -1; pnew = new BTCACHE;#ifndef WINDOWS if( !pnew ) return method ? m_btfiles.IO(buf, off, len, method) : 0;#endif pnew->bc_buf = new char[len];#ifndef WINDOWS if( !(pnew->bc_buf) ){ delete pnew; return method ? m_btfiles.IO(buf, off, len, method) : 0; }#endif memcpy(pnew->bc_buf, buf, len); pnew->bc_off = off; pnew->bc_len = len; pnew->bc_f_flush = method; m_cache_used += len; time(&pnew->bc_last_timestamp); // find insert point. for(p = m_cache; p && off > p->bc_off; pp = p, p = pp->bc_next) ; pnew->bc_next = p; if( pp ) pp->bc_next = pnew; else m_cache = pnew; return 0;}ssize_t btContent::ReadPiece(char *buf,size_t idx){ return ReadSlice(buf, idx, 0, GetPieceLength(idx));}size_t btContent::GetPieceLength(size_t idx){ return (idx == m_btfiles.GetTotalLength() / m_piece_length) ? (size_t)(m_btfiles.GetTotalLength() % m_piece_length) :m_piece_length;}int btContent::CheckExist(){ size_t idx = 0; size_t percent = GetNPieces() / 100; unsigned char md[20]; if( !percent ) percent = 1; char *runtime_msg = new char[256]; for( ; idx < m_npieces; idx++){ if( GetHashValue(idx, md) == 0 && memcmp(md, m_hash_table + idx * 20, 20) == 0){ m_left_bytes -= GetPieceLength(idx); pBF->Set(idx); } if(idx % percent == 0 || idx == m_npieces-1){ if (arg_runtime_status_fd >0) { memset(runtime_msg, 0, 256); sprintf(runtime_msg, "Check exist: %d/%d", idx+1, pBF->NBits()); write(arg_runtime_status_fd, runtime_msg, 256); lseek(arg_runtime_status_fd, 0, SEEK_SET); } else { printf("\rCheck exist: %d/%d",idx+1,pBF->NBits()); fflush(stdout); } } } if (arg_runtime_status_fd > 0) { memset(runtime_msg, 0, 256); sprintf(runtime_msg, "Check Complete.\n"); write(arg_runtime_status_fd, runtime_msg, 256); lseek(arg_runtime_status_fd, 0, SEEK_SET); } else printf(" Complete\n"); delete []runtime_msg; return 0;}char* btContent::_file2mem(const char *fname, size_t *psiz){ char *b = (char*) 0; struct stat sb; FILE* fp; fp = fopen(fname,"r"); if( !fp ){ fprintf(stderr,"error, open %s failed. %s\n",fname,strerror(errno)); return (char*) 0; } if(stat(fname,&sb) < 0){ fprintf(stderr,"error, stat %s failed, %s\n",fname,strerror(errno)); return (char*) 0; } if( sb.st_size > MAX_METAINFO_FILESIZ ){ fprintf(stderr,"error, %s is really a metainfo file???\n",fname); return (char*) 0; } b = new char[sb.st_size];#ifndef WINDOWS if( !b ) return (char*) 0;#endif if(fread(b, sb.st_size, 1, fp) != 1){ if( ferror(fp) ){ delete []b; return (char*) 0; } } fclose(fp); if(psiz) *psiz = sb.st_size; return b;}int btContent::APieceComplete(size_t idx){ unsigned char md[20]; if(pBF->IsSet(idx)) return 1; if( GetHashValue(idx, md) < 0 ) return -1; if( memcmp(md,(m_hash_table + idx * 20), 20) != 0){ fprintf(stderr,"warn,piece %d hash check failed.\n",idx); return 0; } pBF->Set(idx); m_left_bytes -= GetPieceLength(idx); return 1;}int btContent::GetHashValue(size_t idx,unsigned char *md){ if( ReadPiece(global_piece_buffer,idx) < 0) return -1; Sha1(global_piece_buffer,GetPieceLength(idx),md); return 0;}int btContent::SeedTimeout(const time_t *pnow){ u_int64_t dl; if( pBF->IsFull() ){ if( !m_seed_timestamp ){ Tracker.Reset(1); Self.ResetDLTimer(); Self.ResetULTimer(); ReleaseHashTable(); m_seed_timestamp = *pnow; FlushCache(); if (arg_runtime_status_fd>0) { char *runtime_msg = new char[256]; memset(runtime_msg, 0, 256); sprintf(runtime_msg, "Download complete.\nTotal time used: %lu minutes.\n", (*pnow - m_start_timestamp)/60); write(arg_runtime_status_fd, runtime_msg, 256); delete []runtime_msg; } else { printf("\nDownload complete.\n"); printf("Total time used: %lu minutes.\n",(*pnow - m_start_timestamp) / 60); } printf("Seed for other %lu hours", cfg_seed_hours); if(cfg_seed_ratio) printf(" or to ratio of %f", cfg_seed_ratio); printf(".\n\n"); if (arg_runtime_status_fd >0) { close(arg_runtime_status_fd); arg_runtime_status_fd = -1; } } dl = (Self.TotalDL() > 0) ? Self.TotalDL() : GetTotalFilesLength(); if( (cfg_seed_ratio == 0 && cfg_seed_hours == 0) || (cfg_seed_hours > 0 && (*pnow - m_seed_timestamp) >= (cfg_seed_hours * 60 * 60)) || (cfg_seed_ratio > 0 && cfg_seed_ratio <= Self.TotalUL() / dl) ) return 1; } return 0;}size_t btContent::getFilePieces(size_t nfile){ return m_btfiles.getFilePieces(nfile);}void btContent::SetFilter(){ m_btfiles.SetFilter(arg_file_to_download,pBFilter,m_piece_length);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -