git.delta.rocks / jrsonnet / refs/commits / 00fce89fa19e

difftreelog

perf make std.base64Decode[Bytes] builtin

Yaroslav Bolyukin2021-07-12parent: #747b2b7.patch.diff
in: master

2 files changed

modifiedcrates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/builtin/mod.rs
+++ b/crates/jrsonnet-evaluator/src/builtin/mod.rs
@@ -114,6 +114,8 @@
 			("encodeUTF8".into(), builtin_encode_utf8),
 			("md5".into(), builtin_md5),
 			("base64".into(), builtin_base64),
+			("base64DecodeBytes".into(), builtin_base64_decode_bytes),
+			("base64Decode".into(), builtin_base64_decode),
 			("trace".into(), builtin_trace),
 			("join".into(), builtin_join),
 			("escapeStringJson".into(), builtin_escape_string_json),
@@ -626,6 +628,39 @@
 	})
 }
 
+fn builtin_base64_decode_bytes(
+	context: Context,
+	_loc: Option<&ExprLocation>,
+	args: &ArgsDesc,
+) -> Result<Val> {
+	parse_args!(context, "base64DecodeBytes", args, 1, [
+		0, input: ty!(string) => Val::Str;
+	], {
+		Ok(Val::Arr(
+			base64::decode(&input.as_bytes())
+				.map_err(|_| RuntimeError("bad base64".into()))?
+				.iter()
+				.map(|v| Val::Num(*v as f64)).collect::<Vec<_>>().into()
+		))
+	})
+}
+
+fn builtin_base64_decode(
+	context: Context,
+	_loc: Option<&ExprLocation>,
+	args: &ArgsDesc,
+) -> Result<Val> {
+	parse_args!(context, "base64Decode", args, 1, [
+		0, input: ty!(string) => Val::Str;
+	], {
+		Ok(Val::Str(
+			String::from_utf8(base64::decode(&input.as_bytes())
+				.map_err(|_| RuntimeError("bad base64".into()))?)
+				.map_err(|_| RuntimeError("bad utf8".into()))?.into()
+		))
+	})
+}
+
 fn builtin_join(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {
 	parse_args!(context, "join", args, 2, [
 		0, sep: ty!((string | array));
modifiedcrates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth
531531
532 base64:: $intrinsic(base64),532 base64:: $intrinsic(base64),
533533
534 base64DecodeBytes(str)::534 base64DecodeBytes:: $intrinsic(base64DecodeBytes),
535 if std.length(str) % 4 != 0 then
536 error 'Not a base64 encoded string "%s"' % str
537 else
538 local aux(str, i, r) =
539 if i >= std.length(str) then
540 r
541 else
542 // all 6 bits of i, 2 MSB of i+1
543 local n1 = [base64_inv[str[i]] << 2 | (base64_inv[str[i + 1]] >> 4)];
544 // 4 LSB of i+1, 4MSB of i+2
545 local n2 =
546 if str[i + 2] == '=' then []
547 else [(base64_inv[str[i + 1]] & 15) << 4 | (base64_inv[str[i + 2]] >> 2)];
548 // 2 LSB of i+2, all 6 bits of i+3
549 local n3 =
550 if str[i + 3] == '=' then []
551 else [(base64_inv[str[i + 2]] & 3) << 6 | base64_inv[str[i + 3]]];
552 aux(str, i + 4, r + n1 + n2 + n3) tailstrict;
553 aux(str, 0, []),
554535
555 base64Decode(str)::536 base64Decode:: $intrinsic(base64Decode),
556 local bytes = std.base64DecodeBytes(str);
557 std.join('', std.map(function(b) std.char(b), bytes)),
558537
559 reverse:: $intrinsic(reverse),538 reverse:: $intrinsic(reverse),
560539