331 lines
7.1 KiB
C#
331 lines
7.1 KiB
C#
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Rokojori
|
|
{
|
|
public enum FilePathType
|
|
{
|
|
Absolute,
|
|
Relative
|
|
}
|
|
|
|
public class FilePath
|
|
{
|
|
public FilePathType type;
|
|
public FilePath parent;
|
|
public string path;
|
|
|
|
public string _fileName;
|
|
public string _fileExtension;
|
|
string _fullPath = null;
|
|
|
|
Trillean isDirectory = Trillean.Any;
|
|
|
|
public bool Exists()
|
|
{
|
|
return File.Exists( fullPath );
|
|
}
|
|
|
|
public void MarkAsFile()
|
|
{
|
|
isDirectory = Trillean.False;
|
|
}
|
|
|
|
public void MarkAsDirectory()
|
|
{
|
|
isDirectory = Trillean.True;
|
|
}
|
|
|
|
/**<summary for="method get_fileName">Only fileName without fileExtension </summary>*/
|
|
public string fileName
|
|
{
|
|
get
|
|
{
|
|
if ( _fileName == null)
|
|
{
|
|
_fileName = Path.GetFileNameWithoutExtension( path );
|
|
}
|
|
|
|
return _fileName;
|
|
}
|
|
}
|
|
|
|
/**<summary for="method get_fullFileName">Combines fileName + fileExtension </summary>*/
|
|
public string fullFileName => fileName + fileExtension;
|
|
|
|
/** <summary for="method get_fileExtension">File extension including the dot, eg. ".svg", ".jpg", ".js" </summary> */
|
|
public string fileExtension
|
|
{
|
|
get
|
|
{
|
|
if ( _fileExtension == null )
|
|
{
|
|
_fileExtension = Path.GetExtension( path );
|
|
}
|
|
|
|
return _fileExtension;
|
|
}
|
|
}
|
|
|
|
public bool HasFileExtension( string extension, bool forceDot = true )
|
|
{
|
|
if ( fileExtension == null )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if ( forceDot && ! extension.StartsWith( "." ))
|
|
{
|
|
extension = "." + extension;
|
|
}
|
|
|
|
return fileExtension.ToLower() == extension.ToLower();
|
|
}
|
|
|
|
public string fullPath
|
|
{
|
|
get
|
|
{
|
|
if ( _fullPath == null )
|
|
{
|
|
if ( this.parent != null )
|
|
{
|
|
_fullPath = this.parent.fullPath + "/" + path;
|
|
}
|
|
else
|
|
{
|
|
_fullPath = path;
|
|
}
|
|
|
|
}
|
|
|
|
return _fullPath;
|
|
}
|
|
}
|
|
|
|
public static FilePath Create( string path, FilePathType type = FilePathType.Relative, FilePath parent = null )
|
|
{
|
|
|
|
var rp = new FilePath();
|
|
|
|
if ( path.EndsWith( "/" ) )
|
|
{
|
|
path = path.ReplaceEnd( "/" );
|
|
rp.isDirectory = Trillean.True;
|
|
}
|
|
|
|
path = path.ReplaceStart( "/" );
|
|
|
|
rp.type = type;
|
|
rp.parent = parent;
|
|
rp.path = path;
|
|
|
|
|
|
|
|
return rp;
|
|
}
|
|
|
|
public FilePath WithExtension( string extension, bool forceDot = true )
|
|
{
|
|
var rp = new FilePath();
|
|
|
|
rp.type = type;
|
|
rp.parent = parent;
|
|
|
|
if ( forceDot && ! extension.StartsWith( "." ) )
|
|
{
|
|
extension = "." + extension;
|
|
}
|
|
|
|
rp.path = Path.ChangeExtension( path, extension );
|
|
|
|
return rp;
|
|
}
|
|
|
|
public string absolutePath
|
|
{
|
|
get
|
|
{
|
|
return fullPath;
|
|
}
|
|
}
|
|
|
|
public string absoluteParentPath
|
|
{
|
|
get
|
|
{
|
|
return RegexUtility.ParentPath( fullPath );
|
|
}
|
|
}
|
|
|
|
public FilePath ChangeFileName( string fileName )
|
|
{
|
|
var parentPath = absoluteParentPath;
|
|
|
|
if ( ! parentPath.EndsWith( "/" ) )
|
|
{
|
|
parentPath += "/";
|
|
}
|
|
|
|
return Absolute( parentPath + fileName + fileExtension );
|
|
}
|
|
|
|
public FilePath AddToFileName( string fileNameAddition )
|
|
{
|
|
return ChangeFileName( fileName + fileNameAddition );
|
|
}
|
|
|
|
public static FilePath Absolute( string path )
|
|
{
|
|
return FilePath.Create( path, FilePathType.Absolute );
|
|
}
|
|
|
|
public FilePath CreateAbsoluteParent()
|
|
{
|
|
var path = this.fullPath;
|
|
|
|
return Absolute( RegexUtility.ParentPath( path ) );
|
|
}
|
|
|
|
|
|
public FilePath MakeRelative( string path )
|
|
{
|
|
return FilePath.Create( path, FilePathType.Relative, this );
|
|
}
|
|
|
|
|
|
public FilePath MakeAbsolutePathRelative( string otherAbsolutePath )
|
|
{
|
|
otherAbsolutePath = FilePath.Normalize( otherAbsolutePath );
|
|
var ownAbsolutePath = FilePath.Normalize( fullPath );
|
|
|
|
if ( ! otherAbsolutePath.StartsWith( ownAbsolutePath ) )
|
|
{
|
|
// A/B/C/D.x => own
|
|
// A/B/E/F.x => other
|
|
|
|
// A/B => common
|
|
|
|
// E/F => common relative
|
|
// /.. => own to common
|
|
// /../E/F => own to other
|
|
|
|
var commonPath = ownAbsolutePath.ExtractCommonStart( otherAbsolutePath );
|
|
var commonFilePath = FilePath.Absolute( commonPath );
|
|
var commonRelativeFilePath = commonFilePath.MakeAbsolutePathRelative( otherAbsolutePath );
|
|
|
|
|
|
var ownIsDir = Trillean.True == isDirectory || Trillean.False != isDirectory && fileExtension == "";
|
|
|
|
var itPath = ownAbsolutePath;
|
|
|
|
if ( ! ownIsDir )
|
|
{
|
|
itPath = absoluteParentPath;
|
|
}
|
|
|
|
itPath = itPath.ReplaceStart( commonPath );
|
|
var splits = RegexUtility.SplitPaths( itPath );
|
|
|
|
var dirs = "";
|
|
|
|
for ( int i = 0; i < splits.Count; i++ )
|
|
{
|
|
if ( i != 0 )
|
|
{
|
|
dirs += "/" ;
|
|
}
|
|
|
|
dirs += "..";
|
|
}
|
|
|
|
if ( ! commonRelativeFilePath.path.StartsWith( "/" ) )
|
|
{
|
|
dirs += "/";
|
|
}
|
|
|
|
// RJLog.Log(
|
|
// "\nown:", ownAbsolutePath,
|
|
// "\nother:", otherAbsolutePath,
|
|
// "\ncommonPath:", commonPath,
|
|
// "\ncommonRelativeFilePath:", commonRelativeFilePath.fullPath,
|
|
// "\ncommonRelativeFilePath.path:", commonRelativeFilePath.path,
|
|
// "\ndirs", dirs,
|
|
// "\nRelative:", dirs + commonRelativeFilePath.path
|
|
// );
|
|
|
|
|
|
|
|
return MakeRelative( dirs + commonRelativeFilePath.path );
|
|
}
|
|
|
|
// A/B/C
|
|
// A/B/C/D
|
|
var relativePath = otherAbsolutePath.Substring( ownAbsolutePath.Length );
|
|
|
|
relativePath = relativePath.ReplaceStart( "/" );
|
|
|
|
|
|
return MakeRelative( relativePath );
|
|
}
|
|
|
|
public FilePath CreateRelativeFromAbsolutePathWithParent( string absolutePath, FilePath absoluteParent )
|
|
{
|
|
var rp = new FilePath();
|
|
|
|
rp.type = FilePathType.Relative;
|
|
rp.parent = absoluteParent;
|
|
rp.path = Path.GetFileName( absolutePath );
|
|
rp._fullPath = absolutePath;
|
|
|
|
return rp;
|
|
|
|
}
|
|
|
|
public static string Normalize( string path, bool removeFirst = true, bool removeLast = true )
|
|
{
|
|
path = Regex.Replace( path, @"\\", "/" );
|
|
path = Regex.Replace( path, @"/+", "/" );
|
|
|
|
if ( removeFirst )
|
|
{
|
|
path = Regex.Replace( path, @"^/", "" );
|
|
}
|
|
|
|
if ( removeLast )
|
|
{
|
|
path = Regex.Replace( path, @"/$", "" );
|
|
}
|
|
|
|
|
|
|
|
return path;
|
|
}
|
|
|
|
public static string Join( params string[] paths )
|
|
{
|
|
var sb = new StringBuilder();
|
|
|
|
for ( int i = 0; i < paths.Length; i++ )
|
|
{
|
|
var path = paths[ i ];
|
|
|
|
path = Normalize( path );
|
|
|
|
if ( i != 0 )
|
|
{
|
|
sb.Append( "/" );
|
|
}
|
|
|
|
sb.Append( path );
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
}
|
|
} |