void RDirNode::addNode(RDirNode* node) { // does this node prefix any other nodes, if so, add them to it std::vector<RDirNode*> matches; std::string path = node->getPath(); //debugLog("adding node %s to %s\n", path.c_str(), abspath.c_str()); for(std::list<RDirNode*>::iterator it = children.begin(); it != children.end(); ) { RDirNode* child = (*it); if(child->prefixedBy(path)) { it = children.erase(it); node->addNode(child); } else { it++; } } // add to this node children.push_back(node); node->setParent(this); //debugLog("added node %s to %s\n", node->getPath().c_str(), getPath().c_str()); nodeUpdated(false); }
bool RDirNode::addFile(RFile* f) { //doesnt match this path at all if(f->path.find(abspath) != 0) { if(parent!=0) return false; RDirNode* newparent; std::string common = commonPathPrefix(f->path); if(common.size()==0) common = "/"; newparent = new RDirNode(0, common); newparent->addNode(this); return newparent->addFile(f); } //simply change path of node and add this to it if( parent==0 && abspath == "/" && f->path.compare(abspath) != 0 && fileCount()==0 && dirCount()==0) { debugLog("modifying root path to %s\n", f->path.c_str()); changePath(f->path); } //is this dir - add to this node if(f->path.compare(abspath) == 0) { //debugLog("addFile %s to %s\n", f->fullpath.c_str(), abspath.c_str()); files.push_back(f); if(!f->isHidden()) visible_count++; f->setDir(this); fileUpdated(false); return true; } //does this belong to one of the children ? for(std::list<RDirNode*>::iterator it = children.begin(); it != children.end(); it++) { RDirNode* child = (*it); bool added = child->addFile(f); if(added) return true; } //add new child, add it to that //if commonpath is longer than abspath, add intermediate node, else just add at the files path RDirNode* node = new RDirNode(this, f->path); node->addFile(f); addNode(node); // do we have dir nodes, with a common path element greater than abspath, // if so create another node, and move those nodes there std::string commonpath; vec2f commonPos; for(std::list<RDirNode*>::iterator it = children.begin(); it != children.end(); it++) { RDirNode* child = (*it); std::string common = child->commonPathPrefix(f->path); if(common.size() > abspath.size() && common != f->path) { commonpath = common; commonPos = child->getPos(); break; } } // redistribute to new common node if(commonpath.size() > abspath.size()) { //debugLog("common path %s\n", commonpath.c_str()); RDirNode* cnode = new RDirNode(this, commonpath); cnode->setPos(commonPos); for(std::list<RDirNode*>::iterator it = children.begin(); it != children.end();) { RDirNode* child = (*it); if(child->prefixedBy(commonpath)) { //debugLog("this path = %s, commonpath = %s, path = %s\n", abspath.c_str(), commonpath.c_str(), child->getPath().c_str()); it = children.erase(it); cnode->addNode(child); continue; } it++; } addNode(cnode); } return true; }
bool RDirNode::addFile(RFile* f) { //doesnt match this path at all if(f->path.find(abspath) != 0) { if(parent != 0) return false; //if this is the root node (ie no parent), we fork it //if we encounter a file with a non matching path to the //current root path. the calling process then checks if //the root now has a parent node, and changes the pointer. RDirNode* newparent; std::string common = commonPathPrefix(f->path); if(common.size()==0) common = "/"; newparent = new RDirNode(0, common); newparent->addNode(this); return newparent->addFile(f); } //simply change path of node and add this to it if( parent==0 && abspath == "/" && f->path.compare(abspath) != 0 && noFiles() && noDirs()) { debugLog("modifying root path to %s", f->path.c_str()); changePath(f->path); } //is this dir - add to this node if(f->path.compare(abspath) == 0) { //debugLog("addFile %s to %s\n", f->fullpath.c_str(), abspath.c_str()); files.push_back(f); if(!f->isHidden()) visible_count++; f->setDir(this); fileUpdated(false); return true; } bool added = false; //does this belong to one of the children ? for(std::list<RDirNode*>::iterator it = children.begin(); it != children.end(); it++) { RDirNode* child = (*it); added = child->addFile(f); if(added) break; } if(added && parent != 0) return true; //do we have a file in this directory thats fullpath is a prefix of this file, if so //that file is actually a directory - the file should be removed, and a directory with that path added //if this is the root node we do this regardless of if the file was added to a child node for(std::list<RFile*>::const_iterator it = files.begin(); it != files.end(); it++) { RFile* file = (*it); if(f->path.find(file->fullpath) == 0) { //fprintf(stderr, "removing %s as is actually the directory of %s\n", file->fullpath.c_str(), f->fullpath.c_str()); file->remove(true); break; } } if(added) return true; //add new child, add it to that //if commonpath is longer than abspath, add intermediate node, else just add at the files path RDirNode* node = new RDirNode(this, f->path); node->addFile(f); addNode(node); // do we have dir nodes, with a common path element greater than abspath, // if so create another node, and move those nodes there std::string commonpath; vec2 commonPos; for(std::list<RDirNode*>::iterator it = children.begin(); it != children.end(); it++) { RDirNode* child = (*it); std::string common = child->commonPathPrefix(f->path); if(common.size() > abspath.size() && common != f->path) { commonpath = common; commonPos = child->getPos(); break; } } // redistribute to new common node if(commonpath.size() > abspath.size()) { //debugLog("common path %s\n", commonpath.c_str()); RDirNode* cnode = new RDirNode(this, commonpath); cnode->setPos(commonPos); for(std::list<RDirNode*>::iterator it = children.begin(); it != children.end();) { RDirNode* child = (*it); if(child->prefixedBy(commonpath)) { //debugLog("this path = %s, commonpath = %s, path = %s\n", abspath.c_str(), commonpath.c_str(), child->getPath().c_str()); it = children.erase(it); cnode->addNode(child); continue; } it++; } addNode(cnode); } return true; }