1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-05 12:10:55 +00:00

Add support for reading text resource format 4

Co-Authored-By: Gilles Roudiere <gilles.roudiere@gmail.com>
This commit is contained in:
Haoyu Qiu
2024-04-27 20:53:27 +08:00
parent 190cbcfd7f
commit 4ade4ab92a
3 changed files with 84 additions and 4 deletions

View File

@@ -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;
} }

View File

@@ -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);

View File

@@ -39,7 +39,9 @@
// 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.
// Version 4: PackedByteArray is now stored as base64 encoded.
#define FORMAT_VERSION 3 #define FORMAT_VERSION 3
#define FORMAT_VERSION_READABLE 4
#define BINARY_FORMAT_VERSION 4 #define BINARY_FORMAT_VERSION 4
@@ -1050,7 +1052,7 @@ void ResourceLoaderText::open(Ref<FileAccess> p_f, bool p_skip_first_tag) {
if (tag.fields.has("format")) { if (tag.fields.has("format")) {
int fmt = tag.fields["format"]; int fmt = tag.fields["format"];
if (fmt > FORMAT_VERSION) { if (fmt > FORMAT_VERSION_READABLE) {
error_text = "Saved with newer format version"; error_text = "Saved with newer format version";
_printerr(); _printerr();
error = ERR_PARSE_ERROR; error = ERR_PARSE_ERROR;
@@ -1541,7 +1543,7 @@ String ResourceLoaderText::recognize_script_class(Ref<FileAccess> p_f) {
if (tag.fields.has("format")) { if (tag.fields.has("format")) {
int fmt = tag.fields["format"]; int fmt = tag.fields["format"];
if (fmt > FORMAT_VERSION) { if (fmt > FORMAT_VERSION_READABLE) {
error_text = "Saved with newer format version"; error_text = "Saved with newer format version";
_printerr(); _printerr();
return ""; return "";
@@ -1579,7 +1581,7 @@ String ResourceLoaderText::recognize(Ref<FileAccess> p_f) {
if (tag.fields.has("format")) { if (tag.fields.has("format")) {
int fmt = tag.fields["format"]; int fmt = tag.fields["format"];
if (fmt > FORMAT_VERSION) { if (fmt > FORMAT_VERSION_READABLE) {
error_text = "Saved with newer format version"; error_text = "Saved with newer format version";
_printerr(); _printerr();
return ""; return "";