📄 btstream.cpp
字号:
#include "btstream.h" // def.h#include <arpa/inet.h>#include <inttypes.h>#include <sys/time.h>#include <string.h> // memcpy#include "msgencode.h"#include "btconfig.h"#ifndef HAVE_CLOCK_GETTIME#include "compat.h"#endifsize_t get_nl(char *from){ // assumes H_INT_LEN==H_LEN==4 uint32_t t = 0; memcpy(&t, from, H_INT_LEN); return (size_t)ntohl((unsigned long)t);}void set_nl(char *to, size_t from){ // assumes H_INT_LEN==H_LEN==4 uint32_t from32 = (uint32_t)htonl((unsigned long)from); memcpy(to, &from32, H_INT_LEN);}ssize_t btStream::Flush(){ return out_buffer.FlushOut(sock);}ssize_t btStream::Send_State(unsigned char state){ char msg[H_LEN + H_BASE_LEN]; set_nl(msg, H_BASE_LEN); msg[H_LEN] = (char)state; return out_buffer.Put(sock,msg,H_LEN + H_BASE_LEN);}ssize_t btStream::Send_Have(size_t idx){ char msg[H_LEN + H_HAVE_LEN]; set_nl(msg, H_HAVE_LEN); msg[H_LEN] = (char)M_HAVE; set_nl(msg + H_LEN + H_BASE_LEN, idx); return out_buffer.Put(sock,msg,H_LEN + H_HAVE_LEN);}ssize_t btStream::Send_Bitfield(char *bit_buf,size_t len){ size_t q = htonl(len + H_BASE_LEN); unsigned char t = M_BITFIELD; ssize_t r = out_buffer.Put(sock,(char*)&q,H_LEN); if(r < 0) return r; r = out_buffer.Put(sock,(char*)&t,H_BASE_LEN); if(r < 0) return r; return out_buffer.Put(sock,bit_buf,len);}ssize_t btStream::Send_Cancel(size_t idx,size_t off,size_t len){ char msg[H_LEN + H_CANCEL_LEN]; set_nl(msg, H_CANCEL_LEN); msg[H_LEN] = M_CANCEL; set_nl(msg + H_LEN + H_BASE_LEN, idx); set_nl(msg + H_LEN + H_BASE_LEN + H_INT_LEN, off); set_nl(msg + H_LEN + H_BASE_LEN + H_INT_LEN * 2, len); return out_buffer.Put(sock,msg,H_LEN + H_CANCEL_LEN);}ssize_t btStream::Send_Piece(size_t idx,size_t off,char *piece_buf,size_t len){ size_t q = htonl(len + H_PIECE_LEN); unsigned char t = M_PIECE; ssize_t r; idx = htonl(idx); off = htonl(off); if( (r = out_buffer.Put(sock,(char*)&q,H_LEN)) < 0 ) return r; if( (r = out_buffer.Put(sock,(char*)&t,H_BASE_LEN)) < 0 ) return r; if( (r = out_buffer.Put(sock,(char*)&idx,H_INT_LEN)) < 0) return r; if( (r = out_buffer.Put(sock,(char*)&off,H_INT_LEN)) < 0) return r; return out_buffer.PutFlush(sock,piece_buf,len);}ssize_t btStream::Send_Request(size_t idx, size_t off,size_t len){ char msg[H_LEN + H_REQUEST_LEN]; set_nl(msg, H_REQUEST_LEN); msg[H_LEN] = (char)M_REQUEST; set_nl(msg + H_LEN + H_BASE_LEN, idx); set_nl(msg + H_LEN + H_BASE_LEN + H_INT_LEN, off); set_nl(msg + H_LEN + H_BASE_LEN + H_INT_LEN * 2, len); return out_buffer.Put(sock,msg,H_LEN + H_REQUEST_LEN);}ssize_t btStream::Send_Keepalive(){ size_t i = 0; return out_buffer.Put(sock,(char*)&i,H_LEN);}int btStream::HaveMessage(){ // if message arrived. size_t r; if( H_LEN <= in_buffer.Count() ){ r = get_nl(in_buffer.BasePointer()); if( cfg_max_slice_size + H_LEN + H_PIECE_LEN < r ) return -1; //message too long if( r + H_LEN <= in_buffer.Count() ) return 1; } return 0; //no message arrived}ssize_t btStream::Feed(){ return in_buffer.FeedIn(sock);}ssize_t btStream::Feed(Rate *rate){ return Feed(0, rate);}ssize_t btStream::Feed(size_t limit, Rate *rate){ ssize_t retval; struct timespec nowspec; clock_gettime(CLOCK_REALTIME, &nowspec); retval = in_buffer.FeedIn(sock, limit); if( H_LEN + H_PIECE_LEN < in_buffer.Count() && M_PIECE == in_buffer.BasePointer()[H_LEN] ){ size_t r = get_nl(in_buffer.BasePointer()); if( r > H_PIECE_LEN ){ size_t change; if( in_buffer.Count() >= r + H_LEN ){ // have the whole message change = r - H_PIECE_LEN - m_oldbytes; m_oldbytes = 0; }else{ size_t nbytes = in_buffer.Count() - H_LEN - H_PIECE_LEN; change = nbytes - m_oldbytes; m_oldbytes = nbytes; } rate->RateAdd(change, (size_t)cfg_max_bandwidth_down, nowspec.tv_sec + (double)(nowspec.tv_nsec)/1000000000); } } return retval;}ssize_t btStream::PickMessage(){ return in_buffer.PickUp( get_nl(in_buffer.BasePointer()) + H_LEN );}ssize_t btStream::Send_Buffer(char *buf, size_t len){ return out_buffer.Put(sock,buf,len);}// Does not distinguish between keepalive, choke (msg 0), and no message.char btStream::PeekMessage(){ return ( H_LEN < in_buffer.Count() && get_nl(in_buffer.BasePointer()) ) ? in_buffer.BasePointer()[H_LEN] : 0;}// Is the next message known to match m?int btStream::PeekMessage(char m){ return ( H_LEN < in_buffer.Count() && m == in_buffer.BasePointer()[H_LEN] && get_nl(in_buffer.BasePointer()) ) ? 1 : 0;}// Is the next next message known to match m?int btStream::PeekNextMessage(char m){ char *base; base = in_buffer.BasePointer() + H_LEN + get_nl(in_buffer.BasePointer()); return ( H_LEN < in_buffer.Count() - (base - in_buffer.BasePointer()) && m == base[H_LEN] && get_nl(base) ) ? 1 : 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -