Cache immutable Wasm server configuration encoding
This commit is contained in:
@@ -1175,6 +1175,87 @@ bool ucb_decode(const String& encoded, DValue& out, String* error_out)
|
||||
return(false);
|
||||
}
|
||||
|
||||
#ifdef __UCE_WASM_CORE__
|
||||
static bool ucb_decode_flat_string_map(const String& encoded, StringMap& out, String* error_out)
|
||||
{
|
||||
String error;
|
||||
StringMap decoded;
|
||||
size_t offset = 0;
|
||||
auto fail = [&](String message) {
|
||||
error = message;
|
||||
return(false);
|
||||
};
|
||||
if(encoded.size() < 5 || encoded.compare(0, 4, UCEB_MAGIC) != 0)
|
||||
fail("missing UCEB magic header");
|
||||
else if((u8)encoded[4] != UCEB_VERSION)
|
||||
fail("unsupported UCEB version");
|
||||
else
|
||||
{
|
||||
offset = 5;
|
||||
if(encoded.size() - offset < 2)
|
||||
fail("unexpected end of UCEB2 string map");
|
||||
else
|
||||
{
|
||||
u8 flags = (u8)encoded[offset++];
|
||||
char type = encoded[offset++];
|
||||
u64 scalar_len = 0, child_count = 0;
|
||||
if(flags != 0 || type != 'M')
|
||||
fail("UCEB2 string map root must be a map");
|
||||
else if(!ucb_read_varint(encoded, offset, scalar_len) || scalar_len != 0)
|
||||
fail("UCEB2 string map root must have no scalar");
|
||||
else if(!ucb_read_varint(encoded, offset, child_count))
|
||||
fail("invalid UCEB2 string map child count");
|
||||
else
|
||||
{
|
||||
for(u64 i = 0; error == "" && i < child_count; i++)
|
||||
{
|
||||
u64 key_len = 0, value_len = 0, value_children = 0;
|
||||
if(!ucb_read_varint(encoded, offset, key_len) || key_len > encoded.size() - offset)
|
||||
{
|
||||
fail("invalid UCEB2 string map key");
|
||||
break;
|
||||
}
|
||||
String key(encoded.data() + offset, (size_t)key_len);
|
||||
offset += (size_t)key_len;
|
||||
if(encoded.size() - offset < 2)
|
||||
{
|
||||
fail("unexpected end of UCEB2 string map value");
|
||||
break;
|
||||
}
|
||||
u8 value_flags = (u8)encoded[offset++];
|
||||
char value_type = encoded[offset++];
|
||||
if(value_flags != 0 || value_type != 'S' || !ucb_read_varint(encoded, offset, value_len) || value_len > encoded.size() - offset)
|
||||
{
|
||||
fail("UCEB2 string map value must be a string scalar");
|
||||
break;
|
||||
}
|
||||
String value(encoded.data() + offset, (size_t)value_len);
|
||||
offset += (size_t)value_len;
|
||||
if(!ucb_read_varint(encoded, offset, value_children) || value_children != 0)
|
||||
{
|
||||
fail("UCEB2 string map value cannot have children");
|
||||
break;
|
||||
}
|
||||
decoded[std::move(key)] = std::move(value);
|
||||
}
|
||||
if(error == "" && offset != encoded.size())
|
||||
fail("trailing bytes after UCEB2 string map");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(error != "")
|
||||
{
|
||||
if(error_out)
|
||||
*error_out = error;
|
||||
return(false);
|
||||
}
|
||||
out = std::move(decoded);
|
||||
if(error_out)
|
||||
*error_out = "";
|
||||
return(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
DValue ucb_decode(const String& encoded)
|
||||
{
|
||||
DValue out;
|
||||
|
||||
Reference in New Issue
Block a user