1use crate::seqstring::global_string;
22use crate::stack::{Stack, pop, push};
23use crate::value::Value;
24
25use base64::prelude::*;
26
27#[unsafe(no_mangle)]
34pub unsafe extern "C" fn patch_seq_base64_encode(stack: Stack) -> Stack {
35 assert!(!stack.is_null(), "base64-encode: stack is empty");
36
37 let (stack, value) = unsafe { pop(stack) };
38
39 match value {
40 Value::String(s) => {
41 let encoded = BASE64_STANDARD.encode(s.as_str().as_bytes());
42 unsafe { push(stack, Value::String(global_string(encoded))) }
43 }
44 _ => panic!("base64-encode: expected String on stack, got {:?}", value),
45 }
46}
47
48#[unsafe(no_mangle)]
57pub unsafe extern "C" fn patch_seq_base64_decode(stack: Stack) -> Stack {
58 assert!(!stack.is_null(), "base64-decode: stack is empty");
59
60 let (stack, value) = unsafe { pop(stack) };
61
62 match value {
63 Value::String(s) => match BASE64_STANDARD.decode(s.as_str().as_bytes()) {
64 Ok(bytes) => match String::from_utf8(bytes) {
65 Ok(decoded) => {
66 let stack = unsafe { push(stack, Value::String(global_string(decoded))) };
67 unsafe { push(stack, Value::Bool(true)) }
68 }
69 Err(_) => {
70 let stack = unsafe { push(stack, Value::String(global_string(String::new()))) };
72 unsafe { push(stack, Value::Bool(false)) }
73 }
74 },
75 Err(_) => {
76 let stack = unsafe { push(stack, Value::String(global_string(String::new()))) };
78 unsafe { push(stack, Value::Bool(false)) }
79 }
80 },
81 _ => panic!("base64-decode: expected String on stack, got {:?}", value),
82 }
83}
84
85#[unsafe(no_mangle)]
95pub unsafe extern "C" fn patch_seq_base64url_encode(stack: Stack) -> Stack {
96 assert!(!stack.is_null(), "base64url-encode: stack is empty");
97
98 let (stack, value) = unsafe { pop(stack) };
99
100 match value {
101 Value::String(s) => {
102 let encoded = BASE64_URL_SAFE_NO_PAD.encode(s.as_str().as_bytes());
103 unsafe { push(stack, Value::String(global_string(encoded))) }
104 }
105 _ => panic!(
106 "base64url-encode: expected String on stack, got {:?}",
107 value
108 ),
109 }
110}
111
112#[unsafe(no_mangle)]
121pub unsafe extern "C" fn patch_seq_base64url_decode(stack: Stack) -> Stack {
122 assert!(!stack.is_null(), "base64url-decode: stack is empty");
123
124 let (stack, value) = unsafe { pop(stack) };
125
126 match value {
127 Value::String(s) => match BASE64_URL_SAFE_NO_PAD.decode(s.as_str().as_bytes()) {
128 Ok(bytes) => match String::from_utf8(bytes) {
129 Ok(decoded) => {
130 let stack = unsafe { push(stack, Value::String(global_string(decoded))) };
131 unsafe { push(stack, Value::Bool(true)) }
132 }
133 Err(_) => {
134 let stack = unsafe { push(stack, Value::String(global_string(String::new()))) };
135 unsafe { push(stack, Value::Bool(false)) }
136 }
137 },
138 Err(_) => {
139 let stack = unsafe { push(stack, Value::String(global_string(String::new()))) };
140 unsafe { push(stack, Value::Bool(false)) }
141 }
142 },
143 _ => panic!(
144 "base64url-decode: expected String on stack, got {:?}",
145 value
146 ),
147 }
148}
149
150#[unsafe(no_mangle)]
159pub unsafe extern "C" fn patch_seq_hex_encode(stack: Stack) -> Stack {
160 assert!(!stack.is_null(), "hex-encode: stack is empty");
161
162 let (stack, value) = unsafe { pop(stack) };
163
164 match value {
165 Value::String(s) => {
166 let encoded = hex::encode(s.as_str().as_bytes());
167 unsafe { push(stack, Value::String(global_string(encoded))) }
168 }
169 _ => panic!("hex-encode: expected String on stack, got {:?}", value),
170 }
171}
172
173#[unsafe(no_mangle)]
183pub unsafe extern "C" fn patch_seq_hex_decode(stack: Stack) -> Stack {
184 assert!(!stack.is_null(), "hex-decode: stack is empty");
185
186 let (stack, value) = unsafe { pop(stack) };
187
188 match value {
189 Value::String(s) => match hex::decode(s.as_str()) {
190 Ok(bytes) => match String::from_utf8(bytes) {
191 Ok(decoded) => {
192 let stack = unsafe { push(stack, Value::String(global_string(decoded))) };
193 unsafe { push(stack, Value::Bool(true)) }
194 }
195 Err(_) => {
196 let stack = unsafe { push(stack, Value::String(global_string(String::new()))) };
198 unsafe { push(stack, Value::Bool(false)) }
199 }
200 },
201 Err(_) => {
202 let stack = unsafe { push(stack, Value::String(global_string(String::new()))) };
204 unsafe { push(stack, Value::Bool(false)) }
205 }
206 },
207 _ => panic!("hex-decode: expected String on stack, got {:?}", value),
208 }
209}
210
211#[cfg(test)]
212mod tests;