struct UrlPercentDecodeParams {
input_len: u32,
output_capacity: u32,
reserved0: u32,
reserved1: u32,
}
@group(0) @binding(0) var<uniform> params: UrlPercentDecodeParams;
@group(0) @binding(1) var<storage, read> input_words: array<u32>;
@group(0) @binding(2) var<storage, read_write> output_words: array<u32>;
@group(0) @binding(3) var<storage, read_write> status: array<u32>;
@compute @workgroup_size(1, 1, 1)
fn decode_url_percent(@builtin(global_invocation_id) id: vec3<u32>) {
if (id.x != 0u) {
return;
}
status[0] = 0u;
status[1] = 0u;
var input = 0u;
var out = 0u;
loop {
if (input >= params.input_len) {
break;
}
if (out >= params.output_capacity) {
status[0] = 5u;
return;
}
let byte = vyre_packed_byte(&input_words, input);
if (byte != 37u) {
vyre_store_packed_byte(&output_words, out, byte);
input = input + 1u;
out = out + 1u;
continue;
}
if (input + 2u >= params.input_len) {
status[0] = 1u;
status[1] = input;
return;
}
let hi = vyre_hex_value(vyre_packed_byte(&input_words, input + 1u));
let lo = vyre_hex_value(vyre_packed_byte(&input_words, input + 2u));
if (hi == 0xffffffffu) {
status[0] = 2u;
status[1] = input + 1u;
return;
}
if (lo == 0xffffffffu) {
status[0] = 2u;
status[1] = input + 2u;
return;
}
vyre_store_packed_byte(&output_words, out, (hi << 4u) | lo);
input = input + 3u;
out = out + 1u;
}
status[1] = out;
}