From 8ca621f38f1901eed5deb925bfbe5dd51635543e Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 2 Jun 2023 11:49:13 +0200 Subject: [PATCH] message: move header functions around --- message/header.ha | 111 +++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 55 deletions(-) diff --git a/message/header.ha b/message/header.ha index c54bc3c..f664f90 100644 --- a/message/header.ha +++ b/message/header.ha @@ -9,61 +9,6 @@ use strings; use strio; use types; -export def HEADER_BUCKETS: u64 = 16; - -export type header_field = struct { - raw: []u8, - key: str, - val: str, -}; - -// Initializes a new header field, duplicating the provided parameters. -fn new_header_field(key: str, val: str, raw: []u8) header_field = { - return header_field { - raw = alloc(raw...), - key = canonical_mime_header_key(key), - val = strings::dup(val), - }; -}; - -fn header_field_destroy(hf: *header_field) void = { - free(hf.raw); - free(hf.key); - free(hf.val); - free(hf); -}; - -// Returns the raw representation of this header field, including CRLF. The -// return value is borrowed from the header field. -fn header_field_raw(hf: *header_field) ([]u8 | errors::invalid) = { - if (len(hf.raw) != 0) { - return hf.raw; - }; - - const iter = strings::iter(hf.key); - for (true) { - const rn = match (strings::next(&iter)) { - case let rn: rune => - yield rn; - case void => - break; - }; - - if (!ascii::isprint(rn) || rn == ':') { - return errors::invalid; - }; - }; - - if (strings::contains(hf.val, "\r\n")) { - return errors::invalid; - }; - - let sink = bufio::dynamic(io::mode::WRITE); - header_field_fmt(&sink, hf)!; - hf.raw = bufio::buffer(&sink); - return hf.raw; -}; - export type header = struct { fields: []*header_field, map: [HEADER_BUCKETS][]header_map_key, @@ -74,6 +19,14 @@ export type header_map_key = struct { fields: []*header_field, }; +export def HEADER_BUCKETS: u64 = 16; + +export type header_field = struct { + raw: []u8, + key: str, + val: str, +}; + // Creates a new message header. The representation is idempotent, such that // whitespace and field ordering is preserved. export fn new_header() header = { @@ -384,6 +337,54 @@ export fn write_header(sink: io::handle, head: *header) (size | io::error) = { assert(result == expect); }; +// Initializes a new header field, duplicating the provided parameters. +fn new_header_field(key: str, val: str, raw: []u8) header_field = { + return header_field { + raw = alloc(raw...), + key = canonical_mime_header_key(key), + val = strings::dup(val), + }; +}; + +fn header_field_destroy(hf: *header_field) void = { + free(hf.raw); + free(hf.key); + free(hf.val); + free(hf); +}; + +// Returns the raw representation of this header field, including CRLF. The +// return value is borrowed from the header field. +fn header_field_raw(hf: *header_field) ([]u8 | errors::invalid) = { + if (len(hf.raw) != 0) { + return hf.raw; + }; + + const iter = strings::iter(hf.key); + for (true) { + const rn = match (strings::next(&iter)) { + case let rn: rune => + yield rn; + case void => + break; + }; + + if (!ascii::isprint(rn) || rn == ':') { + return errors::invalid; + }; + }; + + if (strings::contains(hf.val, "\r\n")) { + return errors::invalid; + }; + + let sink = bufio::dynamic(io::mode::WRITE); + header_field_fmt(&sink, hf)!; + hf.raw = bufio::buffer(&sink); + return hf.raw; +}; + + def PREFERRED_HEADER_LEN = 76z; def MAX_HEADER_LEN = 998z; -- 2.45.2