@@ -5,6 +5,8 @@ const Uri = std.Uri;
55const ParseError = std .Uri .ParseError ;
66const StringHashMap = @import ("std" ).StringHashMap ;
77
8+ const Values = @import ("values.zig" ).Values ;
9+
810pub const URL = @This ();
911
1012allocator : std.mem.Allocator = std .heap .page_allocator ,
@@ -14,14 +16,15 @@ host: ?[]const u8 = undefined,
1416path : []const u8 = "/" ,
1517fragment : ? []const u8 = undefined ,
1618query : ? []const u8 = undefined ,
17- querymap : ? StringHashMap ([]const u8 ) = StringHashMap ([]const u8 ).init (std .heap .page_allocator ),
19+
20+ // querymap: ?StringHashMap(std.ArrayList([]const u8)) = StringHashMap(std.ArrayList([]const u8)).init(std.heap.page_allocator),
21+ values : ? std .StringHashMap (std .ArrayList ([]const u8 )) = std .StringHashMap (std .ArrayList ([]const u8 )).init (std .heap .page_allocator ),
1822
1923// https://developer.mozilla.org/en-US/docs/Learn/Common_questions/Web_mechanics/What_is_a_URL
2024
2125pub fn init (self : URL ) URL {
2226 return .{
2327 .allocator = self .allocator ,
24- // .uri = self.uri,
2528 // .querymap = self.querymap,
2629 };
2730}
@@ -67,7 +70,7 @@ pub fn parseUrl(self: *URL, text: []const u8) ParseError!*URL {
6770 if ((reader .peek () orelse 0 ) == '?' ) { // query part
6871 std .debug .assert (reader .get ().? == '?' );
6972 self .query = reader .readUntil (isQuerySeparator );
70- self . querymap = parseQuery (self .query .? );
73+ try parseQuery (& self . values .? , self .query .? );
7174 }
7275
7376 if ((reader .peek () orelse 0 ) == '#' ) { // fragment part
@@ -90,7 +93,7 @@ fn uriToUrl(self: *URL, uri: Uri) void {
9093
9194 if (uri .query != null ) {
9295 self .query = @constCast (uri .query .? .percent_encoded );
93- self . querymap = parseQuery (@constCast (uri .query .? .percent_encoded ));
96+ try parseQuery (& self . values .? , @constCast (uri .query .? .percent_encoded ));
9497 }
9598 if (uri .fragment != null ) {
9699 self .fragment = @constCast (uri .fragment .? .percent_encoded );
@@ -104,8 +107,7 @@ pub fn parseUri(self: *URL, text: []const u8) ParseError!*URL {
104107 return self ;
105108}
106109
107- pub fn parseQuery (uri_query : []const u8 ) StringHashMap ([]const u8 ) {
108- var querymap = StringHashMap ([]const u8 ).init (std .heap .page_allocator );
110+ pub fn parseQuery (map : * std .StringHashMap (std .ArrayList ([]const u8 )), uri_query : []const u8 ) ! void {
109111 var queryitmes = std .mem .splitSequence (u8 , uri_query , "&" );
110112 while (true ) {
111113 const pair = queryitmes .next ();
@@ -114,19 +116,31 @@ pub fn parseQuery(uri_query: []const u8) StringHashMap([]const u8) {
114116 }
115117 var kv = std .mem .splitSequence (u8 , pair .? , "=" );
116118 if (kv .buffer .len == 0 ) {
117- break ;
119+ continue ;
118120 }
119121 const key = kv .next ();
120122 if (key == null ) {
121- break ;
123+ continue ;
122124 }
125+
123126 const value = kv .next ();
124127 if (value == null ) {
125- break ;
128+ continue ;
129+ }
130+
131+ var al : std .ArrayList ([]const u8 ) = undefined ;
132+ const v = map .get (key .? );
133+ if (v == null ) {
134+ al = std .ArrayList ([]const u8 ).init (std .heap .page_allocator );
135+ al .append (value .? ) catch continue ;
136+ map .put (key .? , al ) catch continue ;
137+ continue ;
126138 }
127- querymap .put (key .? , value .? ) catch break ;
139+
140+ al = v .? ;
141+ al .append (value .? ) catch continue ;
142+ map .put (key .? , al ) catch continue ;
128143 }
129- return querymap ;
130144}
131145
132146fn isAuthoritySeparator (c : u8 ) bool {
0 commit comments