use an ArrayList in uri.pathRelative
This commit is contained in:
parent
adb012001f
commit
87bfa683bd
28
src/uri.zig
28
src/uri.zig
@ -51,43 +51,37 @@ pub fn fromPath(allocator: std.mem.Allocator, path: []const u8) ![]const u8 {
|
|||||||
|
|
||||||
/// Move along `rel` from `base` with a single allocation.
|
/// Move along `rel` from `base` with a single allocation.
|
||||||
/// `base` is a URI of a folder, `rel` is a raw relative path.
|
/// `base` is a URI of a folder, `rel` is a raw relative path.
|
||||||
pub fn pathRelative(allocator: std.mem.Allocator, base: []const u8, rel: []const u8) ![]const u8 {
|
pub fn pathRelative(allocator: std.mem.Allocator, base: []const u8, rel: []const u8) error{ OutOfMemory, UriBadScheme }![]const u8 {
|
||||||
const max_size = base.len + rel.len * 3 + 1;
|
const max_size = base.len + rel.len * 3 + 1;
|
||||||
|
|
||||||
var result = try allocator.alloc(u8, max_size);
|
var result = try std.ArrayListUnmanaged(u8).initCapacity(allocator, max_size);
|
||||||
errdefer allocator.free(result);
|
errdefer result.deinit(allocator);
|
||||||
|
|
||||||
|
result.appendSliceAssumeCapacity(base);
|
||||||
|
|
||||||
std.mem.copy(u8, result, base);
|
|
||||||
var result_index: usize = base.len;
|
|
||||||
var it = std.mem.tokenize(u8, rel, "/");
|
var it = std.mem.tokenize(u8, rel, "/");
|
||||||
while (it.next()) |component| {
|
while (it.next()) |component| {
|
||||||
if (std.mem.eql(u8, component, ".")) {
|
if (std.mem.eql(u8, component, ".")) {
|
||||||
continue;
|
continue;
|
||||||
} else if (std.mem.eql(u8, component, "..")) {
|
} else if (std.mem.eql(u8, component, "..")) {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (result_index == 0)
|
const char = result.popOrNull() orelse return error.UriBadScheme;
|
||||||
return error.UriBadScheme;
|
if (char == '/') break;
|
||||||
result_index -= 1;
|
|
||||||
if (result[result_index] == '/')
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result[result_index] = '/';
|
result.appendAssumeCapacity('/');
|
||||||
result_index += 1;
|
|
||||||
for (component) |char| {
|
for (component) |char| {
|
||||||
if (std.mem.indexOfScalar(u8, reserved_chars, char)) |reserved| {
|
if (std.mem.indexOfScalar(u8, reserved_chars, char)) |reserved| {
|
||||||
const escape = &reserved_escapes[reserved];
|
const escape = &reserved_escapes[reserved];
|
||||||
std.mem.copy(u8, result[result_index..], escape);
|
result.appendSliceAssumeCapacity(escape);
|
||||||
result_index += escape.len;
|
|
||||||
} else {
|
} else {
|
||||||
result[result_index] = char;
|
result.appendAssumeCapacity(char);
|
||||||
result_index += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return allocator.resize(result, result_index) orelse error.FailedResize;
|
return result.toOwnedSlice(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Original code: https://github.com/andersfr/zig-lsp/blob/master/uri.zig
|
// Original code: https://github.com/andersfr/zig-lsp/blob/master/uri.zig
|
||||||
|
Loading…
Reference in New Issue
Block a user