⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileinfoarray.cpp

📁 c++系统开发实例精粹内附的80例源代码 环境:windows2000,c++6.0
💻 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 + -