| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- #include "FilesTree.h"
- #include "PackFile.h"
- FilesTree::Node::Node() : path(_FL_),
- children(_FL_)
- {
- parent = null;
- }
- FilesTree::FilesTree() : paths(_FL_)
- {
- root.parent = null;
- pathsCount = 0;
- }
- FilesTree::~FilesTree()
- {
- }
- //Добавить объект отображающий путь
- void FilesTree::AddMirrorPath(MirrorPath * mp, const char * on)
- {
- //Получаем последний нод в пути
- Node * node = AddPath(root, on);
- Assert(node);
- //Регистрируемся в ноде
- node->path.Add(mp);
- mp->SetNode(node);
- }
- //Добавить новый путь и вернуть конечный узел
- FilesTree::Node * FilesTree::AddPath(Node & node, const char * path)
- {
- //Выделяем текущее имя
- for(long size = 0; path[size] != '\\' && path[size]; size++);
- //Если нет продолжения то возвращаем родительский нод
- if(size == 0)
- {
- return &node;
- }
- //Ищем среди детей
- for(long i = 0; i < node.children; i++)
- {
- Node & child = *node.children[i];
- if(IsEqual(child.name.c_str(), child.name.Len(), path, size))
- {
- if(path[size])
- {
- return AddPath(child, path + size + 1);
- }
- return &child;
- }
- }
- //Нет такого, добавляем
- Node * n = NEW Node();
- n->name.Reserve(size + 1);
- for(long i = 0; i < size; i++)
- {
- n->name += path[i];
- }
- node.children.Add(n);
- n->parent = &node;
- return AddPath(*n, path + size + 1);
- }
- //Удалить объект отображающий путь
- void FilesTree::DelMirrorPath(MirrorPath * mp)
- {
- Node * node = (Node *)mp->GetNode();
- Assert(node);
- node->path.Del(mp);
- //Удаляем цепочку пустых нодов
- while(node->children.Size() == 0 && node->path.Size() == 0 && node->parent)
- {
- Node * parent = node->parent;
- parent->children.Del(node);
- delete node;
- node = parent;
- }
- }
- //Получить список зеркальных путей
- dword FilesTree::FindPaths(const char * fullPath)
- {
- pathsCount = 0;
- //Ищем по зеркальным путям в паках
- TreeProcess(root, fullPath);
- return pathsCount;
- }
- //Получить путь из списка
- const char * FilesTree::GetPath(dword index)
- {
- if(index < pathsCount)
- {
- return paths[index].c_str();
- }
- return null;
- }
- //Поиск всех путей и проверка файлов в паке
- void FilesTree::TreeProcess(Node & node, const char * fullPath)
- {
- //Перебираем все отзеркаленые пути
- for(long i = 0; i < node.path; i++)
- {
- MirrorPath * p = node.path[i];
- if(pathsCount >= paths.Size())
- {
- paths.AddElements(16);
- for(dword i = pathsCount; i < paths.Size(); i++)
- {
- paths[i].Reserve(1024);
- }
- }
- string & path = paths[pathsCount++];
- path = node.path[i]->GetPath();
- path += fullPath;
- }
- if(*fullPath == 0)
- {
- //Закончились поиски
- return;
- }
- //Выделяем текущее имя
- for(long size = 0; fullPath[size] != '\\' && fullPath[size]; size++);
- //Ищем среди детей
- for(long i = 0; i < node.children; i++)
- {
- Node & child = *node.children[i];
- if(IsEqual(child.name.c_str(), child.name.Len(), fullPath, size))
- {
- const char * path = fullPath + size;
- if(*path == '\\') path++;
- TreeProcess(child, path);
- return;
- }
- }
- }
- //Сравнить строки
- bool FilesTree::IsEqual(const char * str1, long len1, const char * str2, long len2)
- {
- if(len1 != len2)
- {
- return false;
- }
- for(; len1 > 0; len1--, str1++, str2++)
- {
- if(*str1 != *str2)
- {
- return false;
- }
- }
- return true;
- }
|