Mega Code Archive

 
Categories / C# / File Stream
 

Relative Paths

/*  * 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 {   /// <include file='IO.xml' path='/Docs/RelativePaths/Class/*'/>   public class RelativePaths   {     private string basepath = string.Empty;     /// <include file='IO.xml' path='/Docs/RelativePaths/ctor_string/*'/>     public RelativePaths(string basePath)     {       if (basePath == null || basePath.Length == 0)       {         throw new ArgumentException( "Invalid base path." );       }       BasePath = basePath;     }     /// <include file='IO.xml' path='/Docs/RelativePaths/ctor/*'/>     public RelativePaths()     {     }     /// <include file='IO.xml' path='/Docs/RelativePaths/GetRelativePath/*'/>     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;     }     /// <include file='IO.xml' path='/Docs/RelativePaths/BasePath/*'/>     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;     }     /// <include file='IO.xml' path='/Docs/Empty/Empty/*'/>     [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;     }     /// <include file='IO.xml' path='/Docs/RelativePaths/RebuildFullPath/*'/>     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;     }   } }