瀏覽代碼

New api for managing the content of a torrent. It'll keep track of which

pieces we and blocks we have, it'll do the writing and reading from disk
and test pieces against their hashes.
This is only a dummy implementation of the api. I'll flesh it out in
subsequent commits.
master
Richard Nyberg 19 年之前
父節點
當前提交
56320bce47
共有 2 個文件被更改,包括 157 次插入0 次删除
  1. +132
    -0
      btpd/content.c
  2. +25
    -0
      btpd/content.h

+ 132
- 0
btpd/content.c 查看文件

@@ -0,0 +1,132 @@
#include <math.h>

#include "btpd.h"

struct content {
uint32_t npieces;
uint8_t *piece_field;

uint64_t nblocks;
uint8_t *block_field;

uint32_t *piece_map;

struct event done;
};

void
done_cb(int fd, short type, void *arg)
{
struct torrent *tp = arg;
if (tp->state == T_STARTING)
torrent_cm_cb(tp, CM_STARTED);
else
torrent_cm_cb(tp, CM_STOPPED);
}

int
cm_start(struct torrent *tp)
{
size_t mem =
sizeof(struct content)
+ sizeof(uint32_t) * tp->meta.npieces
+ ceil(tp->meta.npieces / 8.0)
+ tp->meta.npieces * ceil(tp->meta.piece_length / (double)(1 << 17));

tp->cp = btpd_calloc(mem, 1);
tp->cp->piece_map = (uint32_t *)(tp->cp + 1);
tp->cp->piece_field = (uint8_t *)(tp->cp->piece_map + tp->meta.npieces);
tp->cp->block_field = tp->cp->piece_field
+ (size_t)ceil(tp->meta.npieces / 8.0);

evtimer_set(&tp->cp->done, done_cb, tp);
evtimer_add(&tp->cp->done, (& (struct timeval) { 0, 0 }));

return 0;
}

void
cm_stop(struct torrent *tp)
{
evtimer_add(&tp->cp->done, (& (struct timeval) { 0, 0 }));
}

int
cm_full(struct torrent *tp)
{
return tp->cp->npieces == tp->meta.npieces;
}

uint8_t *
cm_get_piece_field(struct torrent *tp)
{
return tp->cp->piece_field;
}

uint8_t *
cm_get_block_field(struct torrent *tp, uint32_t piece)
{
return tp->cp->block_field +
piece * (size_t)ceil(tp->meta.piece_length / (double)(1 << 17));
}

int
cm_has_piece(struct torrent *tp, uint32_t piece)
{
return has_bit(tp->cp->piece_field, piece);
}

int
cm_put_block(struct torrent *tp, uint32_t piece, uint32_t block,
const char *data)
{
set_bit(tp->cp->block_field +
piece * (size_t)ceil(tp->meta.piece_length / (double)(1 << 17)),
block);
tp->cp->nblocks++;
return 0;
}

int
cm_get_bytes(struct torrent *tp, uint32_t piece, uint32_t begin, size_t len,
char **buf)
{
*buf = btpd_malloc(len);
return 0;
}

struct test {
struct piece *pc;
struct event test;
};

static
void test_cb(int fd, short type, void *arg)
{
struct test *t = arg;
set_bit(t->pc->tp->cp->piece_field, t->pc->index);
t->pc->tp->cp->npieces++;
dl_on_ok_piece(t->pc);
free(t);
}

void
cm_test_piece(struct piece *pc)
{
struct test *t = btpd_calloc(1, sizeof(*t));
t->pc = pc;
evtimer_set(&t->test, test_cb, t);
evtimer_add(&t->test, (& (struct timeval) { 0 , 0 }));
}

uint32_t
cm_get_npieces(struct torrent *tp)
{
return tp->cp->npieces;
}

off_t
cm_bytes_left(struct torrent *tp)
{
return cm_full(tp) ? 0 : tp->meta.total_length;
}

+ 25
- 0
btpd/content.h 查看文件

@@ -0,0 +1,25 @@
#ifndef BTPD_CONTENT_H
#define BTPD_CONTENT_H

int cm_start(struct torrent *tp);
void cm_stop(struct torrent * tp);

int cm_full(struct torrent *tp);

uint8_t *cm_get_piece_field(struct torrent *tp);
uint8_t *cm_get_block_field(struct torrent *tp, uint32_t piece);

uint32_t cm_get_npieces(struct torrent *tp);

int cm_has_piece(struct torrent *tp, uint32_t piece);

int cm_put_block(struct torrent *tp, uint32_t piece, uint32_t block,
const char *buf);
int cm_get_bytes(struct torrent *tp, uint32_t piece, uint32_t begin,
size_t len, char **buf);

void cm_test_piece(struct piece *pc);

off_t cm_bytes_left(struct torrent *tp);

#endif

Loading…
取消
儲存