diff options
author | Nathan Woltman <nwoltman@outlook.com> | 2014-11-21 11:22:07 +0300 |
---|---|---|
committer | Bert Belder <bertbelder@gmail.com> | 2014-12-09 19:57:09 +0300 |
commit | 50d7401244c5e70893daf6580d185b13b4e1fe75 (patch) | |
tree | a5e32eb936eee79dd433b97e9524e0a8d901f10c /lib/path.js | |
parent | 9483bfe6e3e84c3eee3056ac3a78d38cbb39d7b6 (diff) |
path: refactor normalizeArray()
The normalizeArray() function now avoids using the slow Array#splice()
method to improve performance and now also filters out empty path parts.
Code that pre-filtered empty parts has been removed.
PR-URL: https://github.com/joyent/node/pull/8724
Reviewed-by: Trevor Norris <trev.norris@gmail.com>
Diffstat (limited to 'lib/path.js')
-rw-r--r-- | lib/path.js | 64 |
1 files changed, 23 insertions, 41 deletions
diff --git a/lib/path.js b/lib/path.js index c7a5f037176..1972bdc601a 100644 --- a/lib/path.js +++ b/lib/path.js @@ -26,33 +26,30 @@ var util = require('util'); // resolves . and .. elements in a path array with directory names there -// must be no slashes, empty elements, or device names (c:\) in the array +// must be no slashes or device names (c:\) in the array // (so also no leading and trailing slashes - it does not distinguish // relative and absolute paths) function normalizeArray(parts, allowAboveRoot) { - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } + var res = []; + for (var i = 0; i < parts.length; i++) { + var p = parts[i]; + + // ignore empty parts + if (!p || p === '.') + continue; - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up--; up) { - parts.unshift('..'); + if (p === '..') { + if (res.length && res[res.length - 1] !== '..') { + res.pop(); + } else if (allowAboveRoot) { + res.push('..'); + } + } else { + res.push(p); } } - return parts; + return res; } // Regex to split a windows path into three parts: [*, device, slash, @@ -154,12 +151,7 @@ win32.resolve = function() { // fails) // Normalize the tail path - - function f(p) { - return !!p; - } - - resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/).filter(f), + resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/), !resolvedAbsolute).join('\\'); return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) || @@ -176,9 +168,7 @@ win32.normalize = function(path) { trailingSlash = /[\\\/]$/.test(tail); // Normalize the tail path - tail = normalizeArray(tail.split(/[\\\/]+/).filter(function(p) { - return !!p; - }), !isAbsolute).join('\\'); + tail = normalizeArray(tail.split(/[\\\/]+/), !isAbsolute).join('\\'); if (!tail && !isAbsolute) { tail = '.'; @@ -443,9 +433,8 @@ posix.resolve = function() { // handle relative paths to be safe (might happen when process.cwd() fails) // Normalize the path - resolvedPath = normalizeArray(resolvedPath.split('/').filter(function(p) { - return !!p; - }), !resolvedAbsolute).join('/'); + resolvedPath = normalizeArray(resolvedPath.split('/'), + !resolvedAbsolute).join('/'); return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; }; @@ -454,17 +443,10 @@ posix.resolve = function() { // posix version posix.normalize = function(path) { var isAbsolute = posix.isAbsolute(path), - trailingSlash = path.substr(-1) === '/', - segments = path.split('/'), - nonEmptySegments = []; + trailingSlash = path.substr(-1) === '/'; // Normalize the path - for (var i = 0; i < segments.length; i++) { - if (segments[i]) { - nonEmptySegments.push(segments[i]); - } - } - path = normalizeArray(nonEmptySegments, !isAbsolute).join('/'); + path = normalizeArray(path.split('/'), !isAbsolute).join('/'); if (!path && !isAbsolute) { path = '.'; |