hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 85ed033a0ec3a8ff8e92bb326d524096103aa97f
parent bea9ed5e688358aa669072cf8ef840606eef4235
Author: Sebastian <sebastian@sebsite.pw>
Date:   Tue, 17 Oct 2023 21:09:33 -0400

encoding::pem: restructure decoder

Prior to this commit, pemdecoder used an awful hack in which, when
initialized, the b64 field was forcefully zeroed, and a bool b64_ready
was used so b64 could actually be set the first time the stream was read
from. This was necessary since a base64::decoder needs to be initialized
with an *io::stream, but the io::stream being used was part of the
pemdecoder which hasn't been returned yet, so its address couldn't be
taken.

This is solved by storing a bufio::stream (non-pointer) in b64stream,
and storing and initializing a b64stream in decoder (replacing the
bufio::stream in decoder). This way, since the stream is stored in the
decoder which is already owned, the address can be taken for the
base64::decoder in the pemdecoder. This also allows the same b64stream
to be reused, rather than creating a new one every time `next` is
called.

Additionally, the 'in' field of pemdecoder can be removed, since it just
duplicates a field already stored in base64::decoder.

Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Mencoding/pem/pem.ha | 34+++++++++++-----------------------
1 file changed, 11 insertions(+), 23 deletions(-)

diff --git a/encoding/pem/pem.ha b/encoding/pem/pem.ha @@ -17,23 +17,19 @@ const end: str = "-----END "; const suffix: str = "-----"; export type decoder = struct { - in: bufio::stream, + in: b64stream, label: memio::stream, buf: []u8, }; export type b64stream = struct { stream: io::stream, - in: *bufio::stream, + in: bufio::stream, }; export type pemdecoder = struct { stream: io::stream, - in: *bufio::stream, - b64_in: b64stream, b64: base64::decoder, - // XXX: kind of dumb but it saves us some memory management problems - b64_ready: bool, }; const pemdecoder_vt: io::vtable = io::vtable { @@ -51,7 +47,10 @@ const b64stream_r_vt: io::vtable = io::vtable { export fn newdecoder(in: io::handle) decoder = { let buf: []u8 = alloc([0...], os::BUFSZ); return decoder { - in = bufio::init(in, buf, []), + in = b64stream { + stream = &b64stream_r_vt, + in = bufio::init(in, buf, []), + }, buf = buf, label = memio::dynamic(), }; @@ -86,7 +85,7 @@ export fn next(dec: *decoder) ((str, pemdecoder) | io::EOF | io::error) = { for (true) { // XXX: This can be improved following // https://todo.sr.ht/~sircmpwn/hare/562 - const line = match (bufio::read_line(&dec.in)?) { + const line = match (bufio::read_line(&dec.in.in)?) { case io::EOF => return io::EOF; case let line: []u8 => @@ -112,14 +111,7 @@ export fn next(dec: *decoder) ((str, pemdecoder) | io::EOF | io::error) = { return (memio::string(&dec.label)!, pemdecoder { stream = &pemdecoder_vt, - in = &dec.in, - b64_in = b64stream { - stream = &b64stream_r_vt, - in = &dec.in, - }, - // forcefully zero field (it's actually set in pem_read) - b64 = *(&([0...]: [size(base64::decoder)]u8): *base64::decoder), - b64_ready = false, + b64 = base64::newdecoder(&base64::std_encoding, &dec.in), }); }; @@ -133,10 +125,6 @@ fn pem_read(st: *io::stream, buf: []u8) (size | io::EOF | io::error) = { // -----END. const st = st: *pemdecoder; assert(st.stream.reader == &pem_read); - if (!st.b64_ready) { - st.b64 = base64::newdecoder(&base64::std_encoding, &st.b64_in); - st.b64_ready = true; - }; match (io::read(&st.b64, buf)?) { case let z: size => @@ -145,7 +133,7 @@ fn pem_read(st: *io::stream, buf: []u8) (size | io::EOF | io::error) = { yield; }; - const line = match (bufio::read_line(st.in)?) { + const line = match (bufio::read_line(st.b64.in)?) { case io::EOF => return io::EOF; case let line: []u8 => @@ -173,7 +161,7 @@ fn b64_read(st: *io::stream, buf: []u8) (size | io::EOF | io::error) = { const st = st: *b64stream; assert(st.stream.reader == &b64_read); - const z = match (io::read(st.in, buf)?) { + const z = match (io::read(&st.in, buf)?) { case let z: size => yield z; case io::EOF => @@ -184,7 +172,7 @@ fn b64_read(st: *io::stream, buf: []u8) (size | io::EOF | io::error) = { let sub = buf[..z]; for (let i = 0z; i < len(sub); i += 1) { if (sub[i] == '-') { - bufio::unread(st.in, sub[i..]); + bufio::unread(&st.in, sub[i..]); sub = sub[..i]; break; };