⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bencode.cpp

📁 linux系统下bt的客户端实现。 采用的是c++
💻 CPP
字号:
#include <stdlib.h>#include <unistd.h>#include <stdio.h>#include <fstream>#include <sys/stat.h>#include <sys/types.h>#include <iostream>#include <fcntl.h>#include <errno.h>#include "Btcontent.h"#include "Bencode.h"#include "Sha.h"using namespace std;BencodeDict *create_dictionary(const char *path){    int fd;    size_t len;    struct stat sb;    char *buf, *s;    Bencode *pinfo ;	std::string keylist;    BencodeDict *pdict = NULL;    if (-1 == (fd = open(path, O_RDONLY)) || -1 == fstat(fd, &sb))	return NULL;    buf = new char[sb.st_size + 1];    if (NULL == buf)	return pdict;    s = buf;    len = 0;    for (; len != sb.st_size;) {	int n;	if (0 == (n = read(fd, s, sb.st_size - len)))	    break;	else {	    if (n < 0)		if (EINTR == errno)		    continue;		else		    break;	}	len += n;	s += n;    }    if (len < sb.st_size)	goto err;    *s = '\0';    pdict = new BencodeDict;    if (NULL == pdict || 0 == pdict->Decode(buf, sb.st_size + 1))		goto err;    keylist = "info";    pinfo = query_dict(pdict, keylist);    uint64_t totallen;		if( (totallen = pinfo->Encode(buf, sb.st_size)) > 0)	{/*    	cout << totallen << endl;		for(int i = 0; i< totallen ; i++)			cout<<buf[i];		cout << endl << endl <<endl;*/	}		Sha1((unsigned char*)buf, totallen, BTCONTENT.GetInfoHash());/*	for(int i = 0; i < 20; i++)	{		cout << md[i];	}	cout << endl;	*/    return pdict;  err:delete pdict;    delete []buf;    return NULL;}Bencode *query_dict(Bencode * pcode, std::string & keylist){    if (NULL == pcode || keylist.empty()	|| bencode_dict != pcode->m_enumType)	return NULL;    return ((BencodeDict *) pcode)->Search(keylist);}bool search_dictionary(Bencode * pcode, std::string & keylist,		       char **pbuf, int *pint){    bool b = false;    Bencode *ret;    int len;    if (NULL == pcode || bencode_dict != pcode->m_enumType	|| NULL == (ret = ((BencodeDict *) pcode)->Search(keylist)))	return false;    switch (ret->m_enumType) {    case bencode_int:	if (pint) {	    *pint = ((BencodeInt *) ret)->m_nValue;	    b = true;	}	break;    case bencode_str:	if (pbuf) {	    len = ((BencodeString *) ret)->m_strValue.length();	    *pbuf = new char[len + 1];	    if (NULL == *pbuf)		return false;	    memcpy(*pbuf, ((BencodeString *) ret)->m_strValue.c_str(),		   len);	    (*pbuf)[len] = '\0';	    if (pint)		*pint = len;	    std::cout << len << std::endl;	    b = true;	}	break;    default:	break;    }    return b;}void delete_dictionary(Bencode * pcode){    delete pcode;} size_t BencodeInt::Decode(char *pch, size_t len){    char *p = pch + 1;    if (2 > len)	return 0;    for (; len && isdigit(*p); p++, len--);    if (!len || *p != END_DELIMITER)	return 0;    m_nValue = strtol(pch + 1, (char **) 0, 10);    return (size_t) (p - pch + 1);}uint64_t BencodeInt::Encode(char *pch, size_t len){	char *p,dt[100];		p = pch;	*p++ = 'i';	snprintf(dt, 100, "%d", m_nValue);	//ltoa(m_nValue, dt, 10);	memcpy(p, dt, strlen(dt));	p += strlen(dt);	*p++ = 'e';		return p - pch;}BencodeInt::~BencodeInt(){}size_t BencodeString::Decode(char *pch, size_t len){    long int n;    char *psave, *p = pch;    if (2 > len)	return 0;    for (; len && *p != ':'; p++, len--);    if (!len)	return 0;    n = strtol(pch, (char **) 0, 10);    psave = p + 1;    for (; len && n; len--, n--, p++);    if (!len)	return 0;    std::string tempstr(psave, p + 1);    m_strValue += tempstr;    return p - pch + 1;}uint64_t BencodeString::Encode(char* pch, size_t len){	char* p, dt[64];	int n;	p = pch;	n = m_strValue.length();	snprintf(dt, 64, "%d", n);	//itoa(n, dt, 10);	memcpy(p, dt, strlen(dt));	p += strlen(dt);	*p++ = ':';	memcpy(p, m_strValue.c_str(), n);	p += n;	return p - pch;}BencodeString::~BencodeString(){}size_t BencodeList::Decode(char *pch, size_t len){    char *p = pch + 1;    size_t n;    Bencode *pnew;    len--;    while (*p != END_DELIMITER && len) {	switch (*p) {	case 'i':	    pnew = new BencodeInt;	    break;	case 'l':	    pnew = new BencodeList;	    break;	case 'd':	    pnew = new BencodeDict;	    break;	default:	    pnew = new BencodeString;	}	n = pnew->Decode(p, len);	m_list.push_back(pnew);	p += n;	len -= n;    }    return (size_t) (p - pch + 1);}uint64_t BencodeList::Encode(char* pch, size_t len){	char *p;	std::vector < Bencode * >::iterator iter;	std::vector < Bencode * >::iterator iter_end;	p = pch;	iter = m_list.begin();	iter_end = m_list.end();    *p++ = 'l';	for(; iter != iter_end; iter++)	{		size_t nfeed;		nfeed = (*iter)->Encode(p, len - (p - pch));		p += nfeed;	}	*p++ = 'e';		return p - pch;	}BencodeList::~BencodeList(){    std::vector < Bencode * >::iterator iter;    std::vector < Bencode * >::iterator iter_end;    iter = m_list.begin();    iter_end = m_list.end();    for (; iter != iter_end; iter++)	delete *iter;}size_t BencodeDict::Decode(char *pch, size_t len){    char *p = pch + 1;    size_t n;    BencodeString *pstr;    Bencode *pnew;    len--;    while (*p != END_DELIMITER && len) {	pstr = new BencodeString;	n = pstr->Decode(p, len);	p += n;	len -= n;		switch (*p) {	case 'i':	    pnew = new BencodeInt;	    break;	case 'l':	    pnew = new BencodeList;	    break;	case 'd':	    pnew = new BencodeDict;	    break;	default:	    pnew = new BencodeString;	}	n = pnew->Decode(p, len);	p += n;	len -= n;	m_map.insert(std::map < std::string,		     Bencode * >::value_type(pstr->m_strValue, pnew));	delete pstr;    }    return (size_t) (p - pch + 1);}uint64_t BencodeDict::Encode(char* pch, size_t len){	char *p = pch;	std::map<string, Bencode*>::iterator iter, iter_end;	iter = m_map.begin();	iter_end = m_map.end();	*p++ = 'd';	for(;iter != iter_end; )	{		size_t nfeed;				int slen;		char dt[64];		slen = (*iter).first.length();		snprintf(dt, 64, "%d", slen);		memcpy(p, dt, strlen(dt));		p += strlen(dt);		*p++ = ':';		memcpy(p, (*iter).first.c_str(), slen);		p += slen;			nfeed = (*iter).second->Encode(p, len -(p - pch));		p += nfeed;		iter++;				}	*p++ = 'e';	return (p - pch);}Bencode *BencodeDict::Search(std::string & keylist){    Bencode *ret = NULL;    std::string::size_type pos = 0;    std::map < std::string, Bencode * >::iterator iter;    std::map < std::string, Bencode * >::iterator iter_end;    iter = m_map.begin();    iter_end = m_map.end();    pos = keylist.find_first_of('|', pos);    if (std::string::npos == pos) {	while (iter != iter_end) {	    if (keylist == (*iter).first)		return ret = (*iter).second;	    iter++;	}    }    else {	while (iter != iter_end) {	    Bencode *pcode = (*iter).second;	    iter++;	    if (bencode_dict != pcode->m_enumType)		continue;	    keylist.erase(0, pos + 1);	    if (NULL != (ret = ((BencodeDict *) pcode)->Search(keylist)))		return ret;	}    }    return ret;}BencodeDict::~BencodeDict(){    std::map < std::string, Bencode * >::iterator iter;    std::map < std::string, Bencode * >::iterator iter_end;    iter = m_map.begin();    iter_end = m_map.end();    for (; iter != iter_end; iter++)	delete(*iter).second;}void BencodeInt::printout(){    std::cout << m_nValue << std::endl;} void BencodeString::printout(){    std::cout << m_strValue << std::endl;}void BencodeList::printout(){    std::vector < Bencode * >::iterator iter;    std::vector < Bencode * >::iterator iter_end;    iter = m_list.begin();    iter_end = m_list.end();		cout<<"########################list#########################"<<endl;    while (iter_end != iter) {	(*iter)->printout();	iter++;    }		cout<<"########################list-end#####################"<<endl;}void BencodeDict::printout(){    std::map < std::string, Bencode * >::iterator iter;    std::map < std::string, Bencode * >::iterator iter_end;    iter = m_map.begin();    iter_end = m_map.end();	cout<<"**********************dictionary*********************"<<endl;    while (iter_end != iter) {	cout << (*iter).first << endl;	(*iter).second->printout();	iter++;    }	cout<<"********************dictionary-end*******************"<<endl;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -