提交 4c751647 编写于 作者: J Johannes Rieken

fix issues with getRootLength, start with normalize2 that doesn't allocate arrays

上级 0a5223be
......@@ -74,6 +74,56 @@ export function normalize(path: string, toOSPath?: boolean): string {
return parts.join(toOSPath ? nativeSep : sep);
}
export function normalize2(path: string, toOSPath?: boolean): string {
if (path === null || path === void 0) {
return path;
}
let len = path.length;
if (len === 0) {
return '.';
}
let rootLen = getRootLength(path);
let head = path.slice(0, rootLen);
let tail = '';
// operate on the 'path-portion' only
path = path.slice(rootLen);
let sep = isWindows && toOSPath ? '\\' : '/';
let start = 0;
for (let end = 0; end <= len; end++) {
let code = path.charCodeAt(end);
if (code === _slash || code === _backslash || end === len) {
let part = path.slice(start, end);
start = end + 1;
if (part === '..') {
// skip current and remove parent (if applicable)
let prev_start = tail.lastIndexOf(sep);
let prev_part = tail.slice(prev_start + 1);
if (prev_part.length > 0 && prev_part !== '..') {
tail = prev_start === -1 ? '' : tail.slice(0, prev_start);
continue;
}
}
if (tail !== '' && tail[tail.length - 1] !== sep) {
tail += sep;
}
tail += part;
}
}
// res += path.slice(start);
return head + tail;
}
/**
* @returns the directory name of a path.
*/
......@@ -130,20 +180,24 @@ export function getRootLength(path: string): number {
// UNC candidate \\localhost\shares\ddd
// ^^^^^^^^^^^^^^^^^^^
let pos = 2;
let start = pos;
for (; pos < len; pos++) {
code = path.charCodeAt(pos);
if (code === _slash || code === _backslash) {
break;
}
}
if (start !== pos) {
pos += 1;
code = path.charCodeAt(2);
if (code !== _slash && code !== _backslash) {
let pos = 3;
let start = pos;
for (; pos < len; pos++) {
code = path.charCodeAt(pos);
if (code === _slash || code === _backslash) {
return pos + 1; // consume this separator
break;
}
}
code = path.charCodeAt(pos + 1);
if (start !== pos && code !== _slash && code !== _backslash) {
pos += 1;
for (; pos < len; pos++) {
code = path.charCodeAt(pos);
if (code === _slash || code === _backslash) {
return pos + 1; // consume this separator
}
}
}
}
......
......@@ -53,6 +53,29 @@ suite('Paths', () => {
assert.equal(paths.normalize('/foo/bar.test'), '/foo/bar.test');
});
test('normalize2', () => {
assert.equal(paths.normalize2('foo/bar/../far'), 'foo/far');
assert.equal(paths.normalize2('foo/bar/../../far'), 'far');
assert.equal(paths.normalize2('../far'), '../far');
assert.equal(paths.normalize2('../../far'), '../../far');
assert.equal(paths.normalize2('foo/xxx/..'), 'foo');
assert.equal(paths.normalize2('foo/xxx/../bar'), 'foo/bar');
assert.equal(paths.normalize2('foo/../../bar'), '../bar');
assert.equal(paths.normalize2('foo/far/../../bar'), 'bar');
assert.equal(paths.normalize2(undefined), undefined);
assert.equal(paths.normalize2(null), null);
assert.equal(paths.normalize2(''), '.');
assert.equal(paths.normalize2('.'), '.');
assert.equal(paths.normalize2('foo/'), 'foo/');
assert.equal(paths.normalize2('foo//'), 'foo/');
assert.equal(paths.normalize2('//foo'), '/foo');
assert.equal(paths.normalize2('//foo//'), '/foo/');
assert.equal(paths.normalize2('foo//bar'), 'foo/bar');
assert.equal(paths.normalize2('foo//bar/far'), 'foo/bar/far');
assert.equal(paths.normalize2('///'), '/');
assert.equal(paths.normalize2('\\\\\\'), '\\');
});
test('getRootLength', () => {
assert.equal(paths.getRootLength('/user/far'), 1);
......@@ -60,6 +83,7 @@ suite('Paths', () => {
assert.equal(paths.getRootLength('//server/share/some/path'), 15);
assert.equal(paths.getRootLength('//server/share'), 1);
assert.equal(paths.getRootLength('//server'), 1);
assert.equal(paths.getRootLength('//server//'), 1);
assert.equal(paths.getRootLength('c:/user/far'), 3);
assert.equal(paths.getRootLength('c:user/far'), 2);
assert.equal(paths.getRootLength('http://wwww'), 0);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册