};
ssize_t file_bencode(struct file*,uint8_t*,size_t);
+int file_equals(struct file*,struct file*);
void file_free(struct file*);
int file_hash(struct file*,int);
int file_init(struct file**,const char*);
#include<opt.h>
#include<tree.h>
+struct torrent_files {
+ struct hash_map *paths;
+ struct hash_map *roots;
+};
+
struct torrent {
char *root;
char *name;
unsigned long long piece_length;
struct tree *tree;
- struct hash_map *files;
+ struct torrent_files *files;
int watch_fd;
};
return buf_len-len;
}
+int file_equals(struct file *a, struct file *b) {
+ if((NULL==a)&&(b!=NULL)) { return -1; }
+ if((NULL==b)&&(a!=NULL)) { return -1; }
+
+ if(strcmp(a->name,b->name)!=0) { return -1; }
+ if(strcmp(a->path,b->path)!=0) { return -1; }
+
+ if(memcmp(a->root,b->root,crypto_hash_sha256_BYTES)!=0) { return -1; }
+
+ return 1;
+}
+
void file_free(struct file *p) {
if(NULL==p) { return; }
static int torrent_add_file(struct torrent *p, struct file *f) {
int i;
- while(
- ((i = torrent_add_file_by_root(p->files,f))<=0) ||
- ((i = torrent_add_file_by_path(p->files,f))<=0)
- ) {
+ while((i = torrent_add_file_by_root(p->files,f))<=0) {
+ if(i<0) { return -1; }
+ if(torrent_files_resize(p,p->files->size<<1)<0) { return -1; }
+ }
+
+ while((i = torrent_add_file_by_path(p->files,f))<=0) {
if(i<0) { return -1; }
-
if(torrent_files_resize(p,p->files->size<<1)<0) { return -1; }
}
if(i<0) { return -1; }
p = hashmap_find(files,f->path,strlen(f->path));
- if(p!=NULL) { return 0; }
+ if((p!=NULL)&&(file_equals(f,p)<1)) { return 0; }
}
return 1;
if(i<0) { return -1; }
p = hashmap_find(files,f->root,crypto_hash_sha256_BYTES);
- if(p!=NULL) { return 0; }
+ if((p!=NULL)&&(file_equals(f,p)<1)) { return 0; }
}
return 1;
static int torrent_files_resize(struct torrent *torrent_p, size_t new_size) {
struct file *p;
struct hash_map *new, *old;
- int ret;
+ int ret1, ret2;
if(hashmap_init(&new,new_size)<0) { return -1; }
for(size_t i=0;i<torrent_p->files->size;i++) {
p = torrent_p->files->map[i];
+ /*
+ * cases:
+ * 1.) p = NULL
+ * 2.) p = added by torrent_add_file_by_root, not already added
+ * 3.) p = added by torrent_add_file_by_path, not already added
+ * 4.) p = added by torrent_add_file_by_root, already added
+ * 5.) p = added by torrent_add_file_by_path, already added
+ */
if(p!=NULL) {
- if((ret = torrent_add_file_by_root(new,p))<=0) {
- if(ret<0) { return -1; }
- goto resize;
+ found = hashmap_find(torrent_p->files,p->path,strlen(p->path));
+ if(
+ if((ret1 = torrent_add_file_by_root(new,p))<=0) {
+ if(ret1<0) { goto clean; }
+ printf("%s already found [root]\n",p->name);
}
-
- if(ret==0) {
- if((ret = torrent_add_file_by_path(new,p))<=0) { goto resize; }
+ if((ret2 = torrent_add_file_by_path(new,p))<=0) {
+ if(ret2<0) { goto clean; }
+ printf("%s already found [path]\n",p->name);
}
+
+ if((!ret1)&&(!ret2)) { goto resize; }
+ }
+ }
+
+ printf("after\n");
+ for(size_t i=0;i<new->size;i++) {
+ p = new->map[i];
+ printf("%lu: ",i);
+ if(p==NULL) {
+ printf("NULL\n");
+ } else {
+ printf("%s\n",p->name);
}
}
return 1;
resize:
- if(ret<0) { return -1; }
hashmap_clear(new);
hashmap_free(new);
+ printf("resizing to %lu\n",new_size<<1);
return torrent_files_resize(torrent_p,new_size<<1);
+clean:
+ hashmap_clear(new);
+ hashmap_free(new);
+ return -1;
}
int main();
static void torrent_add_basic_test();
+static void torrent_file_info_basic_test();
+static void torrent_file_path_basic_test();
static void torrent_init_basic_test();
static void torrent_magnet_basic_test();
+static void torrent_setup_example(struct torrent**);
int main() {
setup_env();
torrent_init_basic_test();
torrent_add_basic_test();
torrent_magnet_basic_test();
+ torrent_file_info_basic_test();
+ torrent_file_path_basic_test();
clean_env();
struct torrent *torrent;
struct file *file1, *file2, *file3, *file4, *p;
-// for(size_t i=0;i<100;i++) {
+ for(size_t i=0;i<100;i++) {
assert(file_init(&file1,TEST_FILE_1)==1);
memset(file1->root,1,crypto_hash_sha256_BYTES);
assert(file_init(&file2,TEST_FILE_2)==1);
assert(p==file4);
torrent_free(torrent);
+ }
+}
+
+static void torrent_file_info_basic_test() {
+ struct torrent *torrent;
+
+ torrent_setup_example(&torrent);
+
+ torrent_free(torrent);
+}
- reset_env();
-// }
+static void torrent_file_path_basic_test() {
+ struct torrent *torrent;
+
+ torrent_setup_example(&torrent);
+
+ torrent_free(torrent);
}
static void torrent_init_basic_test() {
torrent_free(torrent);
}
+
static void torrent_magnet_basic_test() {
struct torrent *torrent;
- struct file *file1, *file2;
char *p;
- assert(file_init(&file1,TEST_FILE_1)==1);
- memset(file1->root,1,crypto_hash_sha256_BYTES);
- assert(file_init(&file2,TEST_FILE_2)==1);
- memset(file2->root,2,crypto_hash_sha256_BYTES);
-
- assert(torrent_init(&torrent,TEST_DIRECTORY,TEST_DIRECTORY,16384)==1);
-
- assert(torrent_add(torrent,file1)==1);
- assert(torrent_add(torrent,file2)==1);
+ torrent_setup_example(&torrent);
p = torrent_magnet(torrent);
assert(p!=NULL);
reset_env();
}
+
+static void torrent_setup_example(struct torrent **p) {
+ struct file *file1, *file2;
+
+ assert(file_init(&file1,TEST_FILE_1)==1);
+ memset(file1->root,1,crypto_hash_sha256_BYTES);
+ assert(file_init(&file2,TEST_FILE_2)==1);
+ memset(file2->root,2,crypto_hash_sha256_BYTES);
+
+ assert(torrent_init(p,TEST_DIRECTORY,TEST_DIRECTORY,16384)==1);
+
+ assert(torrent_add(*p,file1)==1);
+ assert(torrent_add(*p,file2)==1);
+}