?? btfiles.cpp
字號:
#include "Btfiles.h"#include <unistd.h>#include <limits.h>#include <fcntl.h>#include <iostream.h>using namespace std;#ifndef PATH_MAX#define PATH_MAX 255#endif#ifndef DEBUG#define DEBUG(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)#endifbtFiles::btFiles(){ m_head = NULL; m_totallength = 0; m_dirctory = NULL;}btFiles::~btFiles(){ btfile *p = m_head, *q; for (; p;) { delete p->path; q = p->next; delete p; p = q; } m_head = NULL; m_totallength = 0; delete m_dirctory;}btfile *btFiles::new_node(){ return new btfile;}int btFiles::open_file(btfile * bf){ char fullpath[PATH_MAX]; snprintf(fullpath, PATH_MAX, "%s%c%s", m_dirctory, '/', bf->path); if (NULL != bf->fp) return 0; if (NULL == fullpath || NULL == (bf->fp = fopen(fullpath, "r+"))) return -1; DEBUG("open file %s successfully\n", fullpath); return 0;}ssize_t btFiles::IO(char *buf, uint64_t off, size_t len, bool in){ btfile *p = m_head; off_t l = 0, pos; if (!buf || ((off + len) >= m_totallength)) return -1; if (!len) return 0; for (; p && ((l += p->length) <= off); p = p->next); if (!p) return -1; pos = p->length - (l - off); for (; p && len;) { if (NULL == p->fp) { if (open_file(p) < 0) return -1; } if (fseek(p->fp, pos, SEEK_SET) < 0) return -1; l = len > (p->length - pos) ? p->length - pos : len; if (in) { if (1 != fwrite(buf, l, 1, p->fp)) return -1; fflush(p->fp); } else { if (1 != fread(buf, l, 1, p->fp)) return -1; } len -= l; buf += l; p = p->next; pos = 0; } if (NULL == p) return -1; return 0;}int btFiles::allocate_disk(int fd, uint64_t len){ if (0 == len) return 0; if (ftruncate(fd, len) < 0) { char c = '\0'; if (lseek(fd, len - 1, SEEK_SET) < 0) return -1; if (write(fd, &c, 1) < 0) return -1; } return 0;}int btFiles::BuildFromMI(Bencode * pdict){ btfile **pbf = &m_head; if (NULL == pdict || bencode_dict != pdict->m_enumType) return -1; std::string str = "info|name"; Bencode *pcode = query_dict(pdict, str); if (NULL == pcode || bencode_str != pcode->m_enumType) return -1; m_dirctory = new char[((BencodeString *) pcode)->m_strValue.length() + 1]; strcpy(m_dirctory, ((BencodeString *) pcode)->m_strValue.c_str()); str = "info|files"; pcode = query_dict(pdict, str); if (pcode) { if (pcode->m_enumType != bencode_list) return -1; std::vector < Bencode * >::iterator iter = ((BencodeList *) pcode)->m_list.begin(); std::vector < Bencode * >::iterator iter_end = ((BencodeList *) pcode)->m_list.end(); while (iter != iter_end) { Bencode *p; std::string keylist("path"); char pathname[PATH_MAX]; uint64_t len = 0; if ((*iter)->m_enumType != bencode_dict) return -1; if (NULL == (p = query_dict(*iter, keylist))) return -1; if (0 > list2path(p, pathname)) return -1; keylist = "length"; if (NULL == (p = query_dict(*iter, keylist))) return -1; if (p->m_enumType != bencode_int) return -1; len = ((BencodeInt *) p)->m_nValue; m_totallength += len; btfile *pnode = new btfile; pnode->path = new char[strlen(pathname) + 1]; strcpy(pnode->path, pathname); pnode->length = len; iter++; pnode->next = *pbf; *pbf = pnode; pbf = &pnode->next; } } else { } return 0;}int btFiles::list2path(Bencode * plist, char *path){ char *p = path; if (!plist || bencode_list != plist->m_enumType) return -1; if (NULL == path) return 0; std::vector < Bencode * >::iterator iter = ((BencodeList *) plist)->m_list.begin(); std::vector < Bencode * >::iterator iter_end = ((BencodeList *) plist)->m_list.end(); while (iter != iter_end) { if (bencode_str != (*iter)->m_enumType) return -1; BencodeString *pstr = (BencodeString *) (*iter); int len = pstr->m_strValue.length(); memcpy(p, pstr->m_strValue.c_str(), len); p += len; *p++ = '/'; iter++; } p--; *p = '\0'; return 0;}int btFiles::CreateFiles(){ btfile *p = m_head; while (p) { if (0 > build_file(p->path, p->length)) cout << "can't create the file:" << p->path << endl; p = p->next; } return 0;}int btFiles::build_file(const char *pathname, uint64_t length){ char path[PATH_MAX], *p; struct stat sb; int fd; if (snprintf(path, PATH_MAX, "%s%c%s", m_dirctory, '/', pathname) < 0) return -1; p = path; for (; *p;) { for (; p && *p && *p != '/'; p++); if ('/' == *p) { *p = '\0'; if (stat(path, &sb) < 0) if (mkdir(path, 0755) < 0) return -1; *p++ = '/'; } else { if (stat(path, &sb) < 0) if (0 > (fd = creat(path, 0644)) || allocate_disk(fd, length) < 0) return -1; close(fd); } } return 0;}void btFiles::printout(){ btfile *pbf = m_head; cout << "total size is:" << m_totallength << endl; for (; pbf; pbf = pbf->next) cout << pbf->path << endl << pbf->length << endl;}/*int main(){ Bencode *pdict = create_dictionary("ab.TORRENT"); if (NULL == pdict) { cout << "can't create the dictionary" << endl; exit(0); } btFiles bf; bf.BuildFromMI(pdict); if (0 > bf.CreateFiles()) cout << "create file failed" << endl; delete_dictionary(pdict); return 0;}*/
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -