void FS::copy(FileDescriptor src_file, FileDescriptor & dst_fold, std::string dst_filename){ Block * src_block = new Block(src_file.first_block, config.block_size, _root); read_data(&src_file, sizeof(FileDescriptor), src_block); char * data = new char[src_file.size]; read_data(data, src_file.size, src_block); FileDescriptor file; Block * file_block = get_free_block(); write_data(&file, sizeof(FileDescriptor), file_block); write_data(data, src_file.size, file_block); Block * dst_block = new Block(dst_fold.first_block, config.block_size, _root); bool found = false; for(auto it = DirIterator(*this, dst_fold); it != DirIterator(*this); ++it){ FileDescriptor f = *it; if (std::string(f.filename) == dst_filename ){ if( f.directory){ found = true; dst_fold = f; dst_block = new Block(dst_fold.first_block, config.block_size, _root); } else{ throw std::runtime_error("File already exist"); } } } file.first_block = file_block->get_index(); if(!found){ file.set_filename(dst_filename); } else{ file.set_filename(src_file.filename); } file.parent_file = dst_fold.first_block; file.size = src_file.size; file.directory = src_file.directory; if(dst_fold.first_child != -1){ Block * nb = new Block(dst_fold.first_child, config.block_size, _root); FileDescriptor nd; read_data(&nd, sizeof(FileDescriptor), nb); nd.prev_file = file.first_block; update_descriptor(nd,nb); file.next_file = nd.first_block; } dst_fold.first_child = file.first_block; update_descriptor(dst_fold, dst_block); update_descriptor(file, file_block); if(src_file.directory){ for(auto it = DirIterator(*this, src_file); it != DirIterator(*this); ++it){ FileDescriptor f = *it; copy(f, file, f.filename); } } }
void FS::import(std::string host_file, std::string fs_file){ if (!initialized) {throw "Not initialized";} read_meta(); if(fs_file[fs_file.size() - 1] == '/'){ fs_file = fs_file.substr(0, fs_file.size() - 1); } int last_match = fs_file.find_last_of("/"); std::string fs_file_path = fs_file.substr(0, last_match + 1); std::string fs_file_name = fs_file.substr(last_match + 1); FileDescriptor dst_fold = get_file(fs_file_path, false, false); Block * dst_block = new Block(dst_fold.first_block, config.block_size, _root); for(auto it = DirIterator(*this, dst_fold); it != DirIterator(*this); ++it){ FileDescriptor file = *it; if (std::string(file.filename) == fs_file_name ) throw std::runtime_error("File already exist"); } FileDescriptor file; Block * file_block = get_free_block(); std::ifstream File (host_file, std::ios::in | std::ios::binary); if( File.fail() ) throw std::runtime_error("Can't open " + host_file); File.seekg( 0, std::ios::end ); int fileLen = File.tellg(); file.size = fileLen; File.seekg( 0, std::ios::beg); char * data = new char[fileLen]; File.read(data, fileLen); if(File.fail()) throw std::runtime_error("Can't read file " + host_file); File.close(); write_data(&file, sizeof(FileDescriptor), file_block); write_data(data, fileLen, file_block); file.directory = false; file.set_filename(fs_file_name); file.first_block = file_block->get_index(); file.parent_file = dst_fold.first_block; file.prev_file = -1; file.next_file = -1; if(dst_fold.first_child != -1){ Block * nb = new Block(dst_fold.first_child, config.block_size, _root); FileDescriptor nd; read_data(&nd, sizeof(FileDescriptor), nb); nd.prev_file = file.first_block; update_descriptor(nd,nb); file.next_file = nd.first_block; } dst_fold.first_child = file.first_block; update_descriptor(dst_fold, dst_block); update_descriptor(file, file_block); write_meta(); }
void FS::format(){ if (!initialized) {throw "Not initialized";} meta.block_map_size = config.block_no/8 + 1; meta.block_map = new char[meta.block_map_size]; memset(meta.block_map, 0, sizeof(char)*meta.block_map_size); int free_space_size = config.block_size - sizeof(BlockDescriptor); int no_of_blocks = (sizeof(meta) + meta.block_map_size)/free_space_size + 1; meta.root_block = no_of_blocks; for(int i = 0; i<no_of_blocks; ++i) reserve_block(i); FileDescriptor root; root.set_filename("/"); root.first_block = meta.root_block; write_data(&root, sizeof(FileDescriptor), 0); write_meta(); }
FileDescriptor FS::get_file(std::string path, bool create, bool file_available){ if( path[path.size() - 1] != '/' ){ path.push_back('/'); } int pos; pos = path.find('/'); if (pos != 0){ throw std::runtime_error("Bad path"); } path.erase(0, 1); FileDescriptor curr_dir; Block * curr_dir_block = new Block(meta.root_block, config.block_size, _root); read_data(&curr_dir, sizeof(curr_dir), curr_dir_block); while(path.size() != 0){ pos = path.find('/'); std::string dir_name = path.substr(0, pos); bool found = false; for(auto it = DirIterator(*this, curr_dir); it != DirIterator(*this); ++it){ FileDescriptor file = *it; if(std::string(file.filename) == dir_name){ found = true; if(!file.directory){ if(file_available && pos == (int)path.size() - 1){ return file; }else{ throw std::runtime_error("File in path"); } } curr_dir = file; } } if(!found){ if( create ){ Block * dir_block = get_free_block(); FileDescriptor dir; dir.set_filename(dir_name); dir.first_block = dir_block->get_index(); dir.parent_file = curr_dir.first_block; if( curr_dir.first_child == -1 ){ curr_dir.first_child = dir.first_block; } else{ Block * neighbour_file_block = new Block(curr_dir.first_child, config.block_size, _root); curr_dir.first_child = dir.first_block; FileDescriptor neighbour_file_descriptor; read_data(&neighbour_file_descriptor, sizeof(FileDescriptor), neighbour_file_block); dir.next_file = neighbour_file_descriptor.first_block; neighbour_file_descriptor.prev_file = dir.first_block; update_descriptor(neighbour_file_descriptor, neighbour_file_block); } update_descriptor(curr_dir, curr_dir_block); curr_dir = dir; write_data(&dir, sizeof(FileDescriptor), dir_block); } else{ throw std::runtime_error("No such file or directory"); } } curr_dir_block = new Block(curr_dir.first_block, config.block_size, _root); path.erase(0, pos + 1); } return curr_dir; }