|
// Copyright (C) 2011 Fog Creek Software
// 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 "stdafx.h"
#include "Directory.h"
#include "Winstat.h"
#include <time.h>
CDirectory::CDirectory(CDirectory* pParent, const CString& strName,
const CString& strBasePath) :
m_pParent(pParent), m_strName(strName)
{
if (strName.IsEmpty())
{
m_strPath = strBasePath;
}
else if (strBasePath.IsEmpty())
{
m_strPath = strName;
}
else
{
m_strPath = strBasePath + '/' + strName;
}
}
CDirectory::~CDirectory()
{
POSITION position = m_listSubdirs.GetHeadPosition();
while (position != NULL)
{
delete m_listSubdirs.GetNext(position);
}
}
int SplitBase(const CString& strPath, CString& strBase, CString& strRest)
{
if (strPath.IsEmpty()) return 0;
int nPos = strPath.Find('/');
if (nPos == -1)
{
strBase.Empty();
strRest = strPath;
return 1;
}
if (nPos == 0 || nPos == strPath.GetLength() - 1) return 0;
strBase = strPath.Left(nPos);
strRest = strPath.Mid(nPos + 1);
return 1;
}
int CDirectory::Add(CString strName, CDirentry& rEntry)
{
CString strBase;
CString strRest;
CDirectory* cur = this;
for (;;)
{
if (!SplitBase(strName, strBase, strRest))
{
ATLTRACE("CDirectory('%s')::Add(%d): splitbase returned 0\n",
(LPCTSTR)Path(), (LPCTSTR)strName);
return 0;
}
if (strBase.IsEmpty())
{
rEntry.m_strName = strName;
cur->m_listFiles.AddTail(rEntry);
return 1;
}
CDirectory* pDir = 0;
POSITION position = cur->m_listSubdirs.GetHeadPosition();
while (position != NULL)
{
CDirectory* pItem = cur->m_listSubdirs.GetNext(position);
if (pItem->m_strName == strBase)
{
pDir = pItem;
break;
}
}
if (!pDir)
{
pDir = new CDirectory(cur, strBase, cur->Path());
cur->m_listSubdirs.AddTail(pDir);
}
strName = strRest;
cur = pDir;
}
}
const CDirentry* CDirectory::Get(CString strRelPath) const
{
CString strBase;
CString strRest;
const CDirectory* pCur = this;
for (;;)
{
loopstart:
if (!SplitBase(strRelPath, strBase, strRest))
{
ATLTRACE("CDirectory('%s')::Get(%d): splitbase returned 0\n",
(LPCTSTR)Path(), (LPCTSTR)strRelPath);
return 0;
}
if (strBase.IsEmpty())
{
POSITION position = pCur->m_listFiles.GetHeadPosition();
while (position != NULL)
{
const CDirentry& rItem = pCur->m_listFiles.GetNext(position);
if (rItem.m_strName == strRelPath) return &rItem;
}
return 0;
}
POSITION position = pCur->m_listSubdirs.GetHeadPosition();
while (position != NULL)
{
CDirectory* pItem = pCur->m_listSubdirs.GetNext(position);
if (pItem->m_strName == strBase)
{
pCur = pItem;
strRelPath = strRest;
goto loopstart;
}
}
return 0;
}
}
CDirectory* CDirectory::GetDir(CString strRelPath)
{
CString strBase;
CString strRest;
const CDirectory* pCur = this;
for (;;)
{
loopstart:
if (!SplitBase(strRelPath, strBase, strRest))
{
ATLTRACE("Directory('%s')::getdir('%s'): splitbase returned 0\n",
(LPCTSTR)Path(), (LPCTSTR)strRelPath);
return 0;
}
bool bLeaf = strBase.IsEmpty();
const CString& strSearch = (bLeaf ? strRelPath : strBase);
POSITION position = pCur->m_listSubdirs.GetHeadPosition();
while (position != NULL)
{
CDirectory* pItem = pCur->m_listSubdirs.GetNext(position);
if (pItem->m_strName == strSearch)
{
if (bLeaf) return pItem;
pCur = pItem;
strRelPath = strRest;
goto loopstart;
}
}
return 0;
}
}
void CDirectory::Print() const
{
POSITION position = m_listSubdirs.GetHeadPosition();
while (position != NULL)
{
const CDirectory* pDir = m_listSubdirs.GetNext(position);
if (!pDir)
{
ATLTRACE("Directory('%s')::print: error: d is 0\n", (LPCTSTR)Path());
return;
}
pDir->Print();
}
CString strBase = Path();
time_t t;
CString str;
char ctime_res[26];
position = m_listFiles.GetHeadPosition();
while (position != NULL)
{
const CDirentry& rItem = m_listFiles.GetNext(position);
CString strPath = (!strBase.IsEmpty() ? strBase + "/" + rItem.m_strName :
rItem.m_strName);
t = rItem.m_uMTime;
errno_t err = ctime_s(ctime_res, 26, &t);
if (err == 0)
{
str = ctime_res;
str.Truncate(str.GetLength() - 1); // strip ending '\n'
}
else
{
str = "unset";
}
printf("%c %6o %10u %-24s %s\n", rItem.m_chState, rItem.m_uMode, rItem.m_uSize,
(LPCTSTR)str, (LPCTSTR)strPath);
}
}
|
Loading...