Save PackedByteArrays as base64 encoded
This commit is contained in:
parent
7d2ca2d8ac
commit
de5073519e
3 changed files with 85 additions and 12 deletions
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "variant_parser.h"
|
#include "variant_parser.h"
|
||||||
|
|
||||||
|
#include "core/crypto/crypto_core.h"
|
||||||
#include "core/input/input_event.h"
|
#include "core/input/input_event.h"
|
||||||
#include "core/io/resource_loader.h"
|
#include "core/io/resource_loader.h"
|
||||||
#include "core/object/script_language.h"
|
#include "core/object/script_language.h"
|
||||||
|
@ -595,6 +596,82 @@ Error VariantParser::_parse_construct(Stream *p_stream, Vector<T> &r_construct,
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Error VariantParser::_parse_byte_array(Stream *p_stream, Vector<uint8_t> &r_construct, int &line, String &r_err_str) {
|
||||||
|
Token token;
|
||||||
|
get_token(p_stream, token, line, r_err_str);
|
||||||
|
if (token.type != TK_PARENTHESIS_OPEN) {
|
||||||
|
r_err_str = "Expected '(' in constructor";
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_token(p_stream, token, line, r_err_str);
|
||||||
|
if (token.type == TK_STRING) {
|
||||||
|
// Base64 encoded array.
|
||||||
|
String base64_encoded_string = token.value;
|
||||||
|
int strlen = base64_encoded_string.length();
|
||||||
|
CharString cstr = base64_encoded_string.ascii();
|
||||||
|
|
||||||
|
size_t arr_len = 0;
|
||||||
|
r_construct.resize(strlen / 4 * 3 + 1);
|
||||||
|
uint8_t *w = r_construct.ptrw();
|
||||||
|
Error err = CryptoCore::b64_decode(&w[0], r_construct.size(), &arr_len, (unsigned char *)cstr.get_data(), strlen);
|
||||||
|
if (err) {
|
||||||
|
r_err_str = "Invalid base64-encoded string";
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
r_construct.resize(arr_len);
|
||||||
|
|
||||||
|
get_token(p_stream, token, line, r_err_str);
|
||||||
|
if (token.type != TK_PARENTHESIS_CLOSE) {
|
||||||
|
r_err_str = "Expected ')' in constructor";
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (token.type == TK_NUMBER || token.type == TK_IDENTIFIER) {
|
||||||
|
// Individual elements.
|
||||||
|
while (true) {
|
||||||
|
if (token.type != TK_NUMBER) {
|
||||||
|
bool valid = false;
|
||||||
|
if (token.type == TK_IDENTIFIER) {
|
||||||
|
double real = stor_fix(token.value);
|
||||||
|
if (real != -1) {
|
||||||
|
token.type = TK_NUMBER;
|
||||||
|
token.value = real;
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!valid) {
|
||||||
|
r_err_str = "Expected number in constructor";
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r_construct.push_back(token.value);
|
||||||
|
|
||||||
|
get_token(p_stream, token, line, r_err_str);
|
||||||
|
|
||||||
|
if (token.type == TK_COMMA) {
|
||||||
|
//do none
|
||||||
|
} else if (token.type == TK_PARENTHESIS_CLOSE) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
r_err_str = "Expected ',' or ')' in constructor";
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_token(p_stream, token, line, r_err_str);
|
||||||
|
}
|
||||||
|
} else if (token.type == TK_PARENTHESIS_CLOSE) {
|
||||||
|
// Empty array.
|
||||||
|
return OK;
|
||||||
|
} else {
|
||||||
|
r_err_str = "Expected base64 string, or list of numbers in constructor";
|
||||||
|
return ERR_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser) {
|
Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser) {
|
||||||
if (token.type == TK_CURLY_BRACKET_OPEN) {
|
if (token.type == TK_CURLY_BRACKET_OPEN) {
|
||||||
Dictionary d;
|
Dictionary d;
|
||||||
|
@ -1148,7 +1225,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
|
||||||
value = array;
|
value = array;
|
||||||
} else if (id == "PackedByteArray" || id == "PoolByteArray" || id == "ByteArray") {
|
} else if (id == "PackedByteArray" || id == "PoolByteArray" || id == "ByteArray") {
|
||||||
Vector<uint8_t> args;
|
Vector<uint8_t> args;
|
||||||
Error err = _parse_construct<uint8_t>(p_stream, args, line, r_err_str);
|
Error err = _parse_byte_array(p_stream, args, line, r_err_str);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -2031,17 +2108,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
|
||||||
case Variant::PACKED_BYTE_ARRAY: {
|
case Variant::PACKED_BYTE_ARRAY: {
|
||||||
p_store_string_func(p_store_string_ud, "PackedByteArray(");
|
p_store_string_func(p_store_string_ud, "PackedByteArray(");
|
||||||
Vector<uint8_t> data = p_variant;
|
Vector<uint8_t> data = p_variant;
|
||||||
int len = data.size();
|
if (data.size() > 0) {
|
||||||
const uint8_t *ptr = data.ptr();
|
p_store_string_func(p_store_string_ud, "\"");
|
||||||
|
p_store_string_func(p_store_string_ud, CryptoCore::b64_encode_str(data.ptr(), data.size()));
|
||||||
for (int i = 0; i < len; i++) {
|
p_store_string_func(p_store_string_ud, "\"");
|
||||||
if (i > 0) {
|
|
||||||
p_store_string_func(p_store_string_ud, ", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, itos(ptr[i]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p_store_string_func(p_store_string_ud, ")");
|
p_store_string_func(p_store_string_ud, ")");
|
||||||
} break;
|
} break;
|
||||||
case Variant::PACKED_INT32_ARRAY: {
|
case Variant::PACKED_INT32_ARRAY: {
|
||||||
|
|
|
@ -141,6 +141,7 @@ private:
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
static Error _parse_construct(Stream *p_stream, Vector<T> &r_construct, int &line, String &r_err_str);
|
static Error _parse_construct(Stream *p_stream, Vector<T> &r_construct, int &line, String &r_err_str);
|
||||||
|
static Error _parse_byte_array(Stream *p_stream, Vector<uint8_t> &r_construct, int &line, String &r_err_str);
|
||||||
static Error _parse_enginecfg(Stream *p_stream, Vector<String> &strings, int &line, String &r_err_str);
|
static Error _parse_enginecfg(Stream *p_stream, Vector<String> &strings, int &line, String &r_err_str);
|
||||||
static Error _parse_dictionary(Dictionary &object, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser = nullptr);
|
static Error _parse_dictionary(Dictionary &object, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser = nullptr);
|
||||||
static Error _parse_array(Array &array, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser = nullptr);
|
static Error _parse_array(Array &array, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser = nullptr);
|
||||||
|
|
|
@ -39,7 +39,8 @@
|
||||||
|
|
||||||
// Version 2: changed names for Basis, AABB, Vectors, etc.
|
// Version 2: changed names for Basis, AABB, Vectors, etc.
|
||||||
// Version 3: new string ID for ext/subresources, breaks forward compat.
|
// Version 3: new string ID for ext/subresources, breaks forward compat.
|
||||||
#define FORMAT_VERSION 3
|
// Version 4: PackedByteArray is now stored as base64 encoded.
|
||||||
|
#define FORMAT_VERSION 4
|
||||||
|
|
||||||
#define BINARY_FORMAT_VERSION 4
|
#define BINARY_FORMAT_VERSION 4
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue