Skip to content

Commit

Permalink
container/rbtree: remove pointer arg where not needed
Browse files Browse the repository at this point in the history
container/rbtree: fixes
  • Loading branch information
laytan committed Jan 6, 2025
1 parent 94e584a commit 0beaa32
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 79 deletions.
10 changes: 5 additions & 5 deletions core/container/rbtree/rbtree.odin
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ destroy :: proc(t: ^$T/Tree($Key, $Value), call_on_remove: bool = true) {
}
}

len :: proc "contextless" (t: ^$T/Tree($Key, $Value)) -> (node_count: int) {
len :: proc "contextless" (t: $T/Tree($Key, $Value)) -> (node_count: int) {
return t._size
}

Expand All @@ -108,7 +108,7 @@ last :: proc "contextless" (t: ^$T/Tree($Key, $Value)) -> ^Node(Key, Value) {
}

// find finds the key in the tree, and returns the corresponding node, or nil iff the value is not present.
find :: proc(t: ^$T/Tree($Key, $Value), key: Key) -> (node: ^Node(Key, Value)) {
find :: proc(t: $T/Tree($Key, $Value), key: Key) -> (node: ^Node(Key, Value)) {
node = t._root
for node != nil {
switch t._cmp_fn(key, node.key) {
Expand All @@ -121,7 +121,7 @@ find :: proc(t: ^$T/Tree($Key, $Value), key: Key) -> (node: ^Node(Key, Value)) {
}

// find_value finds the key in the tree, and returns the corresponding value, or nil iff the value is not present.
find_value :: proc(t: ^$T/Tree($Key, $Value), key: Key) -> (value: Value, ok: bool) #optional_ok {
find_value :: proc(t: $T/Tree($Key, $Value), key: Key) -> (value: Value, ok: bool) #optional_ok {
if n := find(t, key); n != nil {
return n.value, true
}
Expand Down Expand Up @@ -165,7 +165,7 @@ remove :: proc {
// removal was successful. While the node's key + value will be left intact,
// the node itself will be freed via the tree's node allocator.
remove_key :: proc(t: ^$T/Tree($Key, $Value), key: Key, call_on_remove := true) -> bool {
n := find(t, key)
n := find(t^, key)
if n == nil {
return false // Key not found, nothing to do
}
Expand Down Expand Up @@ -565,4 +565,4 @@ remove_case6 :: proc(t: ^$T/Tree($Key, $Value), n: ^$N/Node(Key, Value)) {

node_color :: proc(n: ^$N/Node($Key, $Value)) -> (c: Color) {
return n == nil ? .Black : n._color
}
}
9 changes: 4 additions & 5 deletions core/http/body.odin
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ body :: proc(sub: ^Has_Body, max_length: int, user_data: rawptr, cb: Body_Callba
sub._body.cbs.cb = cb
sub._body.cbs.user_data = user_data

enc_header, ok := headers_get(&sub.headers, "transfer-encoding")
enc_header, ok := headers_get(sub.headers, "transfer-encoding")
if ok && strings.has_suffix(enc_header, "chunked") {
_body_chunked(sub, max_length)
} else {
Expand Down Expand Up @@ -176,7 +176,7 @@ body_error_status :: proc(e: Body_Error) -> Status {
// "Decodes" a request body based on the content length header.
// Meant for internal usage, you should use `http.request_body`.
_body_length :: proc(sub: ^Has_Body, max_length: int = -1) {
len, ok := headers_get(&sub.headers, "content-length")
len, ok := headers_get(sub.headers, "content-length")
if !ok {
_body_do_cbs(sub, nil, nil)
return
Expand Down Expand Up @@ -309,9 +309,8 @@ _body_chunked :: proc(sub: ^Has_Body, max_length: int = -1) {
headers_delete(&s.sub.headers, "trailer")

s.sub.headers.readonly = false
dkey, dval := headers_delete(&s.sub.headers, "transfer-encoding")
new_val := strings.trim_suffix(dval, "chunked")
headers_set(&s.sub.headers, dkey, new_val)
entry := headers_entry(&s.sub.headers, "transfer-encoding")
entry^ = strings.trim_suffix(entry^, "chunked")
s.sub.headers.readonly = true

_body_do_cbs(s.sub, s.buf.buf[:], nil)
Expand Down
4 changes: 2 additions & 2 deletions core/http/client.odin
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ client_destroy :: proc(c: ^Client) {
_client_destroy(c)
}

response_destroy :: proc(c: ^Client, res: ^Client_Response) {
response_destroy :: proc(c: ^Client, res: Client_Response) {
_response_destroy(c, res)
}

Expand All @@ -101,7 +101,7 @@ Multi_Res :: struct {
responses_destroy :: proc(c: ^Client, s: []Multi_Res) {
for &res in s {
if res.err == nil {
response_destroy(c, &res.res)
response_destroy(c, res.res)
}
}
delete(s)
Expand Down
13 changes: 8 additions & 5 deletions core/http/client_other.odin
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ _client_destroy :: proc(c: ^Client) {
log.debug("client destroyed")
}

_response_destroy :: proc(c: ^Client, res: ^Client_Response) {
_response_destroy :: proc(c: ^Client, res: Client_Response) {
context.allocator = c.allocator
res := res

iter := headers_iterator(&res.headers)
for k, v in headers_next(&iter) {
Expand Down Expand Up @@ -382,7 +383,7 @@ _client_request :: proc(c: ^Client, req: Client_Request, user: rawptr, cb: On_Re
err := requestline_write(s, { method = r.method, target = r.url, version = {1, 1} })
assert(err == nil) // Only really can be an allocator error.

if !headers_has(&r.headers, "content-length") {
if !headers_has(r.headers, "content-length") {
buf_len := len(r.body)
if buf_len == 0 {
ws(buf, "content-length: 0\r\n")
Expand All @@ -402,15 +403,15 @@ _client_request :: proc(c: ^Client, req: Client_Request, user: rawptr, cb: On_Re
}
}

if !headers_has(&r.headers, "accept") {
if !headers_has(r.headers, "accept") {
ws(buf, "accept: */*\r\n")
}

if !headers_has(&r.headers, "user-agent") {
if !headers_has(r.headers, "user-agent") {
ws(buf, "user-agent: odin-http\r\n")
}

if !headers_has(&r.headers, "host") {
if !headers_has(r.headers, "host") {
ws(buf, "host: ")
ws(buf, url_parse(r.url).host)
ws(buf, "\r\n")
Expand Down Expand Up @@ -712,6 +713,8 @@ _client_request :: proc(c: ^Client, req: Client_Request, user: rawptr, cb: On_Re

if headers_cmp(key, "set-cookie") == .Equal {
dkey, dval := headers_delete(&r.conn.headers, "set-cookie")

// TODO: this allocation can be avoided by splitting header_parse into 2 procs (header_split, giving key and val slice, and another that allocates, checks etc.)
delete(dkey, r.c.allocator)

cookie, cok := cookie_parse(dval)
Expand Down
29 changes: 20 additions & 9 deletions core/http/headers.odin
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ headers_next :: proc(iter: ^Headers_Iterator) -> (key: string, val: string, ok:
return
}

headers_count :: #force_inline proc(h: ^Headers) -> int {
return rb.len(&h._kv)
headers_count :: #force_inline proc(h: Headers) -> int {
return rb.len(h._kv)
}

headers_set :: proc(h: ^Headers, k: string, v: string, loc := #caller_location) {
Expand All @@ -83,19 +83,19 @@ headers_set :: proc(h: ^Headers, k: string, v: string, loc := #caller_location)
assert(n.value == v)
}

headers_get :: proc(h: ^Headers, k: string) -> (string, bool) #optional_ok {
return rb.find_value(&h._kv, k)
headers_get :: proc(h: Headers, k: string) -> (string, bool) #optional_ok {
return rb.find_value(h._kv, k)
}

headers_has :: proc(h: ^Headers, k: string) -> bool {
n := rb.find(&h._kv, k)
headers_has :: proc(h: Headers, k: string) -> bool {
n := rb.find(h._kv, k)
return n != nil
}

headers_delete :: proc(h: ^Headers, k: string, loc := #caller_location) -> (deleted_key: string, deleted_value: string) {
assert(!h.readonly, "these headers are readonly, did you accidentally try to delete a header on the server request or client response?", loc)

n := rb.find(&h._kv, k)
n := rb.find(h._kv, k)
if n == nil {
return
}
Expand All @@ -107,6 +107,17 @@ headers_delete :: proc(h: ^Headers, k: string, loc := #caller_location) -> (dele
return
}

headers_entry :: proc(h: ^Headers, k: string, loc := #caller_location) -> (val: ^string) {
assert(!h.readonly, "these headers are readonly, did you accidentally try to get a header on the server request or client response?", loc)

n := rb.find(h._kv, k)
if n == nil {
return
}

return &n.value
}

/* Common Helpers */

headers_set_content_type :: proc {
Expand All @@ -130,7 +141,7 @@ headers_set_close :: #force_inline proc(h: ^Headers) {
headers_sanitize_for_server :: proc(headers: ^Headers) -> bool {
// RFC 7230 5.4: A server MUST respond with a 400 (Bad Request) status code to any
// HTTP/1.1 request message that lacks a Host header field.
if !headers_has(headers, "host") {
if !headers_has(headers^, "host") {
return false
}

Expand All @@ -145,7 +156,7 @@ headers_sanitize :: proc(headers: ^Headers) -> bool {
// the final encoding, the message body length cannot be determined
// reliably; the server MUST respond with the 400 (Bad Request)
// status code and then close the connection.
if enc_header, ok := headers_get(headers, "transfer-encoding"); ok {
if enc_header, ok := headers_get(headers^, "transfer-encoding"); ok {
strings.has_suffix(enc_header, "chunked") or_return

// RFC 7230 3.3.3: If a message is received with both a Transfer-Encoding and a
Expand Down
8 changes: 5 additions & 3 deletions core/http/http.odin
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ header_parse :: proc(headers: ^Headers, line: string, allocator := context.alloc

// RFC 7230 5.4: Server MUST respond with 400 to any request
// with multiple "Host" header fields.
if headers_cmp(key, "host") == .Equal && headers_has(headers, "host") {
if headers_cmp(key, "host") == .Equal && headers_has(headers^, "host") {
return
}

Expand All @@ -173,7 +173,7 @@ header_parse :: proc(headers: ^Headers, line: string, allocator := context.alloc
// invalid value, then the message framing is invalid and the
// recipient MUST treat it as an unrecoverable error.
if headers_cmp(key, "content-length") == .Equal {
if cl, has_cl := headers_get(headers, "content-length"); has_cl {
if cl, has_cl := headers_get(headers^, "content-length"); has_cl {
if cl != value {
return
}
Expand All @@ -194,6 +194,8 @@ allowed_trailers: Headers

@(private="file", init)
init_allowed_trailers :: proc() {
// TODO: maybe just check each of these in a loop instead.

headers_init(&allowed_trailers)
// Message framing:
headers_set(&allowed_trailers, "transfer-encoding", "")
Expand Down Expand Up @@ -240,7 +242,7 @@ init_allowed_trailers :: proc() {
// 7.1 of [RFC7231]), or determining how to process the payload (e.g.,
// Content-Encoding, Content-Type, Content-Range, and Trailer).
header_allowed_trailer :: proc(key: string) -> bool {
return headers_has(&allowed_trailers, key)
return headers_has(allowed_trailers, key)
}

@(private)
Expand Down
4 changes: 2 additions & 2 deletions core/http/request.odin
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Retrieves the cookie with the given `key` out of the request's `Cookie` header.
If the same key is in the header multiple times the last one is returned.
*/
request_cookie_get :: proc(r: ^Request, key: string) -> (value: string, ok: bool) {
cookies := headers_get(&r.headers, "cookie") or_return
cookies := headers_get(r.headers, "cookie") or_return

for k, v in request_cookies_iter(&cookies) {
if key == k { return v, true }
Expand All @@ -45,7 +45,7 @@ If the same key is in the header multiple times the last one is returned.
request_cookies :: proc(r: ^Request, allocator := context.temp_allocator) -> (res: map[string]string) {
res.allocator = allocator

cookies := headers_get(&r.headers, "cookie") or_else ""
cookies := headers_get(r.headers, "cookie") or_else ""
for k, v in request_cookies_iter(&cookies) {
// Don't overwrite, the iterator goes from right to left and we want the last.
if k in res { continue }
Expand Down
12 changes: 6 additions & 6 deletions core/http/response.odin
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ _response_write_heading :: proc(r: ^Response, content_length: int) {

MIN :: len("HTTP/1.1 200 \r\ndate: \r\ncontent-length: 1000\r\n") + DATE_LENGTH
AVG_HEADER_SIZE :: 20
reserve_size := MIN + content_length + (AVG_HEADER_SIZE * headers_count(&r.headers))
reserve_size := MIN + content_length + (AVG_HEADER_SIZE * headers_count(r.headers))
bytes.buffer_grow(&r._buf, reserve_size)

// According to RFC 7230 3.1.2 the reason phrase is insignificant,
Expand All @@ -242,15 +242,15 @@ _response_write_heading :: proc(r: ^Response, content_length: int) {
ws(b, "\r\n")

// Per RFC 9910 6.6.1 a Date header must be added in 2xx, 3xx, 4xx responses.
if r.status >= .OK && r.status <= .Internal_Server_Error && !headers_has(&r.headers, "date") {
if r.status >= .OK && r.status <= .Internal_Server_Error && !headers_has(r.headers, "date") {
ws(b, "date: ")
ws(b, server_date(conn.server))
ws(b, "\r\n")
}

if (
content_length > -1 &&
!headers_has(&r.headers, "content-length") &&
content_length > -1 &&
!headers_has(r.headers, "content-length") &&
response_needs_content_length(r, conn) \
) {
if content_length == 0 {
Expand Down Expand Up @@ -433,12 +433,12 @@ response_needs_content_length :: proc(r: ^Response, conn: ^Connection) -> bool {
@(private)
response_must_close :: proc(req: ^Request, res: ^Response) -> bool {
// If the request we are responding to indicates it is closing the connection, close our side too.
if req, req_has := headers_get(&req.headers, "connection"); req_has && req == "close" {
if req, req_has := headers_get(req.headers, "connection"); req_has && req == "close" {
return true
}

// If we are responding with a close connection header, make sure we close.
if res, res_has := headers_get(&res.headers, "connection"); res_has && res == "close" {
if res, res_has := headers_get(res.headers, "connection"); res_has && res == "close" {
return true
}

Expand Down
2 changes: 1 addition & 1 deletion core/http/server.odin
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,7 @@ conn_handle_req :: proc(c: ^Connection, allocator := context.temp_allocator) {
l.conn.scanner.max_token_size = bufio.DEFAULT_MAX_SCAN_TOKEN_SIZE

// Automatically respond with a continue status when the client has the Expect: 100-continue header.
if expect, ok := headers_get(&l.req.headers, "expect");
if expect, ok := headers_get(l.req.headers, "expect");
ok && expect == "100-continue" && l.conn.server.opts.auto_expect_continue {

l.res.status = .Continue
Expand Down
Loading

0 comments on commit 0beaa32

Please sign in to comment.