📄 fileinfoarray.cpp
字号:
//////////////////////////////////////////////////////////////////////
// FileFury
// Copyright (c) 2000 Tenebril Incorporated
// All rights reserved.
//
// This source code is governed by the Tenebril open source
// license (http://www.tenebril.com/developers/opensource/license.html)
//
// For more information on this and other open source applications,
// visit the Tenebril OpenSource page:
// http://www.tenebril.com/developers/opensource
//
//////////////////////////////////////////////////////////////////////
// FileInfoArray.cpp: implementation of the CFileInfoArray class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Oscar.h"
#include "FileInfoArray.h"
#include "Defines.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFileInfoArray::CFileInfoArray()
{
m_pData = NULL;
m_iNumData = 0;
m_iNumSpace = 0;
}
CFileInfoArray::~CFileInfoArray()
{
if(m_pData)
delete m_pData;
}
int CFileInfoArray::Add(LPCTSTR strFullName)
{
FileInfoStruct *pStruct;
CString cstrName = strFullName;
if(cstrName.GetLength() > MAX_PATH)
return -1;
if(cstrName.GetLength() < 1)
return -1;
m_iNumData += 1;
// Allocate more space if necessary.
if(m_iNumData > m_iNumSpace)
{
m_iNumSpace += 1024;
pStruct = new FileInfoStruct[m_iNumSpace];
memset((void *)pStruct, 0, sizeof(FileInfoStruct) * m_iNumSpace);
if(m_iNumData > 1 && m_pData)
memcpy((void *)pStruct, (void *)m_pData,
sizeof(FileInfoStruct) * (m_iNumData - 1));
if(m_pData)
delete m_pData;
m_pData = pStruct;
}
ASSERT(m_pData);
SetFullName(m_iNumData - 1, cstrName);
m_pData[m_iNumData - 1].bValid = true;
return m_iNumData - 1;
}
bool CFileInfoArray::SetIcon(int iItem, int iIcon)
{
if(iItem < 0 || iItem >= m_iNumData)
return false;
m_pData[iItem].iIcon = iIcon;
return true;
}
bool CFileInfoArray::SetDirectory(int iItem, bool bDirectory)
{
if(iItem < 0 || iItem >= m_iNumData)
return false;
m_pData[iItem].bDirectory = bDirectory;
return true;
}
int CFileInfoArray::GetIcon(int iItem)
{
if(iItem < 0 || iItem >= m_iNumData)
return -1;
return m_pData[iItem].iIcon;
}
bool CFileInfoArray::GetDirectory(int iItem)
{
if(iItem < 0 || iItem >= m_iNumData)
return false;
return m_pData[iItem].bDirectory;
}
bool CFileInfoArray::Delete(int iItem)
{
if(iItem < 0 || iItem >= m_iNumData)
return false;
// We can't move memory; indices need to apply
m_pData[iItem].bValid = false;
return true;
}
bool CFileInfoArray::Clear()
{
if(m_iNumData < 1 || !m_pData)
return false;
m_iNumData = 0;
m_iNumSpace = 0;
if(m_pData)
{
delete m_pData;
m_pData = NULL;
}
return true;
}
LPCTSTR CFileInfoArray::GetFullName(int iItem)
{
if(iItem < 0 || iItem >= m_iNumData)
return BLANK;
if(!m_pData[iItem].bValid)
return BLANK;
return (LPCTSTR)m_pData[iItem].strFullName;
}
bool CFileInfoArray::SetFullName(int iItem, LPCTSTR strFullName)
{
CString cstrName = strFullName;
if(iItem < 0 || iItem >= m_iNumData)
return false;
// Make sure we don't run over memory
if(sizeof(TCHAR) * (cstrName.GetLength() + 1) >
sizeof(m_pData[iItem].strFullName))
return false;
memcpy((void *)m_pData[iItem].strFullName,
(void *)cstrName.GetBuffer(0),
sizeof(TCHAR) * (cstrName.GetLength() + 1));
return true;
}
BOOL CFileInfoArray::SetSize(int iIndex, LPCTSTR strSize)
{
if(iIndex < 0 || iIndex >= m_iNumData)
return FALSE;
CString cszSize = strSize;
if((cszSize.GetLength() + 1) * sizeof(TCHAR) > sizeof(m_pData[iIndex].strSize))
return FALSE;
memset((void *)m_pData[iIndex].strSize, 0, sizeof(m_pData[iIndex].strSize));
memcpy((void *)m_pData[iIndex].strSize, (void *)cszSize.GetBuffer(0),
cszSize.GetLength() * sizeof(TCHAR));
return TRUE;
}
LPCTSTR CFileInfoArray::GetSize(int iIndex)
{
if(iIndex < 0 || iIndex >= m_iNumData)
return BLANK;
if(!m_pData[iIndex].bValid)
return BLANK;
return (LPCTSTR)m_pData[iIndex].strSize;
}
BOOL CFileInfoArray::SetType(int iIndex, LPCTSTR strType)
{
if(iIndex < 0 || iIndex >= m_iNumData)
return FALSE;
CString cszType = strType;
if((cszType.GetLength() + 1) * sizeof(TCHAR) > sizeof(m_pData[iIndex].strType))
return FALSE;
memset((void *)m_pData[iIndex].strType, 0, sizeof(m_pData[iIndex].strType));
memcpy((void *)m_pData[iIndex].strType, (void *)cszType.GetBuffer(0),
cszType.GetLength() * sizeof(TCHAR));
return TRUE;
}
LPCTSTR CFileInfoArray::GetType(int iIndex)
{
if(iIndex < 0 || iIndex >= m_iNumData)
return BLANK;
if(!m_pData[iIndex].bValid)
return BLANK;
return (LPCTSTR)m_pData[iIndex].strType;
}
BOOL CFileInfoArray::SetModTime(int iIndex, time_t tTime)
{
if(iIndex < 0 || iIndex >= m_iNumData)
return FALSE;
m_pData[iIndex].tModTime = tTime;
return TRUE;
}
time_t CFileInfoArray::GetModTime(int iIndex)
{
if(iIndex < 0 || iIndex >= m_iNumData)
return (time_t)0;
if(!m_pData[iIndex].bValid)
return (time_t)0;
return m_pData[iIndex].tModTime;
}
UINT CFileInfoArray::GetTotalSize()
{
int i;
UINT uTotal;
CString cszSize;
for(i = 0, uTotal = 0; i < m_iNumData; i++)
{
if(!m_pData[i].bValid) continue;
cszSize = GetSize(i);
//Trim the KB off the end
if(cszSize.Find(_T("KB")) > -1)
cszSize = cszSize.Left(cszSize.GetLength() - 2);
//Remove commas
int iPos;
while((iPos = cszSize.Find(_T(','))) > -1)
{
CString temp;
temp = cszSize.Left(iPos) + cszSize.Right(cszSize.GetLength() -
iPos - 1);
cszSize = temp;
}
int iTemp = atoi(cszSize);
if(iTemp < 0) iTemp = 0;
uTotal += (UINT)iTemp;
}
return uTotal;
}
BOOL CFileInfoArray::SortItems(BOOL bAscending, int nType, int nLow, int nHigh)
{
// QSort.
if( nHigh == -1 ) nHigh = GetNumEntries() - 1;
int lo = nLow;
int hi = nHigh;
int mid = (lo + hi) / 2;
if( hi <= lo ) return FALSE;
// loop through the list until indices cross
while( lo <= hi )
{
// find the first element that is greater than or equal to
// the partition element starting from the left Index.
if( bAscending )
while( ( lo < nHigh ) && ( IsItemBefore(lo, mid, nType)))
++lo;
else
while( ( lo < nHigh ) && ( IsItemBefore(mid, lo, nType)))
++lo;
// find an element that is smaller than or equal to
// the partition element starting from the right Index.
if( bAscending )
while( ( hi > nLow ) && ( IsItemBefore(mid, hi, nType)))
--hi;
else
while( ( hi > nLow ) && ( IsItemBefore(hi, mid, nType)))
--hi;
// if the indexes have not crossed, swap
// and if the items are not equal
if( lo <= hi )
{
CString cszLoText = GetFullName(lo);
CString cszHiText = GetFullName(hi);
// swap only if the items are not equal
if( cszLoText.CompareNoCase(cszHiText) != 0 &&
cszLoText.GetLength() > 0 && cszHiText.GetLength() > 0)
{
// swap the items.
SwapItems(lo, hi);
// if swapping the mid, keep it updated
if(mid == lo)
mid = hi;
else if(mid == hi)
mid = lo;
}
++lo;
--hi;
}
}
// If the right index has not reached the left side of array
// must now sort the left partition.
if( nLow < hi )
SortItems(bAscending, nType, nLow, hi);
// If the left index has not reached the right side of array
// must now sort the right partition.
if( lo < nHigh )
SortItems(bAscending, nType, lo, nHigh);
return TRUE;
}
BOOL CFileInfoArray::IsItemBefore(int nItem, int nCompare, int nType)
{
CString strBase, strCheck;
bool bBaseDir, bCheckDir;
int iSortType, iThisSort;
UINT uBaseVal, uCheckVal;
bBaseDir = GetDirectory(nItem);
bCheckDir = GetDirectory(nCompare);
CString TestBase = GetFullName(nItem);
CString TestCheck = GetFullName(nCompare);
// We want directories to be compared by name only
if(!bBaseDir && !bCheckDir)
iThisSort = nType;
else
iThisSort = 0;
switch(iThisSort)
{
case 0: default: // Sort by name
strBase = GetFriendlyName(nItem);
strCheck = GetFriendlyName(nCompare);
iSortType = 0; // Alphabetic
break;
case 1: // Sort by type
strBase = GetType(nItem);
strCheck = GetType(nCompare);
iSortType = 0;
break;
case 2: // Sort by size
strBase = GetSize(nItem);
strCheck = GetSize(nCompare);
//Trim the KB off the end
if(strBase.Find(_T("KB")) > -1)
strBase = strBase.Left(strBase.GetLength() - 2);
if(strCheck.Find(_T("KB")) > -1)
strCheck = strCheck.Left(strCheck.GetLength() - 2);
//Remove commas
int iPos;
while((iPos = strBase.Find(_T(','))) > -1)
{
CString temp;
temp = strBase.Left(iPos) + strBase.Right(strBase.GetLength() - iPos - 1);
strBase = temp;
}
while((iPos = strCheck.Find(_T(','))) > -1)
{
CString temp;
temp = strCheck.Left(iPos) + strCheck.Right(strCheck.GetLength() - iPos - 1);
strCheck = temp;
}
iSortType = 1; // Numeric
break;
case 3: // Sort by date
uBaseVal = (UINT)GetModTime(nItem);
uCheckVal = (UINT)GetModTime(nCompare);
iSortType = 2; // Implicit
break;
}
if((bBaseDir && bCheckDir) || (!bBaseDir && !bCheckDir)) // Compare two
// directories or
// files fairly
{
if(iSortType == 0)
return (strCheck.CompareNoCase(strBase) > 0);
if(iSortType == 2)
return (uCheckVal > uBaseVal);
int iBaseVal, iCheckVal;
iBaseVal = atoi(strBase);
iCheckVal = atoi(strCheck);
return (iCheckVal > iBaseVal);
}
if(bBaseDir && !bCheckDir) // Directories always come before files
return true;
return false;
}
CString CFileInfoArray::GetFriendlyName(int iItem)
{
if(iItem < 0 || iItem >= m_iNumData)
return BLANK;
if(!m_pData[iItem].bValid)
return BLANK;
return (LPCTSTR)m_pData[iItem].strFriendlyName;
}
BOOL CFileInfoArray::SetFriendlyName(int iItem, LPCTSTR strFullName)
{
CString cstrName = CString(strFullName);
if(iItem < 0 || iItem >= m_iNumData)
return false;
// Make sure we don't run over memory
if(sizeof(TCHAR) * (cstrName.GetLength() + 1) >
sizeof(m_pData[iItem].strFriendlyName))
return false;
memcpy((void *)m_pData[iItem].strFriendlyName,
(void *)cstrName.GetBuffer(0),
sizeof(TCHAR) * (cstrName.GetLength() + 1));
return true;
}
BOOL CFileInfoArray::SwapItems(int nItemA, int nItemB)
{
if(nItemA < 0 || nItemA >= m_iNumData ||
nItemB < 0 || nItemB >= m_iNumData)
return FALSE;
FileInfoStruct fisBuffer;
memcpy((void *)&fisBuffer, (void *)(&m_pData[nItemA]), sizeof(FileInfoStruct));
memcpy((void *)(&m_pData[nItemA]), (void *)(&m_pData[nItemB]), sizeof(FileInfoStruct));
memcpy((void *)(&m_pData[nItemB]), (void *)&fisBuffer, sizeof(FileInfoStruct));
return TRUE;
}
int CFileInfoArray::GetNumEntries()
{
return m_iNumData;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -