From 13f84119c52f67137f96daa3639772756271b927 Mon Sep 17 00:00:00 2001 From: yhoogstrate Date: Fri, 2 Aug 2019 10:48:09 +0200 Subject: [PATCH] Appropriate file naming when mounting 2bit files + release notes --- CMakeLists.txt | 2 +- Changelog | 6 ++++++ src/fuse.cpp | 33 +++++++++++++++------------------ src/ucsc2bit.cpp | 16 ++++++++-------- 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 520e0a32..99abc2a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ project(fastafs) # Do this once in a while - find different bugs #set(CMAKE_CXX_COMPILER "clang++") -set(PROJECT_VERSION "1.4.0") +set(PROJECT_VERSION "1.5.0") set(PACKAGE_URL "https://github.com/yhoogstrate/fastafs") set(PACKAGE_BUGREPORT "${PACKAGE_URL}/issues") diff --git a/Changelog b/Changelog index 027edf58..6768af3a 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,9 @@ +2019-08-02 Youri Hoogstrate + + * v1.5.0 + * Support mounting 2bit files (without FASTAFS file(s)) + - Requires c++-17 for several std::filesystem calls + 2019-06-05 Youri Hoogstrate * Changed SHA1 to MD5 hashes for BAM compatibility diff --git a/src/fuse.cpp b/src/fuse.cpp index 8e0f28c9..c34c241f 100644 --- a/src/fuse.cpp +++ b/src/fuse.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "fuse.hpp" @@ -75,7 +76,7 @@ static int do_getattr(const char *path, struct stat *st) } else { st->st_mode = S_IFREG | 0644; st->st_nlink = 1; - + if(ffi->from_fastafs) { if(ffi->f != nullptr) { printf("\033[0;32m[%s]\033[0;33m do_getattr:\033[0m %s \033[0;35m(fastafs: %s, padding: %u)\033[0m\n", cur_time, path, ffi->f->name.c_str(), ffi->padding); @@ -95,8 +96,7 @@ static int do_getattr(const char *path, struct stat *st) st->st_size = ffi->f->dict_filesize(); } } - } - else { + } else { if(ffi->u2b != nullptr) { printf("\033[0;32m[%s]\033[0;33m do_getattr:\033[0m %s \033[0;35m(fastafs: %s, padding: %u)\033[0m\n", cur_time, path, ffi->u2b->name.c_str(), ffi->padding); @@ -142,14 +142,13 @@ static int do_readdir(const char *path, void *buffer, fuse_fill_dir_t filler, of filler(buffer, virtual_ucsc2bit_filename.c_str(), NULL, 0); filler(buffer, virtual_dict_filename.c_str(), NULL, 0); } - } - else { + } else { if(ffi->u2b != nullptr) { printf("\033[0;32m[%s]\033[0;33m 2bit::do_readdir(\033[0moffset=%u\033[0;33m):\033[0m %s \033[0;35m(fastafs: %s, padding: %u)\033[0m\n", cur_time, (uint32_t) offset, path, ffi->u2b->name.c_str(), ffi->padding); std::string virtual_fasta_filename = ffi->u2b->name + ".fa"; std::string virtual_faidx_filename = ffi->u2b->name + ".fa.fai"; - + if(strcmp(path, "/") == 0) { // If the user is trying to show the files/directories of the root directory show the following filler(buffer, virtual_fasta_filename.c_str(), NULL, 0); filler(buffer, virtual_faidx_filename.c_str(), NULL, 0); @@ -188,8 +187,7 @@ static int do_read(const char *path, char *buffer, size_t size, off_t offset, st } else if(strcmp(path, virtual_dict_filename.c_str()) == 0) { written = (signed int) ffi->f->view_dict_chunk(buffer, size, offset); } - } - else { + } else { if(ffi->u2b != nullptr) { printf("\033[0;32m[%s]\033[0;33m 2bit::do_read(\033[0msize=%u, offset=%u\033[0;33m):\033[0m %s \033[0;35m(fastafs: %s, padding: %u)\033[0m\n", cur_time, (uint32_t) size, (uint32_t) offset, path, ffi->u2b->name.c_str(), ffi->padding); @@ -339,7 +337,7 @@ fuse_instance *parse_args(int argc, char **argv, char **argv_fuse) //char **argv_test = (char **) malloc(sizeof(char*) * argc); //fastafs_fuse_instance *ffi = new fastafs_fuse_instance({nullptr, 60, 1, new char[argc]}); //fastafs_fuse_instance *ffi = new fastafs_fuse_instance({nullptr, 60, 0, nullptr}); - + fuse_instance *fi = new fuse_instance({nullptr, nullptr, true, nullptr, 60, 0}); //printf("argc=%i",argc); @@ -362,20 +360,18 @@ fuse_instance *parse_args(int argc, char **argv, char **argv_fuse) //argv_test[fi->argc_fuse] = argv[i]; argv_fuse[fi->argc_fuse++] = argv[i]; } - } - else if(i < argc - 2) { // all arguments that one argument "--lowercase" switches etc + } else if(i < argc - 2) { // all arguments that one argument "--lowercase" switches etc if(strcmp(argv[i], "-2") == 0 or strcmp(argv[i], "--2bit") == 0) { fi->from_fastafs = false; } else { // arguments that need to be send to fuse //argv_test[fi->argc_fuse] = argv[i]; argv_fuse[fi->argc_fuse++] = argv[i]; } - } - else if(i == argc - 2) { // this refers to the fastafs object + } else if(i == argc - 2) { // this refers to the fastafs object if(fi->from_fastafs) { database d = database(); std::string fname = d.get(argv[i]); - + if(fname.size() == 0) { // invalid mount argument, don't bind fastafs object print_fuse_help(); exit(1); @@ -385,9 +381,10 @@ fuse_instance *parse_args(int argc, char **argv, char **argv_fuse) fi->cache = fi->f->init_ffs2f(fi->padding, true);// allow mixed case } - } - else { - fi->u2b = new ucsc2bit("from-2bit"); + } else { + std::string basename = std::filesystem::path(std::string(argv[i])).filename(); + + fi->u2b = new ucsc2bit(basename);// useses basename as prefix for filenames to mount: hg19.2bit -> hg19.2bit.fa fi->u2b->load(std::string(argv[i])); } } else { // mountpoint @@ -410,7 +407,7 @@ void fuse(int argc, char *argv[]) // - @todo at some point define that second mount is not really important? if possible char *argv2[argc]; fuse_instance *ffi = parse_args(argc, argv, argv2); - + // part 2 - print what the planning is char cur_time[100]; time_t now = time(0); diff --git a/src/ucsc2bit.cpp b/src/ucsc2bit.cpp index 087e23d5..39a6479a 100644 --- a/src/ucsc2bit.cpp +++ b/src/ucsc2bit.cpp @@ -451,17 +451,17 @@ std::string ucsc2bit::get_faidx(uint32_t padding) //std::ifstream file(this->filename.c_str(), std::ios::in | std::ios::binary | std::ios::ate); //if(file.is_open()) { // file.close(); - uint32_t offset = 0; + uint32_t offset = 0; - for(size_t i = 0; i < this->data.size(); i++) { - offset += 1;// '>' - offset += (uint32_t) this->data[i]->name.size() + 1; // "chr1\n" + for(size_t i = 0; i < this->data.size(); i++) { + offset += 1;// '>' + offset += (uint32_t) this->data[i]->name.size() + 1; // "chr1\n" - contents += data[i]->name + "\t" + std::to_string(this->data[i]->n) + "\t" + std::to_string(offset) + "\t" + padding_s + "\t" + padding_s2 + "\n"; + contents += data[i]->name + "\t" + std::to_string(this->data[i]->n) + "\t" + std::to_string(offset) + "\t" + padding_s + "\t" + padding_s2 + "\n"; - offset += this->data[i]->n; // ACTG NNN - offset += (this->data[i]->n + (padding - 1)) / padding;// number of newlines corresponding to ACTG NNN lines - } + offset += this->data[i]->n; // ACTG NNN + offset += (this->data[i]->n + (padding - 1)) / padding;// number of newlines corresponding to ACTG NNN lines + } //} else { // throw std::runtime_error("[ucsc2bit::get_faidx] could not load ucsc2bit: " + this->filename); //}