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

📄 ftplistparse.cpp

📁 实现了wince 客户端上传下载查看文件及目录的功能接口d
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   if( !IsUNIXStyleListing(pszLine) )
      return false;

   switch( *pszLine )
   {
   case _T('d'): ftpFileStatus.m_fTryCwd  = true; break;
   case _T('-'): ftpFileStatus.m_fTryRetr = true; break;
   case _T('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]==_T(' ') && pszLine[j-1]!=_T(' ') )
      {
         switch(iState)
         {
         case 1: // skipping perm
            ftpFileStatus.m_strAttributes.assign(pszLine+i, j-i);
            iState = 2;
            break;
         case 2: // skipping nlink
            iState = 3;
            ftpFileStatus.m_strLink.assign(pszLine+i, j-i);
            if( j-i==6 && pszLine[i]==_T('f') ) // for NetPresenz
               iState = 4;
            break;
         case 3: // skipping uid
            iState = 4;
            ftpFileStatus.m_strUID.assign(pszLine+i, j-i);
            break;
         case 4: // getting tentative size
            if( !GetLong(pszLine+i, j-i, lSize) )
            {
               lSize = -1;
               ftpFileStatus.m_strGID.assign(pszLine+i, j-i);
            }
            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]==_T(':') )
            {
               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]==_T(':') )
            {
               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]==_T(' ') )
            ++i;
      }
   }

   if( iState != 8 )
      return false;

   ftpFileStatus.m_lSize = lSize;
   ftpFileStatus.m_enSizeType = CFTPFileStatus::stBinary;

   // handle links
   if( pszLine[0] == _T('l') )
   {
      tstring::size_type pos = ftpFileStatus.m_strName.find(_T(" -> "));
      if( pos != tstring::npos )
         ftpFileStatus.m_strName = ftpFileStatus.m_strName.substr(0, pos);
   }

   // eliminate extra NetWare spaces
   if( pszLine[1]==_T(' ') || pszLine[1]==_T('[') )
   {
      if( ftpFileStatus.m_strName.length()>3 && ftpFileStatus.m_strName.substr(0, 3)==_T("   ") )
         ftpFileStatus.m_strName = ftpFileStatus.m_strName.substr(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(LPCTSTR pszLine)
{
   return pszLine && tcschr(pszLine, _T(';')) != NULL;
}

bool CFTPListParse::ParseMultiNetListing(CFTPFileStatus& ftpFileStatus, LPCTSTR 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]==_T(';') )
         break;

   if( i < iLength)
   {
      ftpFileStatus.m_strName = pszLine;
      ftpFileStatus.m_strName = ftpFileStatus.m_strName.substr(0, i);
      if( i > 4 && tcsncmp(pszLine+i-4, _T(".DIR"), 4)==0 )
      {
         ftpFileStatus.m_strName = ftpFileStatus.m_strName.substr(0, ftpFileStatus.m_strName.length()-4);
         ftpFileStatus.m_fTryCwd = true;
      }
      else
         ftpFileStatus.m_fTryRetr = true;

      while (pszLine[i] != _T(' ')) if (++i == iLength) return false;
      while (pszLine[i] == _T(' ')) if (++i == iLength) return false;
      while (pszLine[i] != _T(' ')) if (++i == iLength) return false;
      while (pszLine[i] == _T(' ')) if (++i == iLength) return false;
      
      int j = i;
      while (pszLine[j] != _T('-')) if (++j == iLength) return false;
      long lMDay = 0;
      GetLong(pszLine+i, j-i, lMDay);

      while (pszLine[j] == _T('-')) if (++j == iLength) return false;
      i = j;
      while (pszLine[j] != _T('-')) if (++j == iLength) return false;
      long lMonth = GetMonth(pszLine+i, j-i);
      if (lMonth < 0) return false;

      while (pszLine[j] == _T('-')) if (++j == iLength) return false;
      i = j;
      while (pszLine[j] != _T(' ')) if (++j == iLength) return false;
      long lYear = 0;
      GetLong(pszLine+i, j-i, lYear);

      while (pszLine[j] == _T(' ')) if (++j == iLength) return false;
      i = j;
      while (pszLine[j] != _T(':')) if (++j == iLength) return false;
      long lHour = 0;
      GetLong(pszLine+i, j-i, lHour);

      while (pszLine[j] == _T(':')) if (++j == iLength) return false;
      i = j;
      while (pszLine[j] != _T(':') && pszLine[j] != _T(' ')) 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(LPCTSTR pszLine)
{
   return pszLine && tisdigit(pszLine[0]);
}

bool CFTPListParse::ParseMSDOSListing(CFTPFileStatus& ftpFileStatus, LPCTSTR pszLine, int iLength)
{
   if( !IsMSDOSListing(pszLine) )
      return false;

   int i = 0;
   int j = 0;
   while (pszLine[j] != _T('-')) if (++j == iLength) return false;
   long lMonth = 0;
   GetLong(pszLine+i, j-i, lMonth); //+# -1 

   while (pszLine[j] == _T('-')) if (++j == iLength) return false;
   i = j;
   while (pszLine[j] != _T('-')) if (++j == iLength) return false;
   long lMDay = 0;
   GetLong(pszLine+i, j-i, lMDay);

   while (pszLine[j] == _T('-')) if (++j == iLength) return false;
   i = j;
   while (pszLine[j] != _T(' ')) 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] == _T(' ')) if (++j == iLength) return false;
   i = j;
   while (pszLine[j] != _T(':')) if (++j == iLength) return false;
   long lHour = 0;
   GetLong(pszLine+i, j-i, lHour);

   while (pszLine[j] == _T(':')) if (++j == iLength) return false;
   i = j;
   while ((pszLine[j] != _T('A')) && (pszLine[j] != _T('P'))) if (++j == iLength) return false;
   long lMinute = 0;
   GetLong(pszLine+i, j-i, lMinute);

   if (lHour == 12)
      lHour = 0;

   if (pszLine[j] == _T('A')) if (++j == iLength) return false;
   if (pszLine[j] == _T('P')) { lHour += 12; if (++j == iLength) return false; }
   if (pszLine[j] == _T('M')) if (++j == iLength) return false;

   while (pszLine[j] == _T(' ')) if (++j == iLength) return false;
   if (pszLine[j] == _T('<'))
   {
      ftpFileStatus.m_fTryCwd = true;
      while (pszLine[j] != _T(' ')) if (++j == iLength) return false;
   }
   else
   {
      i = j;
      while (pszLine[j] != _T(' ')) 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] == _T(' ')) 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, const tstring& strLineToParse)
{
   ftpFileStatus.Reset();
   LPCTSTR   pszLine = strLineToParse.c_str();
   const int iLength = static_cast<int>(strLineToParse.length());

   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 + -