/win32/shellext/Directory.cpp
https://bitbucket.org/tortoisehg/hgtk/ · C++ · 240 lines · 181 code · 44 blank · 15 comment · 45 complexity · c04dff22443d36d0de4b4fdc7863397c MD5 · raw file
- // Copyright (C) 2009 Benjamin Pollack
- // Copyright (C) 2009 Adrian Buehlmann
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 2 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
- #include <time.h>
- #include "stdafx.h"
- #include "Directory.h"
- #include "Winstat.h"
- Directory::Directory(
- Directory* p, const std::string& n, const std::string& basepath
- ):
- parent_(p), name_(n)
- {
- if (n.empty())
- path_ = basepath;
- else if (basepath.empty())
- path_ = n;
- else
- path_ = basepath + '/' + n;
- }
- Directory::~Directory()
- {
- for (DirsT::iterator i = subdirs_.begin(); i != subdirs_.end(); ++i)
- {
- delete *i;
- }
- }
- int splitbase(const std::string& n, std::string& base, std::string& rest)
- {
- if (n.empty())
- return 0;
- size_t x = n.find_first_of ('/');
- if (x == std::string::npos)
- {
- base.clear();
- rest = n;
- return 1;
- }
- if (x == 0 || x == n.length()-1)
- return 0;
- base = n.substr(0, x);
- rest = n.substr(x+1);
- return 1;
- }
- int Directory::add(const std::string& n_in, Direntry& e)
- {
- std::string base;
- std::string rest;
-
- std::string n = n_in;
- Directory* cur = this;
-
- for (;;)
- {
- if (!splitbase(n, base, rest)) {
- TDEBUG_TRACE("Directory(" << path() << ")::add(" << n_in
- << "): splitbase returned 0");
- return 0;
- }
- if (base.empty())
- {
- e.name = n;
- cur->files_.push_back(e);
- return 1;
- }
- Directory* d = 0;
- for (DirsT::iterator i = cur->subdirs_.begin();
- i != cur->subdirs_.end(); ++i)
- {
- if ((*i)->name_ == base) {
- d = *i;
- break;
- }
- }
- if (!d)
- {
- d = new Directory(cur, base, cur->path());
- cur->subdirs_.push_back(d);
- }
- n = rest;
- cur = d;
- }
- }
- const Direntry* Directory::get(const std::string& n_in) const
- {
- std::string base;
- std::string rest;
- std::string n = n_in;
- const Directory* cur = this;
- for (;;)
- {
- loopstart:
- if (!splitbase(n, base, rest))
- {
- TDEBUG_TRACE("Directory(" << path() << ")::get("
- << n_in << "): splitbase returned 0");
- return 0;
- }
- if (base.empty())
- {
- for (FilesT::const_iterator i = cur->files_.begin();
- i != cur->files_.end(); ++i)
- {
- if (i->name == n)
- return &(*i);
- }
- return 0;
- }
- for (DirsT::const_iterator i = cur->subdirs_.begin();
- i != cur->subdirs_.end(); ++i)
- {
- if ((*i)->name_ == base)
- {
- cur = *i;
- n = rest;
- goto loopstart;
- }
- }
- return 0;
- }
- }
- Directory* Directory::getdir(const std::string& n_in)
- {
- std::string base;
- std::string rest;
- std::string n = n_in;
- const Directory* cur = this;
- for (;;)
- {
- loopstart:
- if (!splitbase(n, base, rest))
- {
- TDEBUG_TRACE("Directory(" << path() << ")::getdir("
- << n_in << "): splitbase returned 0");
- return 0;
- }
- const bool leaf = base.empty();
- const std::string& searchstr = (leaf ? n : base);
- for (DirsT::const_iterator i = cur->subdirs_.begin();
- i != cur->subdirs_.end(); ++i)
- {
- if ((*i)->name_ == searchstr)
- {
- if (leaf)
- return *i;
- cur = *i;
- n = rest;
- goto loopstart;
- }
- }
- return 0;
- }
- }
- void Directory::print() const
- {
- for (DirsT::const_iterator i = subdirs_.begin(); i != subdirs_.end(); ++i)
- {
- const Directory* d = *i;
- if (!d)
- {
- TDEBUG_TRACE("Directory(" << path() << ")::print: error: d is 0");
- return;
- }
- d->print();
- }
- std::string base = path();
- time_t t;
- std::string s;
- char* ctime_res = 0;
- for (FilesT::const_iterator i = files_.begin(); i != files_.end(); ++i)
- {
- std::string p = (!base.empty() ? base + "/" + i->name : i->name);
- t = i->mtime;
- ctime_res = ctime(&t);
- if (ctime_res) {
- s = ctime_res;
- s.resize(s.size() - 1); // strip ending '\n'
- }
- else {
- s = "unset";
- }
- printf(
- "%c %6o %10u %-24s %s\n",
- i->state, i->mode, i->size, s.c_str(), p.c_str()
- );
- }
- }