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.
 | 
			
		||||
/// `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;
 | 
			
		||||
 | 
			
		||||
    var result = try allocator.alloc(u8, max_size);
 | 
			
		||||
    errdefer allocator.free(result);
 | 
			
		||||
    var result = try std.ArrayListUnmanaged(u8).initCapacity(allocator, max_size);
 | 
			
		||||
    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, "/");
 | 
			
		||||
    while (it.next()) |component| {
 | 
			
		||||
        if (std.mem.eql(u8, component, ".")) {
 | 
			
		||||
            continue;
 | 
			
		||||
        } else if (std.mem.eql(u8, component, "..")) {
 | 
			
		||||
            while (true) {
 | 
			
		||||
                if (result_index == 0)
 | 
			
		||||
                    return error.UriBadScheme;
 | 
			
		||||
                result_index -= 1;
 | 
			
		||||
                if (result[result_index] == '/')
 | 
			
		||||
                    break;
 | 
			
		||||
                const char = result.popOrNull() orelse return error.UriBadScheme;
 | 
			
		||||
                if (char == '/') break;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            result[result_index] = '/';
 | 
			
		||||
            result_index += 1;
 | 
			
		||||
            result.appendAssumeCapacity('/');
 | 
			
		||||
            for (component) |char| {
 | 
			
		||||
                if (std.mem.indexOfScalar(u8, reserved_chars, char)) |reserved| {
 | 
			
		||||
                    const escape = &reserved_escapes[reserved];
 | 
			
		||||
                    std.mem.copy(u8, result[result_index..], escape);
 | 
			
		||||
                    result_index += escape.len;
 | 
			
		||||
                    result.appendSliceAssumeCapacity(escape);
 | 
			
		||||
                } else {
 | 
			
		||||
                    result[result_index] = char;
 | 
			
		||||
                    result_index += 1;
 | 
			
		||||
                    result.appendAssumeCapacity(char);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user