fn __zero_std_url_is_unreserved(byte: u8) -> Bool { return (byte >= 65_u8 && byte <= 90_u8) || (byte >= 97_u8 && byte <= 122_u8) || (byte >= 48_u8 && byte <= 57_u8) || byte == 45_u8 || byte == 46_u8 || byte == 95_u8 || byte == 126_u8 } fn __zero_std_url_hex_char(value: u8) -> u8 { if value < 10_u8 { return 48_u8 + value } return 65_u8 + value - 10_u8 } fn __zero_std_url_percent_encode(buffer: MutSpan, text: Span) -> Maybe> { var input: usize = 0 var output: usize = 0 while input < std.mem.len(text) { let byte: u8 = text[input] if __zero_std_url_is_unreserved(byte) { if output >= std.mem.len(buffer) { return null } buffer[output] = byte output = output + 1 } else { if output + 3 > std.mem.len(buffer) { return null } buffer[output] = 37_u8 buffer[output + 1] = __zero_std_url_hex_char(byte / 16_u8) buffer[output + 2] = __zero_std_url_hex_char(byte % 16_u8) output = output + 3 } input = input + 1 } return buffer[..output] } fn __zero_std_url_percent_decode(buffer: MutSpan, text: Span) -> Maybe> { var input: usize = 0 var output: usize = 0 while input < std.mem.len(text) { if output >= std.mem.len(buffer) { return null } let byte: u8 = text[input] if byte == 37_u8 { if input + 2 >= std.mem.len(text) { return null } let high: Maybe = std.ascii.hexValue(text[input + 1]) let low: Maybe = std.ascii.hexValue(text[input + 2]) if !high.has || !low.has { return null } buffer[output] = high.value * 16_u8 + low.value input = input + 3 } else { buffer[output] = byte input = input + 1 } output = output + 1 } return buffer[..output] } fn __zero_std_url_query_escape(buffer: MutSpan, text: Span) -> Maybe> { var input: usize = 0 var output: usize = 0 while input < std.mem.len(text) { let byte: u8 = text[input] if byte == 32_u8 { if output >= std.mem.len(buffer) { return null } buffer[output] = 43_u8 output = output + 1 } else if __zero_std_url_is_unreserved(byte) { if output >= std.mem.len(buffer) { return null } buffer[output] = byte output = output + 1 } else { if output + 3 > std.mem.len(buffer) { return null } buffer[output] = 37_u8 buffer[output + 1] = __zero_std_url_hex_char(byte / 16_u8) buffer[output + 2] = __zero_std_url_hex_char(byte % 16_u8) output = output + 3 } input = input + 1 } return buffer[..output] } fn __zero_std_url_query_unescape(buffer: MutSpan, text: Span) -> Maybe> { var input: usize = 0 var output: usize = 0 while input < std.mem.len(text) { if output >= std.mem.len(buffer) { return null } let byte: u8 = text[input] if byte == 43_u8 { buffer[output] = 32_u8 input = input + 1 } else if byte == 37_u8 { if input + 2 >= std.mem.len(text) { return null } let high: Maybe = std.ascii.hexValue(text[input + 1]) let low: Maybe = std.ascii.hexValue(text[input + 2]) if !high.has || !low.has { return null } buffer[output] = high.value * 16_u8 + low.value input = input + 3 } else { buffer[output] = byte input = input + 1 } output = output + 1 } return buffer[..output] } fn __zero_std_url_scheme(url: Span) -> Maybe> { var index: usize = 0 while index < std.mem.len(url) { let byte: u8 = url[index] if byte == 58_u8 { if index == 0 { return null } return url[..index] } if byte == 47_u8 || byte == 63_u8 || byte == 35_u8 { return null } index = index + 1 } return null } fn __zero_std_url_authority_start(url: Span) -> Maybe { let scheme: Maybe> = __zero_std_url_scheme(url) if !scheme.has { return null } let start: usize = std.mem.len(scheme.value) + 1 if start + 1 >= std.mem.len(url) || url[start] != 47_u8 || url[start + 1] != 47_u8 { return null } return start + 2 } fn __zero_std_url_authority(url: Span) -> Maybe> { let start: Maybe = __zero_std_url_authority_start(url) if !start.has { return null } var end: usize = start.value while end < std.mem.len(url) && url[end] != 47_u8 && url[end] != 63_u8 && url[end] != 35_u8 { end = end + 1 } if end == start.value { return null } return url[start.value..end] } fn __zero_std_url_host(url: Span) -> Maybe> { let authority: Maybe> = __zero_std_url_authority(url) if !authority.has { return null } var start: usize = 0 var index: usize = 0 while index < std.mem.len(authority.value) { if authority.value[index] == 64_u8 { start = index + 1 } index = index + 1 } if start < std.mem.len(authority.value) && authority.value[start] == 91_u8 { var close: usize = start + 1 while close < std.mem.len(authority.value) && authority.value[close] != 93_u8 { close = close + 1 } if close >= std.mem.len(authority.value) || close == start + 1 { return null } if close + 1 < std.mem.len(authority.value) && authority.value[close + 1] != 58_u8 { return null } return authority.value[start..close + 1] } var end: usize = start while end < std.mem.len(authority.value) && authority.value[end] != 58_u8 { end = end + 1 } if end == start { return null } return authority.value[start..end] } fn __zero_std_url_path(url: Span) -> Span { var start: usize = 0 let scheme: Maybe> = __zero_std_url_scheme(url) let authority_start: Maybe = __zero_std_url_authority_start(url) if authority_start.has { start = authority_start.value while start < std.mem.len(url) && url[start] != 47_u8 && url[start] != 63_u8 && url[start] != 35_u8 { start = start + 1 } } else if scheme.has { start = std.mem.len(scheme.value) + 1 } if start >= std.mem.len(url) { return url[std.mem.len(url)..] } var end: usize = start while end < std.mem.len(url) && url[end] != 63_u8 && url[end] != 35_u8 { end = end + 1 } return url[start..end] } fn __zero_std_url_query(url: Span) -> Maybe> { var start: usize = 0 while start < std.mem.len(url) && url[start] != 63_u8 { if url[start] == 35_u8 { return null } start = start + 1 } if start >= std.mem.len(url) { return null } start = start + 1 var end: usize = start while end < std.mem.len(url) && url[end] != 35_u8 { end = end + 1 } return url[start..end] } fn __zero_std_url_fragment(url: Span) -> Maybe> { var start: usize = 0 while start < std.mem.len(url) && url[start] != 35_u8 { start = start + 1 } if start >= std.mem.len(url) { return null } return url[start + 1..] } fn __zero_std_url_query_value(query: Span, key: Span) -> Maybe> { var start: usize = 0 while start <= std.mem.len(query) { var end: usize = start while end < std.mem.len(query) && query[end] != 38_u8 { end = end + 1 } var eq: usize = start while eq < end && query[eq] != 61_u8 { eq = eq + 1 } let name: Span = query[start..eq] if std.mem.eql(name, key) { if eq < end { return query[eq + 1..end] } return query[end..end] } if end == std.mem.len(query) { return null } start = end + 1 } return null } fn __zero_std_url_query_value_decoded(buffer: MutSpan, query: Span, key: Span) -> Maybe> { var start: usize = 0 while start <= std.mem.len(query) { var end: usize = start while end < std.mem.len(query) && query[end] != 38_u8 { end = end + 1 } var eq: usize = start while eq < end && query[eq] != 61_u8 { eq = eq + 1 } let name: Span = query[start..eq] var matched: Bool = std.mem.eql(name, key) if !matched { let decoded_name: Maybe> = __zero_std_url_query_unescape(buffer, name) if decoded_name.has { matched = std.mem.eql(decoded_name.value, key) } } if matched { if eq < end { return __zero_std_url_query_unescape(buffer, query[eq + 1..end]) } return buffer[..0] } if end == std.mem.len(query) { return null } start = end + 1 } return null } fn __zero_std_url_write_query_param(buffer: MutSpan, key: Span, value: Span) -> Maybe> { var output: usize = 0 let encoded_key: Maybe> = __zero_std_url_query_escape(buffer, key) if !encoded_key.has { return null } output = output + std.mem.len(encoded_key.value) if output >= std.mem.len(buffer) { return null } buffer[output] = 61_u8 output = output + 1 let encoded_value: Maybe> = __zero_std_url_query_escape(buffer[output..], value) if !encoded_value.has { return null } output = output + std.mem.len(encoded_value.value) return buffer[..output] } fn __zero_std_url_write_form_field(buffer: MutSpan, key: Span, value: Span) -> Maybe> { return __zero_std_url_write_query_param(buffer, key, value) } fn __zero_std_url_append_form_field(buffer: MutSpan, form: Span, field: Span) -> Maybe> { let form_len: usize = std.mem.len(form) let field_len: usize = std.mem.len(field) if form_len == 0_usize { if field_len > std.mem.len(buffer) { return null } var field_index: usize = 0 while field_index < field_len { buffer[field_index] = field[field_index] field_index = field_index + 1 } return buffer[..field_len] } if form_len >= std.mem.len(buffer) { return null } if field_len > std.mem.len(buffer) - form_len - 1_usize { return null } var output: usize = 0 while output < form_len { buffer[output] = form[output] output = output + 1 } buffer[output] = 38_u8 output = output + 1 var field_index: usize = 0 while field_index < field_len { buffer[output] = field[field_index] output = output + 1 field_index = field_index + 1 } return buffer[..output] } fn __zero_std_url_form_value(buffer: MutSpan, form: Span, key: Span) -> Maybe> { return __zero_std_url_query_value_decoded(buffer, form, key) } fn __zero_std_url_append_query(buffer: MutSpan, base: Span, query: Span) -> Maybe> { let base_len: usize = std.mem.len(base) if base_len >= std.mem.len(buffer) { return null } if std.mem.len(query) > std.mem.len(buffer) - base_len - 1 { return null } var fragment: usize = 0 while fragment < base_len && base[fragment] != 35_u8 { fragment = fragment + 1 } var output: usize = 0 while output < fragment { buffer[output] = base[output] output = output + 1 } var separator: u8 = 63_u8 var index: usize = 0 while index < fragment { if base[index] == 63_u8 { separator = 38_u8 } index = index + 1 } buffer[output] = separator output = output + 1 var query_index: usize = 0 while query_index < std.mem.len(query) { buffer[output] = query[query_index] output = output + 1 query_index = query_index + 1 } var fragment_index: usize = fragment while fragment_index < base_len { buffer[output] = base[fragment_index] output = output + 1 fragment_index = fragment_index + 1 } return buffer[..output] } fn __zero_std_url_write_url(buffer: MutSpan, scheme: Span, host: Span, path: Span) -> Maybe> { if std.mem.len(scheme) == 0 || std.mem.len(host) == 0 { return null } var output: usize = 0 let scheme_end: Maybe = __zero_std_url_write_span(buffer, output, scheme) if !scheme_end.has { return null } output = scheme_end.value let sep_end: Maybe = __zero_std_url_write_span(buffer, output, "://") if !sep_end.has { return null } output = sep_end.value let host_end: Maybe = __zero_std_url_write_span(buffer, output, host) if !host_end.has { return null } output = host_end.value if std.mem.len(path) > 0 { if path[0] != 47_u8 { let slash_end: Maybe = __zero_std_url_write_span(buffer, output, "/") if !slash_end.has { return null } output = slash_end.value } let path_end: Maybe = __zero_std_url_write_span(buffer, output, path) if !path_end.has { return null } output = path_end.value } return buffer[..output] } fn __zero_std_url_append_fragment(buffer: MutSpan, base: Span, fragment: Span) -> Maybe> { var output: usize = 0 let base_end: Maybe = __zero_std_url_write_span(buffer, output, base) if !base_end.has { return null } output = base_end.value let marker_end: Maybe = __zero_std_url_write_span(buffer, output, "#") if !marker_end.has { return null } output = marker_end.value let fragment_end: Maybe = __zero_std_url_write_span(buffer, output, fragment) if !fragment_end.has { return null } return buffer[..fragment_end.value] } fn __zero_std_url_write_span(buffer: MutSpan, cursor: usize, bytes: Span) -> Maybe { if cursor + std.mem.len(bytes) > std.mem.len(buffer) { return null } var index: usize = 0 while index < std.mem.len(bytes) { buffer[cursor + index] = bytes[index] index = index + 1 } return cursor + std.mem.len(bytes) }