File Stream C#

/*
 * Copyright (c) United Binary LLC.  All rights reserved.
 * 
 * This code is licensed under the MIT License
 * 
 * SEE: http://harnessit.codeplex.com/license
 * 
 */
#region using ...
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
#endregion
namespace UnitedBinary.Core.IO
{
  /// 
  public class RelativePaths
  {
    private string basepath = string.Empty;
    /// 
    public RelativePaths(string basePath)
    {
      if (basePath == null || basePath.Length == 0)
      {
        throw new ArgumentException( "Invalid base path." );
      }
      BasePath = basePath;
    }
    /// 
    public RelativePaths()
    {
    }
    /// 
    public string GetRelativePath(string fullPath)
    {
      if (fullPath == null)
      {
        throw new ArgumentNullException( "fullPath" );
      }
      bool isCommonPath = CheckForCommonDrive( fullPath );
      bool isCommonNetwork = CheckForCommonNetworkPath( fullPath );
      if (!isCommonPath && !isCommonNetwork)
      {
        return fullPath;
      }
      char[] delims = {'\\'};
      string[] baseArray = BasePath.Split( delims );
      string[] fullArray = fullPath.Split( delims );
      int divergenceIndex = 0;
      for (int i=0; i < System.Math.Min( baseArray.Length, fullArray.Length ); i++)
      {
        if (string.Compare(baseArray[i], fullArray[i], true) != 0)
        {
          divergenceIndex = i;
          break;
        }
      }
      if (divergenceIndex == 0)
      {
        divergenceIndex = baseArray.Length;
      }
      int upCount = baseArray.Length - divergenceIndex;
      string relPath = string.Empty;
      for (int i=0; i < upCount; i++)
      {
        relPath += "..\\";
      }
      for (int i=divergenceIndex; i < fullArray.Length; i++)
      {
        relPath += fullArray[i];
        if (i < fullArray.Length-1)
        {
          relPath += "\\";
        }
      }
      Debug.WriteLine( "Divergence at index " + divergenceIndex );
      Debug.WriteLine( "Full path: " + fullPath );
      Debug.WriteLine( "Base path: " + BasePath );
      Debug.WriteLine( "Generated relative path: " + relPath );
      return relPath;
    }
    private bool CheckForCommonNetworkPath(string fullPath)
    {
      if (fullPath.Length == 0)
      {
        return false;
      }
      string basePath = BasePath;
      bool isBaseNetwork = basePath.StartsWith( @"\\" );
      bool isFullNetwork = fullPath.StartsWith( @"\\" );
      bool bothAreNetworks = isBaseNetwork && isFullNetwork;
      if (!bothAreNetworks)
      {
        return false;
      }
      int nextSlash = basePath.IndexOf( '\\', 2 );
      if (nextSlash < 0)
      {
        return false;
      }
      string commonRoot = basePath.Substring( 0, nextSlash + 1 );
      bool commonNetwork =
        string.Compare( basePath, 0, fullPath, 0, nextSlash+1, true ) == 0;
      return commonNetwork;
    }
    private bool CheckForCommonDrive(string fullPath)
    {
      if (fullPath.Length == 0)
      {
        return false;
      }
      string basePath = BasePath;
      bool isBaseDrive = basePath[1] == ':';
      bool isFullDrive = fullPath[1] == ':';
      bool bothAreDrives = isBaseDrive && isFullDrive;
      bool commonDrives =
        bothAreDrives &&
        char.ToLower(basePath[0]) == char.ToLower( fullPath[0] );
      if (bothAreDrives)
      {
        return commonDrives;
      }
      return false;
    }
    /// 
    public string BasePath
    {
      get
      {
        return basepath;
      }
      set
      {
        if (value == null)
        {
          throw new ArgumentNullException( "value" );
        }
        string startingSlashes = GetPrefixedSlashes( value.Trim() );
        basepath = value.Trim( new char[]  {' ', '\\'} );
        basepath = startingSlashes + basepath;
      }
    }
    private string GetPrefixedSlashes(string value)
    {
      StringBuilder sb = new StringBuilder();
      for (int i=0; i < value.Length; i++)
      {
        if (value[i] != '\\')
        {
          break;
        }
        else
        {
          sb.Append( '\\' );
        }
      }
      string startingSlashes = sb.ToString();
      return startingSlashes;
    }
    /// 
    [EditorBrowsable(EditorBrowsableState.Never)]
    public string DirectoryFromFileName(string fullPathName)
    {
      if (fullPathName == null || fullPathName.Length == 0)
      {
        throw new ArgumentException( "Invalid FullPathName." );
      }
      int dirIndex = fullPathName.Length;
      for (int i=fullPathName.Length-1; i > 0; i--)
      {
        if (fullPathName[i] == '\\')
        {
          dirIndex = i;
          break;
        }
      }
      if (dirIndex == fullPathName.Length)
      {
        return fullPathName;
      }
      string dir = fullPathName.Remove( dirIndex, fullPathName.Length - dirIndex );
      char[] trimmer = {'\\',' '};
      dir = dir.Trim( trimmer );
      Debug.WriteLine( "DirectoryFromFileName: Converted-> " + fullPathName );
      Debug.WriteLine( "DirectoryFromFileName: To--------> " + dir );
      return dir;
    }
    /// 
    public string RebuildFullPath(string relativeFilePath)
    {
      if (relativeFilePath == null || relativeFilePath.Length < 2)
      {
        return this.BasePath;
      }
      //
      // Check some special cases that don't fit the algorithm.
      // 1. The file is on a different drive than base (nothing relative to work with).
      // 2. The base path is a relative path itself.
      //
      if (relativeFilePath[1] == ':')
      {
        Debug.WriteLine( "Relative path contains drive letter - it is already a full path.  Returning." );
        return relativeFilePath;
      }
      else if (relativeFilePath.StartsWith(@"\\"))
      {
        Debug.WriteLine( "Relative path is a newtwork share - it is already a full path.  Returning." );
        return relativeFilePath;
      }
      if (BasePath.StartsWith(".."))
      {
        Debug.WriteLine( "Base is relative path, concatenating." );
        return BasePath + "\\" + relativeFilePath;
      }
      char[] splitter = {'\\'};
      string[] dirs = relativeFilePath.Split( splitter );
      int upCount = 0;
      foreach (string dir in dirs)
      {
        if (dir == "..")
        {
          upCount++;
        }
      }
      Debug.WriteLine( "Up count = " + upCount );
      StringBuilder sbFullPath2 = new StringBuilder();
      for (int i=upCount; i < dirs.Length; i++)
      {
        sbFullPath2.Append("\\").Append( dirs[i] );
      }
      string fullPath2 = sbFullPath2.ToString();
      Debug.WriteLine( "FullPath2 = " + fullPath2 );
      dirs = BasePath.Split( splitter );
      StringBuilder sbFullPath1 = new StringBuilder();
      sbFullPath1.Append( dirs[0] );
      for (int i=1; i < dirs.Length-upCount; i++)
      {
        sbFullPath1.Append("\\").Append( dirs[i] );
      }
      string fullPath1 = sbFullPath1.ToString();
      Debug.WriteLine( "FullPath1 = " + fullPath1 );
      string fullPath = fullPath1 + fullPath2;
      Debug.WriteLine( "FullPath = " + fullPath );
      return fullPath;
    }
  }
}