|
// 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 CString& n, const CString& basepath
):
parent_(p), name_(n)
{
if (n.IsEmpty())
path_ = basepath;
else if (basepath.IsEmpty())
path_ = n;
else
path_ = basepath + '/' + n;
}
Directory::~Directory()
{
for (DirsT::iterator i = subdirs_.begin(); i != subdirs_.end(); ++i)
{
delete *i;
}
}
int splitbase(const CString& n, CString& base, CString& rest)
{
if (n.IsEmpty())
return 0;
int x = n.Find('/');
if (x == -1)
{
base.Empty();
rest = n;
return 1;
}
if (x == 0 || x == n.GetLength()-1)
return 0;
base = n.Left(x);
rest = n.Mid(x+1);
return 1;
}
int Directory::add(CString n, Direntry& e)
{
CString base;
CString rest;
Directory* cur = this;
for (;;)
{
if (!splitbase(n, base, rest)) {
ATLTRACE("Directory('%s')::add(%d): splitbase returned 0\n",
(LPCTSTR)path(), (LPCTSTR)n);
return 0;
}
if (base.IsEmpty())
{
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(CString n) const
{
CString base;
CString rest;
const Directory* cur = this;
for (;;)
{
loopstart:
if (!splitbase(n, base, rest))
{
ATLTRACE("Directory('%s')::get(%d): splitbase returned 0\n",
(LPCTSTR)path(), n);
return 0;
}
if (base.IsEmpty())
{
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(CString n)
{
CString base;
CString rest;
const Directory* cur = this;
for (;;)
{
loopstart:
if (!splitbase(n, base, rest))
{
ATLTRACE("Directory('%s')::getdir(%d): splitbase returned 0\n",
path(), n);
return 0;
}
const bool leaf = base.IsEmpty();
const CString& 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)
{
ATLTRACE("Directory('%s')::print: error: d is 0\n", (LPCTSTR)path());
return;
}
d->print();
}
CString base = path();
time_t t;
CString s;
char ctime_res[26];
for (FilesT::const_iterator i = files_.begin(); i != files_.end(); ++i)
{
CString p = (!base.IsEmpty() ? base + "/" + i->name : i->name);
t = i->mtime;
errno_t err = ctime_s(ctime_res, 26, &t);
if (err == 0) {
s = ctime_res;
s.Truncate(s.GetLength() - 1); // strip ending '\n'
}
else {
s = "unset";
}
printf("%c %6o %10u %-24s %s\n", i->state, i->mode, i->size,
(LPCTSTR)s, (LPCTSTR)p);
}
}
|
Loading...