diff options
Diffstat (limited to 'core/io/xml_parser.cpp')
-rw-r--r-- | core/io/xml_parser.cpp | 137 |
1 files changed, 81 insertions, 56 deletions
diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp index abae48fdd8..5c0a017bfc 100644 --- a/core/io/xml_parser.cpp +++ b/core/io/xml_parser.cpp @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* xml_parser.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* xml_parser.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #include "xml_parser.h" @@ -41,11 +41,11 @@ static inline bool _is_white_space(char c) { } //! sets the state that text was found. Returns true if set should be set -bool XMLParser::_set_text(char *start, char *end) { +bool XMLParser::_set_text(const char *start, const char *end) { // check if text is more than 2 characters, and if not, check if there is // only white space, so that this text won't be reported if (end - start < 3) { - char *p = start; + const char *p = start; for (; p != end; ++p) { if (!_is_white_space(*p)) { break; @@ -92,7 +92,7 @@ void XMLParser::_parse_closing_xml_element() { void XMLParser::_ignore_definition() { node_type = NODE_UNKNOWN; - char *F = P; + const char *F = P; // move until end marked with '>' reached while (*P && *P != '>') { next_char(); @@ -123,8 +123,8 @@ bool XMLParser::_parse_cdata() { return true; } - char *cDataBegin = P; - char *cDataEnd = nullptr; + const char *cDataBegin = P; + const char *cDataEnd = nullptr; // find end of CDATA while (*P && !cDataEnd) { @@ -152,9 +152,9 @@ void XMLParser::_parse_comment() { node_type = NODE_COMMENT; P += 1; - char *pEndOfInput = data + length; - char *pCommentBegin; - char *pCommentEnd; + const char *pEndOfInput = data + length; + const char *pCommentBegin; + const char *pCommentEnd; if (P + 1 < pEndOfInput && P[0] == '-' && P[1] == '-') { // Comment, use '-->' as end. @@ -293,7 +293,7 @@ void XMLParser::_parse_opening_xml_element() { } void XMLParser::_parse_current_node() { - char *start = P; + const char *start = P; node_offset = P - data; // more forward until '<' found @@ -354,10 +354,10 @@ void XMLParser::_bind_methods() { ClassDB::bind_method(D_METHOD("get_node_offset"), &XMLParser::get_node_offset); ClassDB::bind_method(D_METHOD("get_attribute_count"), &XMLParser::get_attribute_count); ClassDB::bind_method(D_METHOD("get_attribute_name", "idx"), &XMLParser::get_attribute_name); - ClassDB::bind_method(D_METHOD("get_attribute_value", "idx"), (String(XMLParser::*)(int) const) & XMLParser::get_attribute_value); + ClassDB::bind_method(D_METHOD("get_attribute_value", "idx"), &XMLParser::get_attribute_value); ClassDB::bind_method(D_METHOD("has_attribute", "name"), &XMLParser::has_attribute); - ClassDB::bind_method(D_METHOD("get_named_attribute_value", "name"), (String(XMLParser::*)(const String &) const) & XMLParser::get_attribute_value); - ClassDB::bind_method(D_METHOD("get_named_attribute_value_safe", "name"), &XMLParser::get_attribute_value_safe); + ClassDB::bind_method(D_METHOD("get_named_attribute_value", "name"), &XMLParser::get_named_attribute_value); + ClassDB::bind_method(D_METHOD("get_named_attribute_value_safe", "name"), &XMLParser::get_named_attribute_value_safe); ClassDB::bind_method(D_METHOD("is_empty"), &XMLParser::is_empty); ClassDB::bind_method(D_METHOD("get_current_line"), &XMLParser::get_current_line); ClassDB::bind_method(D_METHOD("skip_section"), &XMLParser::skip_section); @@ -422,7 +422,7 @@ bool XMLParser::has_attribute(const String &p_name) const { return false; } -String XMLParser::get_attribute_value(const String &p_name) const { +String XMLParser::get_named_attribute_value(const String &p_name) const { int idx = -1; for (int i = 0; i < attributes.size(); i++) { if (attributes[i].name == p_name) { @@ -436,7 +436,7 @@ String XMLParser::get_attribute_value(const String &p_name) const { return attributes[idx].value; } -String XMLParser::get_attribute_value_safe(const String &p_name) const { +String XMLParser::get_named_attribute_value_safe(const String &p_name) const { int idx = -1; for (int i = 0; i < attributes.size(); i++) { if (attributes[i].name == p_name) { @@ -458,15 +458,36 @@ bool XMLParser::is_empty() const { Error XMLParser::open_buffer(const Vector<uint8_t> &p_buffer) { ERR_FAIL_COND_V(p_buffer.size() == 0, ERR_INVALID_DATA); - if (data) { - memdelete_arr(data); + if (data_copy) { + memdelete_arr(data_copy); + data_copy = nullptr; } length = p_buffer.size(); - data = memnew_arr(char, length + 1); - memcpy(data, p_buffer.ptr(), length); - data[length] = 0; + data_copy = memnew_arr(char, length + 1); + memcpy(data_copy, p_buffer.ptr(), length); + data_copy[length] = 0; + data = data_copy; + P = data; + current_line = 0; + + return OK; +} + +Error XMLParser::_open_buffer(const uint8_t *p_buffer, size_t p_size) { + ERR_FAIL_COND_V(p_size == 0, ERR_INVALID_DATA); + ERR_FAIL_COND_V(!p_buffer, ERR_INVALID_DATA); + + if (data_copy) { + memdelete_arr(data_copy); + data_copy = nullptr; + } + + length = p_size; + data = (const char *)p_buffer; P = data; + current_line = 0; + return OK; } @@ -479,13 +500,15 @@ Error XMLParser::open(const String &p_path) { length = file->get_length(); ERR_FAIL_COND_V(length < 1, ERR_FILE_CORRUPT); - if (data) { - memdelete_arr(data); + if (data_copy) { + memdelete_arr(data_copy); + data_copy = nullptr; } - data = memnew_arr(char, length + 1); - file->get_buffer((uint8_t *)data, length); - data[length] = 0; + data_copy = memnew_arr(char, length + 1); + file->get_buffer((uint8_t *)data_copy, length); + data_copy[length] = 0; + data = data_copy; P = data; current_line = 0; @@ -512,8 +535,9 @@ void XMLParser::skip_section() { } void XMLParser::close() { - if (data) { + if (data_copy) { memdelete_arr(data); + data_copy = nullptr; } data = nullptr; length = 0; @@ -528,7 +552,8 @@ int XMLParser::get_current_line() const { } XMLParser::~XMLParser() { - if (data) { - memdelete_arr(data); + if (data_copy) { + memdelete_arr(data_copy); + data_copy = nullptr; } } |