Browse Source

add new static methods to Path: normalize(...) and join(...)

Christopher Kaster 11 năm trước cách đây
mục cha
commit
6317a72d7d
1 tập tin đã thay đổi với 88 bổ sung29 xóa
  1. 88 29
      std/haxe/io/Path.hx

+ 88 - 29
std/haxe/io/Path.hx

@@ -24,7 +24,7 @@ package haxe.io;
 /**
 	This class provides a convenient way of working with paths. It supports the
 	common path formats:
-		
+
 	- directory1/directory2/filename.extension
 	- directory1\directory2\filename.excention
 **/
@@ -32,36 +32,36 @@ class Path {
 
 	/**
 		The directory.
-		
+
 		This is the leading part of the path that is not part of the file name
 		and the extension.
-		
+
 		Does not end with a `/` or `\` separator.
-		
+
 		If the path has no directory, the value is null.
 	**/
 	public var dir : String;
-	
+
 	/**
 		The file name.
-		
+
 		This is the part of the part between the directory and the extension.
-		
+
 		If there is no file name, e.g. for ".htaccess" or "/dir/", the value
 		is the empty String "".
 	**/
 	public var file : String;
-	
+
 	/**
 		The file extension.
-		
+
 		It is separated from the file name by a dot. This dot is not part of
 		the extension.
-		
+
 		If the path has no extension, the value is null.
 	**/
 	public var ext : String;
-		
+
 	/**
 		True if the last directory separator is a backslash, false otherwise.
 	**/
@@ -69,7 +69,7 @@ class Path {
 
 	/**
 		Creates a new Path instance by parsing `path`.
-		
+
 		Path information can be retrieved by accessing the dir, file and ext
 		properties.
 	**/
@@ -97,11 +97,11 @@ class Path {
 
 	/**
 		Returns a String representation of `this` path.
-		
+
 		If `this.backslash` is true, backslash is used as directory separator,
 		otherwise slash is used. This only affects the separator between
 		`this.dir` and `this.file`.
-		
+
 		If `this.directory` or `this.extension` is null, their representation
 		is the empty String "".
 	**/
@@ -111,7 +111,7 @@ class Path {
 
 	/**
 		Returns the String representation of `path` without the file extension.
-		
+
 		If `path` is null, the result is unspecified.
 	**/
 	public static function withoutExtension( path : String ) {
@@ -122,7 +122,7 @@ class Path {
 
 	/**
 		Returns the String representation of `path` without the directory.
-		
+
 		If `path` is null, the result is unspecified.
 	**/
 	public static function withoutDirectory( path ) {
@@ -133,9 +133,9 @@ class Path {
 
 	/**
 		Returns the directory of `path`.
-		
+
 		If the directory is null, the empty String "" is returned.
-		
+
 		If `path` is null, the result is unspecified.
 	**/
 	public static function directory( path ) {
@@ -147,9 +147,9 @@ class Path {
 
 	/**
 		Returns the extension of `path`.
-		
+
 		If the extension is null, the empty String "" is returned.
-		
+
 		If `path` is null, the result is unspecified.
 	**/
 	public static function extension( path ) {
@@ -161,9 +161,9 @@ class Path {
 
 	/**
 		Returns a String representation of `path` where the extension is `ext`.
-		
+
 		If `path` has no extension, `ext` is added as extension.
-		
+
 		If `path` or `ext` are null, the result is unspecified.
 	**/
 	public static function withExtension( path, ext ) {
@@ -172,16 +172,75 @@ class Path {
 		return s.toString();
 	}
 
+	/**
+		Join two paths together and normalize them
+
+		e.g. 'assets/maps' and '../textures/img.png' = 'assets/textures/img.png'
+	**/
+	public static function join( path1 : String, path2 : String ) : String {
+		path1 = Path.addTrailingSlash(path1);
+
+		return Path.normalize(path1 + path2);
+	}
+
+	/**
+		Normalize a given `path` (e.g. make '/your/fancy/../path' to '/your/path')
+	**/
+	public static function normalize( path : String, ?forceSlash : Bool = false ) : String {
+		var slash = '/';
+
+		if( this.backslash && !forceSlash ) {
+			slash = '\\';
+		}
+
+		if( forceSlash ) {
+			// replace backslashes
+			path = StringUtils.replace(path, '\\', '/');
+		}
+
+		if( path == null || path == slash ) {
+			return slash;
+		}
+
+		var prependSlash = (path.charAt(0) == slash ||
+			path.charAt(0) == '.');
+		var target = [];
+		var src;
+		var parts;
+		var token;
+
+		src = path.split(slash);
+
+		for( i in 0...src.length ) {
+			token = src[i];
+
+			if(token == '..') {
+				target.pop();
+			} else if(token != '' && token != '.') {
+				target.push(token);
+			}
+		}
+
+		var regex = ~/[\/]{2,}/g;
+
+		var tmp = target.join(slash);
+
+		var result = regex.replace(tmp, slash);
+
+		return (prependSlash ? slash : '') + result;
+	}
+
+
 	/**
 		Adds a trailing slash to `path`, if it does not have one already.
-		
+
 		If the last slash in `path` is a backslash, a backslash is appended to
 		`path`.
-		
+
 		If the last slash in `path` is a slash, or if no slash is found, a slash
 		is appended to `path`. In particular, this applies to the empty String
 		"".
-		
+
 		If `path` is null, the result is unspecified.
 	**/
 	public static function addTrailingSlash( path : String ) : String {
@@ -197,15 +256,15 @@ class Path {
 			else path;
 		}
 	}
-	
+
 	/**
 		Removes trailing slashes from `path`.
-		
+
 		If `path` does not end with a `/` or `\`, `path` is returned unchanged.
-		
+
 		Otherwise the substring of `path` excluding the trailing slashes or
 		backslashes is returned.
-		
+
 		If `path` is null, the result is unspecified.
 	**/
 	@:require(haxe_ver >= 3.01)