Logo Search packages:      
Sourcecode: bareftp version File versions  Download package

ListParserVMS.cs

// ListParserVMS.cs
//
//  Based on code from edtftp.net (see CREDITS)
//

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace bareFTP.Protocol.Ftp
{
      public class ListParserVMS
      {
             private static readonly string DIR = ".DIR";
    
        /// <summary>Directory field</summary>
        private static readonly string HDR = "Directory";
    
         /// <summary>Total field</summary>
        private static readonly string TOTAL = "Total";
    
         /// <summary> Number of expected fields</summary>
        private const int DEFAULT_BLOCKSIZE = 512*1024;
        
        /// <summary> Number of expected fields</summary>
        private static readonly int MIN_EXPECTED_FIELD_COUNT = 4;

        private static  bool versionInName = false;

        //private static int blocksize = DEFAULT_BLOCKSIZE;
            
            public static List<RemoteFile> ParseList(List<string> list)
            {
                  if(list == null || list.Count < 1)
                        return new List<RemoteFile>();

                  List<RemoteFile> files = new List<RemoteFile>();
                  System.Globalization.CultureInfo ParsingCulture = System.Globalization.CultureInfo.InvariantCulture;
                  
                  int counter = -1;
                  
                  foreach(string s in list)
                  {
                        
                        counter++;
                        List<string> fields = Split(s);
                        
                        if(fields.Count <= 0)
                  continue;
                        
                        if(fields.Count == 1 && fields[0].Contains(";"))
                        {
                              List<string> tmp_fields = Split(list[counter+1]);
                              if(tmp_fields.Count == 3)
                              {
                                    if(list[counter+1].StartsWith("%%"))
                                          continue;
                                    fields = Split(s + (list[counter+1].Trim()));
                              }
                              else
                                    continue;
                        }
                        // skip line which lists Directory
                  if (fields.Count >= 2 && fields[0].Equals(HDR))
                        continue;
                  // skip line which lists Total
                if (fields.Count > 0 && fields[0].Equals(TOTAL))
                        continue;
                  if (fields.Count < MIN_EXPECTED_FIELD_COUNT)
                  continue;
                        if(fields[0].Trim().StartsWith("%%"))
                              continue;
                         // skip blank lines
                  

                        string name = fields[0];
        
                  // make sure it is the name (ends with ';<INT>')
                  int semiPos = name.LastIndexOf(';');
                  // check for ;
                  if(semiPos <= 0) 
                  {
                      throw new FormatException("File version number not found in name '" + name + "'");
                  }
      
                  string nameNoVersion = name.Substring(0, semiPos);
                  
                  // check for version after ;
                  string afterSemi = fields[0].Substring(semiPos+1);
                  try
                  {
                      Int64.Parse(afterSemi);
                      // didn't throw exception yet, must be number
                      // we don't use it currently but we might in future
                  }
                  catch(FormatException) 
                  {
                      // don't worry about version number
                  }
      
                  // test is dir
                  bool isDir = false;
                  if (nameNoVersion.EndsWith(DIR)) 
                  {
                      isDir = true;
                      name = nameNoVersion.Substring(0, nameNoVersion.Length-DIR.Length);
                  }
                  
                  if (!versionInName && !isDir)
                  {
                      name = nameNoVersion;
                  }
                  
                  // 2nd field is size USED/ALLOCATED format, or perhaps just USED
                  int slashPos = fields[1].IndexOf('/');
                  string sizeUsed = fields[1];
                  if (slashPos > 0)
                      sizeUsed = fields[1].Substring(0, slashPos);
                  try
                        {
                              long size = Int64.Parse(sizeUsed) * 512;
                        
                        // 3 & 4 fields are date time
                        string lastModifiedStr = TweakDateString(fields);
                        DateTime lastModified = DateTime.Parse(lastModifiedStr.ToString(),ParsingCulture.DateTimeFormat);
                        
                        // 5th field is [group,owner]
                        string group = null;
                        string owner = null;
                        if (fields.Count >= 5)
                        {
                            if (fields[4][0] == '[' && fields[4][fields[4].Length-1] == ']') 
                            {
                                int commaPos = fields[4].IndexOf(',');
                                if (commaPos < 0)
                                {
                                    owner = fields[4].Substring(1, fields[4].Length-2);
                                    group = "";
                                }
                                else 
                                {
                                    group = fields[4].Substring(1, commaPos-1);
                                    owner = fields[4].Substring(commaPos+1, fields[4].Length-commaPos-2);
                                }
                            }
                        }
                        
                        // 6th field is permissions e.g. (RWED,RWED,RE,)
                        string permissions = null;
                        if (fields.Count >= 6)
                        {
                            if (fields[5][0] == '(' && fields[5][fields[5].Length-1] == ')') 
                            {
                                permissions = fields[5].Substring(1, fields[5].Length-2);
                            }
                        }
      
                              RemoteFile file = new RemoteFile();
                              file.Filename = name;
                              file.Size = size;
                              file.Owner = owner;
                              file.Group = group;
                              file.Permissions = permissions;
                              file.IsDir = isDir;
                              file.LastModified = lastModified;
                              files.Add(file);
                        }
                        catch{}
                        
                  }

                  return files;
            }


            private static string TweakDateString(List<string> fields) 
        {
            // convert the last 2 chars of month to lower case
            StringBuilder lastModifiedStr = new StringBuilder();
            bool monthFound = false;
            for (int i = 0; i < fields[2].Length; i++)
            {
                if (!Char.IsLetter(fields[2][i])) 
                {
                    lastModifiedStr.Append(fields[2][i]);
                }
                else
                {
                    if (!monthFound)
                    {
                        lastModifiedStr.Append(fields[2][i]);
                        monthFound = true;
                    }
                    else
                    {
                        lastModifiedStr.Append(Char.ToLower(fields[2][i]));
                    }
                }
            }  
            lastModifiedStr.Append(" ").Append(fields[3]);
            return lastModifiedStr.ToString();
        }

            public static List<string> Split(string str)
        {
            ArrayList allTokens = new ArrayList(str.Split(null));
            for (int i = allTokens.Count - 1; i >= 0; i--)
                if (((string)allTokens[i]).Trim().Length == 0)
                    allTokens.RemoveAt(i);
            string[] ss = (string[])allTokens.ToArray(typeof(string));

                  return new List<string>(ss);
        }
      }
}

Generated by  Doxygen 1.6.0   Back to index