diff --git a/spl/http.spl b/spl/http.spl
index 6761982..61055c0 100644
--- a/spl/http.spl
+++ b/spl/http.spl
@@ -11,6 +11,40 @@ construct net:http namespace {
register { | with name this ;
name "net:http" register-field
}
+ urlencode { str | with str this ;
+ [ { | with x ;
+ x
+ x "0" :_char lt not
+ x "9" :_char gt not and
+ x "a" :_char lt not
+ x "z" :_char gt not and or
+ x "A" :_char lt not
+ x "Z" :_char gt not and or
+ not
+ if {
+ pop
+ "%" :_char
+ x _mega:_str_radix<16> _array =x
+ x:len 1 eq if { "0" :_char }
+ x:to-stack
+ }
+ } str _array :foreach ] _str
+ }
+ urldecode { str | with str this ;
+ str _array =str
+ [
+ def i 0 =i
+ while { i str:len lt } {
+ i str:get dup "%" :_char eq if {
+ pop
+ i ++ =i
+ i i 2 + str:sub _str :_mega_radix<16> _int
+ i ++ =i
+ }
+ i ++ =i
+ }
+ ] _str
+ }
}
construct net:http:Request {
diff --git a/spl/std.spl b/spl/std.spl
index 171cdfa..686c33e 100644
--- a/spl/std.spl
+++ b/spl/std.spl
@@ -72,6 +72,9 @@ construct _str_ext {
}
}> _str
}
+ _mega_radix { mega | with radix this ;
+ this radix str-to-mega-radix
+ }
} include _str_ext in str
construct _mega-ext {
@@ -88,6 +91,9 @@ construct _mega-ext {
fforeach { | with callable this ;
0 while { !!- dup2 this lt } { !!- callable call 1 + }
}
+ _str_radix { str | with radix this ;
+ this radix mega-to-str-radix
+ }
} include _mega-ext in mega
construct _array-ext {
diff --git a/src/std_fns.rs b/src/std_fns.rs
index e063ca3..e206d72 100644
--- a/src/std_fns.rs
+++ b/src/std_fns.rs
@@ -892,9 +892,47 @@ pub fn str_readf(stack: &mut Stack) -> OError {
Ok(())
}
+pub fn str_to_mega_radix(stack: &mut Stack) -> OError {
+ require_int_on_stack!(radix, stack, "str-to-mega-radix");
+ require_on_stack!(str, Str, stack, "str-to-mega-radix");
+ let Ok(result) = i128::from_str_radix(&str, radix as u32) else {
+ stack.push(Value::Null.spl());
+ return Ok(());
+ };
+ stack.push(Value::Mega(result).spl());
+ return Ok(());
+}
+
+pub fn mega_to_str_radix(stack: &mut Stack) -> OError {
+ require_int_on_stack!(radix, stack, "mega-to-str-radix");
+ require_on_stack!(mega, Mega, stack, "mega-to-str-radix");
+ let mut result = Vec::new();
+ let neg = mega < 0;
+ let mut mega = mega;
+ if neg {
+ mega = -mega;
+ result.push('-' as u32);
+ }
+ while mega != 0 {
+ let i = (mega % radix as i128) as u32;
+ result.push(if i < 10 { '0' as u32 } else { 'a' as u32 - 10 } + i);
+ mega = mega / radix as i128;
+ }
+ result.reverse();
+ stack.push(
+ Value::Str(String::from_iter(
+ result
+ .into_iter()
+ .map(|x| char::from_u32(x).expect("invalid radix")),
+ ))
+ .spl(),
+ );
+ return Ok(());
+}
+
pub fn register(r: &mut Stack, o: Arc) {
type Fn = fn(&mut Stack) -> OError;
- let fns: [(&str, Fn, u32); 57] = [
+ let fns: [(&str, Fn, u32); 59] = [
("pop", pop, 0),
("dup", dup, 2),
("dup2", dup2, 3),
@@ -952,6 +990,8 @@ pub fn register(r: &mut Stack, o: Arc) {
("fork", fork, 0),
("sleeptime", time, 0),
("str-readf", str_readf, 1),
+ ("str-to-mega-radix", str_to_mega_radix, 1),
+ ("mega-to-str-radix", mega_to_str_radix, 1),
];
for f in fns {
r.define_func(
diff --git a/test.spl b/test.spl
index 639de80..acf9b95 100644
--- a/test.spl
+++ b/test.spl
@@ -230,6 +230,12 @@ func main { int | with args ;
} fork
def req "localhost" 4076 "GET" "/spltest" Request:new =req
req:send:body _str println;
+
+ "" println;
+ "testing urlencoding";
+
+ "hello! this is a test of URL encoding!" net:http:urlencode dup println;
+ net:http:urldecode println;
5 :foreach<{ | "" println }>