diff --git a/docs/scarpet/language/FunctionsAndControlFlow.md b/docs/scarpet/language/FunctionsAndControlFlow.md index a0a867e0..f60aa07e 100644 --- a/docs/scarpet/language/FunctionsAndControlFlow.md +++ b/docs/scarpet/language/FunctionsAndControlFlow.md @@ -267,6 +267,7 @@ but like everywhere else, doing that sounds like a bad idea. - `io_exception`: This is the parent for any exception that occurs due to an error handling external data. - `nbt_error`: Incorrect input/output NBT file. - `json_error`: Incorrect input/output JSON data. + - `b64_error`: Incorrect input/output b64 (base 64) string - `user_exception`: Exception thrown by default with `throw` function. Synopsis: diff --git a/docs/scarpet/language/LoopsAndHigherOrderFunctions.md b/docs/scarpet/language/LoopsAndHigherOrderFunctions.md index 33d52fa1..c9bdfb0a 100644 --- a/docs/scarpet/language/LoopsAndHigherOrderFunctions.md +++ b/docs/scarpet/language/LoopsAndHigherOrderFunctions.md @@ -146,3 +146,12 @@ it will be used from now on as a new value for the accumulator. reduce([1,2,3,4],_a+_,0) => 10 reduce([1,2,3,4],_a*_,1) => 24 + +### `encode_b64(string)`, `decode_b64(string)` + +Encode or decode a string from b64, throwing a `b64_error` exception if it's invalid + +### `encode_json(value)`, `decode_json(string)` + +Encodes a value as a json string, and decodes a json string as a valid value, throwing a `json_error` exception if it +doesn't parse properly diff --git a/src/main/java/carpet/script/exception/Throwables.java b/src/main/java/carpet/script/exception/Throwables.java index 3f811cfe..fa751b2d 100644 --- a/src/main/java/carpet/script/exception/Throwables.java +++ b/src/main/java/carpet/script/exception/Throwables.java @@ -27,6 +27,7 @@ public class Throwables { public static final Throwables IO_EXCEPTION = register("io_exception", THROWN_EXCEPTION_TYPE); public static final Throwables NBT_ERROR = register("nbt_error", IO_EXCEPTION); public static final Throwables JSON_ERROR = register("json_error", IO_EXCEPTION); + public static final Throwables B64_ERROR = register("b64_error", IO_EXCEPTION); public static final Throwables USER_DEFINED = register("user_exception", THROWN_EXCEPTION_TYPE); /** diff --git a/src/main/java/carpet/script/language/DataStructures.java b/src/main/java/carpet/script/language/DataStructures.java index b97d3b49..6b75e624 100644 --- a/src/main/java/carpet/script/language/DataStructures.java +++ b/src/main/java/carpet/script/language/DataStructures.java @@ -4,6 +4,9 @@ import carpet.script.Context; import carpet.script.Expression; import carpet.script.LazyValue; import carpet.script.exception.InternalExpressionException; +import carpet.script.exception.ThrowStatement; +import carpet.script.exception.Throwables; +import carpet.script.utils.ScarpetJsonDeserializer; import carpet.script.value.ContainerValueInterface; import carpet.script.value.LContainerValue; import carpet.script.value.LazyListValue; @@ -12,8 +15,12 @@ import carpet.script.value.MapValue; import carpet.script.value.NumericValue; import carpet.script.value.StringValue; import carpet.script.value.Value; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Base64; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -320,5 +327,23 @@ public class DataStructures { Value ret = new NumericValue(((ContainerValueInterface) container).delete(lv.get(lv.size()-1).evalValue(c))); return (cc, tt) -> ret; }); + + expression.addUnaryFunction("encode_b64", v -> StringValue.of(Base64.getEncoder().encodeToString(v.getString().getBytes()))); + expression.addUnaryFunction("decode_b64", v -> { + try { + return StringValue.of(new String(Base64.getDecoder().decode(v.getString()), StandardCharsets.ISO_8859_1));//using this charset cos it's the one used in decoding function + } catch (IllegalArgumentException iae){ + throw new ThrowStatement("Invalid b64 string: " + v.getString(), Throwables.B64_ERROR); + } + }); + + expression.addUnaryFunction("encode_json", v -> StringValue.of(v.toJson().toString())); + expression.addUnaryFunction("decode_json", v -> { + try { + return new ScarpetJsonDeserializer().deserialize(new JsonParser().parse(v.getString()), null, null); + } catch (JsonParseException jpe){ + throw new ThrowStatement("Invalid json string: " + v.getString(), Throwables.JSON_ERROR); + } + }); } }