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

📄 ftplistparse.cpp

📁 自己改写的在WINCE上开发用的EVC++的FTP操作示例工程,希望能给相关人士提供帮助.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		switch( *pszLine )
		{
		case 'd': ftpFileStatus.m_fTryCwd  = true; break;
		case '-': ftpFileStatus.m_fTryRetr = true; break;
		case 'l': ftpFileStatus.m_fTryCwd  = true;
			ftpFileStatus.m_fTryRetr = true;
		}
		
		int  iState  = 1;
		int  i       = 0;
		long lSize   = 0;
		long lYear   = 0;
		long lMonth  = 0;
		long lMDay   = 0;
		long lHour   = 0;
		long lMinute = 0;
		
		
		for( int j=1; j<iLength; ++j )
		{
			if( pszLine[j] == ' ' && pszLine[j-1] != ' ')
			{
				CDataStack2 data;
				switch(iState)
				{
				case 1: // skipping perm
					data.NewStack(j-i+1);
					data.SetAt(0,(char*)pszLine+i, j-i);
					ftpFileStatus.m_strAttributes = data.GetData();
					iState = 2;
					break;
				case 2: // skipping nlink
					iState = 3;
					data.NewStack(j-i+1);
					data.SetAt(0,(char*)pszLine+i, j-i);
					ftpFileStatus.m_strLink = data.GetData();
					if( j-i==6 && pszLine[i] == 'f') // for NetPresenz
						iState = 4;
					break;
				case 3: // skipping uid
					iState = 4;
					data.NewStack(j-i+1);
					data.SetAt(0,(char*)pszLine+i, j-i);
					ftpFileStatus.m_strUID = data.GetData();
					break;
				case 4: // getting tentative size
					if( !GetLong(pszLine+i, j-i, lSize) )
					{
						lSize = -1;
						data.NewStack(j-i+1);
						data.SetAt(0,(char*)pszLine+i, j-i);
						ftpFileStatus.m_strGID = data.GetData();
					}
					iState = 5;
					break;
				case 5: // searching for month, otherwise getting tentative size
					lMonth = GetMonth(pszLine + i,j - i);
					if( lMonth >= 0 )
						iState = 6;
					else
					{
						if( !GetLong(pszLine+i, j-i, lSize) )
							lSize = -1;
					}
					break;
				case 6: // have size and month
					GetLong(pszLine+i, j-i, lMDay);
					iState = 7;
					break;
				case 7: // have size, month, mday
					if( j-i==4 && pszLine[i+1]==':' )
					{
						GetLong(pszLine+i, 1, lHour);
						GetLong(pszLine+i+2, 2, lMinute);
						ftpFileStatus.m_enModificationTimeType = CFTPFileStatus::mttRemoteMinute;
						ftpFileStatus.m_mtime = m_tmBase + GuessTAI(lMonth,lMDay) + lHour * 3600 + lMinute * 60;
						INSERT_TIME();
					}
					else if( j-i==5 && pszLine[i+2]==':' )
					{
						GetLong(pszLine+i, 2, lHour);
						GetLong(pszLine+i+3, 2, lMinute);
						ftpFileStatus.m_enModificationTimeType = CFTPFileStatus::mttRemoteMinute;
						ftpFileStatus.m_mtime = m_tmBase + GuessTAI(lMonth,lMDay) + lHour * 3600 + lMinute * 60;
						INSERT_TIME();
					}
					else if( j-i >= 4 )
					{
						GetLong(pszLine+i, j-i, lYear);
						ftpFileStatus.m_enModificationTimeType = CFTPFileStatus::mttRemoteDay;
						ftpFileStatus.m_mtime = m_tmBase + CFTPListParse::ToTAI(lYear,lMonth,lMDay);
						INSERT_TIME();
					}
					else
						return false;
					
					ftpFileStatus.m_strName = pszLine + j + 1;
					iState = 8;
					break;
				case 8: // twiddling thumbs
					break;
				}
				
				i = j + 1;
				while( i<iLength && pszLine[i]==' ')
					++i;
			}
		}
		
		if( iState != 8 )
			return false;
		
		ftpFileStatus.m_lSize = lSize;
		ftpFileStatus.m_enSizeType = CFTPFileStatus::stBinary;
		
		// handle links
		if( pszLine[0] == 'l' )
		{
			int pos = ftpFileStatus.m_strName.Find(" -> ");
			if( pos != -1 )
				ftpFileStatus.m_strName = ftpFileStatus.m_strName.Mid(0, pos);
		}
		
		// eliminate extra NetWare spaces
		if( pszLine[1]==' ' || pszLine[1]=='[')
		{
			if( ftpFileStatus.m_strName.GetLength()>3 && ftpFileStatus.m_strName.Mid(0, 3)=="   " )
				ftpFileStatus.m_strName = ftpFileStatus.m_strName.Mid(3);
		}
		
		return true;
}

/// MultiNet (some spaces removed from examples)
/// "00README.TXT;1      2 30-DEC-1996 17:44 [SYSTEM] (RWED,RWED,RE,RE)"
/// "CORE.DIR;1          1  8-SEP-1996 16:09 [SYSTEM] (RWE,RWE,RE,RE)"
/// and non-MutliNet VMS:
/// "CII-MANUAL.TEX;1  213/216  29-JAN-1996 03:33:12  [ANONYMOU,ANONYMOUS]   (RWED,RWED,,)"
bool CFTPListParse::IsMultiNetListing(LPCSTR pszLine)
{
	return pszLine && strchr(pszLine, ';') != NULL;
}

bool CFTPListParse::ParseMultiNetListing(CFTPFileStatus& ftpFileStatus, LPCSTR pszLine, int iLength)
{
	if( !IsMultiNetListing(pszLine) )
		return false;
	
	// name lookup of `i' changed for new ISO `for' scoping 
	int i=0;
	for( ; i<iLength; ++i )
		if( pszLine[i]==';' )
			break;
		
		if( i < iLength)
		{
			ftpFileStatus.m_strName = pszLine;
			ftpFileStatus.m_strName = ftpFileStatus.m_strName.Mid(0, i);
			if( i > 4 && strncmp(pszLine+i-4, ".DIR", 4)==0 )
			{
				ftpFileStatus.m_strName = ftpFileStatus.m_strName.Mid(0, ftpFileStatus.m_strName.GetLength()-4);
				ftpFileStatus.m_fTryCwd = true;
			}
			else
				ftpFileStatus.m_fTryRetr = true;
			
			while (pszLine[i] != ' ') if (++i == iLength) return false;
			while (pszLine[i] == ' ') if (++i == iLength) return false;
			while (pszLine[i] != ' ') if (++i == iLength) return false;
			while (pszLine[i] == ' ') if (++i == iLength) return false;
			
			int j = i;
			while (pszLine[j] != '-') if (++j == iLength) return false;
			long lMDay = 0;
			GetLong(pszLine+i, j-i, lMDay);
			
			while (pszLine[j] == '-') if (++j == iLength) return false;
			i = j;
			while (pszLine[j] != '-') if (++j == iLength) return false;
			long lMonth = GetMonth(pszLine+i, j-i);
			if (lMonth < 0) return false;
			
			while (pszLine[j] == '-') if (++j == iLength) return false;
			i = j;
			while (pszLine[j] != ' ') if (++j == iLength) return false;
			long lYear = 0;
			GetLong(pszLine+i, j-i, lYear);
			
			while (pszLine[j] == ' ') if (++j == iLength) return false;
			i = j;
			while (pszLine[j] != ':') if (++j == iLength) return false;
			long lHour = 0;
			GetLong(pszLine+i, j-i, lHour);
			
			while (pszLine[j] == ':') if (++j == iLength) return false;
			i = j;
			while (pszLine[j] != ':' && pszLine[j] != ' ') if (++j == iLength) return false;
			long lMinute = 0;
			GetLong(pszLine+i, j-i, lMinute);
			
			ftpFileStatus.m_enModificationTimeType = CFTPFileStatus::mttRemoteMinute;
			ftpFileStatus.m_mtime = m_tmBase + CFTPListParse::ToTAI(lYear, lMonth, lMDay) + lHour * 3600 + lMinute * 60;
			INSERT_TIME();
		}
		
		return true;
}

/// MSDOS format
/// 04-27-00  09:09PM       <DIR>          licensed
/// 07-18-00  10:16AM       <DIR>          pub
/// 04-14-00  03:47PM                  589 readme.htm
bool CFTPListParse::IsMSDOSListing(LPCSTR pszLine)
{
	return pszLine && _istdigit(pszLine[0]);
}

bool CFTPListParse::ParseMSDOSListing(CFTPFileStatus& ftpFileStatus, LPCSTR pszLine, int iLength)
{
	if( !IsMSDOSListing(pszLine) )
		return false;
	
	int i = 0;
	int j = 0;
	while (pszLine[j] != '-') if (++j == iLength) return false;
	long lMonth = 0;
	GetLong(pszLine+i, j-i, lMonth); //+# -1 
	
	while (pszLine[j] == '-') if (++j == iLength) return false;
	i = j;
	while (pszLine[j] != '-') if (++j == iLength) return false;
	long lMDay = 0;
	GetLong(pszLine+i, j-i, lMDay);
	
	while (pszLine[j] == '-') if (++j == iLength) return false;
	i = j;
	while (pszLine[j] != ' ') if (++j == iLength) return false;
	long lYear = 0;
	GetLong(pszLine+i, j-i, lYear);
	
	if (lYear < 50)
		lYear += 2000;
	
	if (lYear < 1000)
		lYear += 1900;
	
	while (pszLine[j] == ' ') if (++j == iLength) return false;
	i = j;
	while (pszLine[j] != ':') if (++j == iLength) return false;
	long lHour = 0;
	GetLong(pszLine+i, j-i, lHour);
	
	while (pszLine[j] == ':') if (++j == iLength) return false;
	i = j;
	while ((pszLine[j] != 'A') && (pszLine[j] != 'P')) if (++j == iLength) return false;
	long lMinute = 0;
	GetLong(pszLine+i, j-i, lMinute);
	
	if (lHour == 12)
		lHour = 0;
	
	if (pszLine[j] == 'A') if (++j == iLength) return false;
	if (pszLine[j] == 'P') { lHour += 12; if (++j == iLength) return false; }
	if (pszLine[j] == 'M') if (++j == iLength) return false;
	
	while (pszLine[j] == ' ') if (++j == iLength) return false;
	if (pszLine[j] == '<')
	{
		ftpFileStatus.m_fTryCwd = true;
		while (pszLine[j] != ' ') if (++j == iLength) return false;
	}
	else
	{
		i = j;
		while (pszLine[j] != ' ') if (++j == iLength) return false;
		if( !GetLong(pszLine+i, j-i, ftpFileStatus.m_lSize ) )
			ftpFileStatus.m_lSize = -1;
		ftpFileStatus.m_enSizeType = CFTPFileStatus::stBinary;
		ftpFileStatus.m_fTryRetr = true;
	}
	while (pszLine[j] == ' ') if (++j == iLength) return false;
	
	ftpFileStatus.m_strName = pszLine + j;
	
	ftpFileStatus.m_enModificationTimeType = CFTPFileStatus::mttRemoteMinute;
	ftpFileStatus.m_mtime = m_tmBase + CFTPListParse::ToTAI(lYear,lMonth,lMDay) + lHour * 3600 + lMinute * 60;
	INSERT_TIME();
	
	return true;
}

bool CFTPListParse::Parse(CFTPFileStatus& ftpFileStatus, CStringA& strLineToParse)
{
	ftpFileStatus.Reset();
	LPCSTR   pszLine = (LPCSTR)strLineToParse;
	const int iLength = static_cast<int>(strLineToParse.GetLength());
	
	if( iLength < 2 ) // an empty name in EPLF, with no info, could be 2 chars
		return false;
	
	if( IsEPLS(pszLine) )
	{
		if( !ParseEPLF(ftpFileStatus, pszLine, iLength) )
			return false;
	}
	else if( IsUNIXStyleListing(pszLine) )
	{
		if( !ParseUNIXStyleListing(ftpFileStatus, pszLine, iLength) )
			return false;
	}
	else if( IsMultiNetListing(pszLine) )
	{
		if( !ParseMultiNetListing(ftpFileStatus, pszLine, iLength) )
			return false;
	}
	else if( IsMSDOSListing(pszLine) )
	{
		if( !ParseMSDOSListing(ftpFileStatus, pszLine, iLength) )
			return false;
	}
	else
	{
		// Some useless lines, safely ignored:
		// "Total of 11 Files, 10966 Blocks." (VMS)
		// "total 14786" (UNIX)
		// "DISK$ANONFTP:[ANONYMOUS]" (VMS)
		// "Directory DISK$PCSA:[ANONYM]" (VMS)
		return false;
	}
	
	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -