summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-08-09 06:25:14 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-08-09 06:25:14 -0700
commite63c561a145103a94efbc49e7c6a1061dd8464f4 (patch)
tree39f295a7e09d052c51765f60f7ac77a6905f8b93
parent46bc67ee1b42f8f7587e87b0ba604e0541bd24f1 (diff)
downloadtxr-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.c49
-rw-r--r--filter.h3
2 files changed, 37 insertions, 15 deletions
diff --git a/filter.c b/filter.c
index 92a51592..3da23016 100644
--- a/filter.c
+++ b/filter.c
@@ -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);
}
diff --git a/filter.h b/filter.h
index a8507b9c..6aaae66c 100644
--- a/filter.h
+++ b/filter.h
@@ -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);