diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-08-09 06:25:14 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-08-09 06:25:14 -0700 |
commit | e63c561a145103a94efbc49e7c6a1061dd8464f4 (patch) | |
tree | 39f295a7e09d052c51765f60f7ac77a6905f8b93 | |
parent | 46bc67ee1b42f8f7587e87b0ba604e0541bd24f1 (diff) | |
download | txr-e63c561a145103a94efbc49e7c6a1061dd8464f4.tar.gz txr-e63c561a145103a94efbc49e7c6a1061dd8464f4.tar.bz2 txr-e63c561a145103a94efbc49e7c6a1061dd8464f4.zip |
base64 funtions: factor out stream filtering internals.
The base64_encode and base64_decode functions internally work
with streams. This change factors out those internals into
separate functions (with the intent that these will be
usefully exposed, in another commit).
* filter.c (base64_stream_enc): New function, made out of
the internals of base64_encode.
(base64_encode): Simple wrapper for base64_stream_enc.
(base64_stream_dec): New function, made out of
the internals of base64_decode.
(base64_decode): Simple wrapper for base64_stream_dec.
* filter.h (base64_stream_enc, base64_stream_dec): Declared.
-rw-r--r-- | filter.c | 49 | ||||
-rw-r--r-- | filter.h | 3 |
2 files changed, 37 insertions, 15 deletions
@@ -735,27 +735,26 @@ INLINE void col_check(cnum *pcol, cnum wcol, val out) } } -val base64_encode(val str, val wrap_cols) +val base64_stream_enc(val out, val in, val nbytes, val wrap_cols) { static const char *b64 = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" }; + int ulim = nilp(default_null_arg(nbytes)); cnum col = 0; + cnum nb = if3(ulim, 0, c_num(nbytes)); cnum wcol = c_num(default_arg(wrap_cols, zero)); - val in_byte = make_string_byte_input_stream(str); - val out = make_string_output_stream(); - for (;;) { - val bv0 = get_byte(in_byte); - val bv1 = get_byte(in_byte); - val bv2 = get_byte(in_byte); + for (; ulim || nb > 0; ulim ? --nb : 0) { + val bv0 = get_byte(in); + val bv1 = if2(bv0 && (ulim || --nb > 0), get_byte(in)); + val bv2 = if2(bv1 && (ulim || --nb > 0), get_byte(in)); if (bv2) { cnum b0 = c_num(bv0); cnum b1 = c_num(bv1); cnum b2 = c_num(bv2); cnum word = (b0 << 16) | (b1 << 8) | b2; - put_char(chr(b64[(word >> 18) ]), out); col_check(&col, wcol, out); put_char(chr(b64[(word >> 12) & 0x3F]), out); col_check(&col, wcol, out); put_char(chr(b64[(word >> 6) & 0x3F]), out); col_check(&col, wcol, out); @@ -785,6 +784,16 @@ val base64_encode(val str, val wrap_cols) if (wcol && col > 0) put_char(chr('\n'), out); + return if3(ulim, nil, num(nb)); +} + +val base64_encode(val str, val wrap_cols) +{ + val in = make_string_byte_input_stream(str); + val out = make_string_output_stream(); + + (void) base64_stream_enc(out, in, nil, wrap_cols); + return get_string_from_stream(out); } @@ -818,16 +827,16 @@ INLINE int b64_code(cnum c) } } -val base64_decode(val str) +val base64_stream_dec(val out, val in, val nchars) { - val in = make_string_input_stream(str); - val out = make_string_output_stream(); + int ulim = nilp(default_null_arg(nchars)); + cnum nc = if3(ulim, 0, c_num(nchars)); - for (;;) { + for (; ulim || nc > 0; ulim ? --nc : 0) { cnum c0 = get_base64_char(in); - cnum c1 = get_base64_char(in); - cnum c2 = get_base64_char(in); - cnum c3 = get_base64_char(in); + cnum c1 = (c0 && (ulim || --nc > 0) ? get_base64_char(in) : 0); + cnum c2 = (c1 && (ulim || --nc > 0) ? get_base64_char(in) : 0); + cnum c3 = (c2 && (ulim || --nc > 0) ? get_base64_char(in) : 0); if (c3) { long f0 = b64_code(c0); @@ -859,6 +868,16 @@ val base64_decode(val str) } } + return if3(ulim, nil, num(nc)); +} + +val base64_decode(val str) +{ + val in = make_string_input_stream(str); + val out = make_string_output_stream(); + + (void) base64_stream_dec(out, in, nil); + return get_string_from_stream(out); } @@ -44,6 +44,9 @@ val register_filter(val sym, val table); val url_encode(val str, val space_plus); val url_decode(val str, val space_plus); +val base64_stream_enc(val out_stream, val in_stream, val nbytes, val wrap_cols); +val base64_stream_dec(val out_stream, val in_stream, val nchars); + val base64_encode(val str, val wrap_cols); val base64_decode(val str); |