about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRichard Nyberg <rnyberg@murmeldjur.se>2006-01-04 12:16:31 +0000
committerRichard Nyberg <rnyberg@murmeldjur.se>2006-01-04 12:16:31 +0000
commit56320bce47b210f45d0bda8da920568ce16fba47 (patch)
treea608ea183d906a3e56004d4fb8dd2183197ce524
parent0cbe0770981ba4e4dab6b85f8f2155dfcccf228d (diff)
downloadbtpd-56320bce47b210f45d0bda8da920568ce16fba47.tar.gz
btpd-56320bce47b210f45d0bda8da920568ce16fba47.zip
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.

-rw-r--r--btpd/content.c132
-rw-r--r--btpd/content.h25
2 files changed, 157 insertions, 0 deletions
diff --git a/btpd/content.c b/btpd/content.c
new file mode 100644
index 0000000..25b3f6f
--- /dev/null
+++ b/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;
+}
diff --git a/btpd/content.h b/btpd/content.h
new file mode 100644
index 0000000..fa02877
--- /dev/null
+++ b/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