| 
									
										
										
										
											2023-01-05 13:25:55 +01:00
										 |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*  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.                 */ | 
					
						
							|  |  |  | /**************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "xml_parser.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-07 19:33:38 -03:00
										 |  |  | #include "core/string/print_string.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | //#define DEBUG_XML
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | static inline bool _is_white_space(char c) { | 
					
						
							|  |  |  | 	return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //! sets the state that text was found. Returns true if set should be set
 | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | bool XMLParser::_set_text(const char *start, const char *end) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	// 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
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (end - start < 3) { | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | 		const char *p = start; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		for (; p != end; ++p) { | 
					
						
							|  |  |  | 			if (!_is_white_space(*p)) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (p == end) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// set current text to the parsed text, and replace xml special characters
 | 
					
						
							|  |  |  | 	String s = String::utf8(start, (int)(end - start)); | 
					
						
							| 
									
										
										
										
											2021-02-11 09:33:55 -06:00
										 |  |  | 	node_name = s.xml_unescape(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// current XML node type is text
 | 
					
						
							|  |  |  | 	node_type = NODE_TEXT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void XMLParser::_parse_closing_xml_element() { | 
					
						
							|  |  |  | 	node_type = NODE_ELEMENT_END; | 
					
						
							|  |  |  | 	node_empty = false; | 
					
						
							|  |  |  | 	attributes.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 	next_char(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	const char *pBeginClose = P; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 	while (*P && *P != '>') { | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 		next_char(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	node_name = String::utf8(pBeginClose, (int)(P - pBeginClose)); | 
					
						
							|  |  |  | #ifdef DEBUG_XML
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	print_line("XML CLOSE: " + node_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (*P) { | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 		next_char(); | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void XMLParser::_ignore_definition() { | 
					
						
							|  |  |  | 	node_type = NODE_UNKNOWN; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | 	const char *F = P; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	// move until end marked with '>' reached
 | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 	while (*P && *P != '>') { | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 		next_char(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	node_name.parse_utf8(F, P - F); | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (*P) { | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 		next_char(); | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool XMLParser::_parse_cdata() { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (*(P + 1) != '[') { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	node_type = NODE_CDATA; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// skip '<![CDATA['
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	int count = 0; | 
					
						
							|  |  |  | 	while (*P && count < 8) { | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 		next_char(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		++count; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!*P) { | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 		node_name = ""; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return true; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | 	const char *cDataBegin = P; | 
					
						
							|  |  |  | 	const char *cDataEnd = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// find end of CDATA
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while (*P && !cDataEnd) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		if (*P == '>' && | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				(*(P - 1) == ']') && | 
					
						
							|  |  |  | 				(*(P - 2) == ']')) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			cDataEnd = P - 2; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 		next_char(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-09 09:42:24 +08:00
										 |  |  | 	if (!cDataEnd) { | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 		cDataEnd = P; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 	node_name = String::utf8(cDataBegin, (int)(cDataEnd - cDataBegin)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #ifdef DEBUG_XML
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	print_line("XML CDATA: " + node_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void XMLParser::_parse_comment() { | 
					
						
							|  |  |  | 	node_type = NODE_COMMENT; | 
					
						
							|  |  |  | 	P += 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | 	const char *pEndOfInput = data + length; | 
					
						
							|  |  |  | 	const char *pCommentBegin; | 
					
						
							|  |  |  | 	const char *pCommentEnd; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 	if (P + 1 < pEndOfInput && P[0] == '-' && P[1] == '-') { | 
					
						
							|  |  |  | 		// Comment, use '-->' as end.
 | 
					
						
							|  |  |  | 		pCommentBegin = P + 2; | 
					
						
							|  |  |  | 		for (pCommentEnd = pCommentBegin; pCommentEnd + 2 < pEndOfInput; pCommentEnd++) { | 
					
						
							|  |  |  | 			if (pCommentEnd[0] == '-' && pCommentEnd[1] == '-' && pCommentEnd[2] == '>') { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (pCommentEnd + 2 < pEndOfInput) { | 
					
						
							|  |  |  | 			P = pCommentEnd + 3; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			P = pCommentEnd = pEndOfInput; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		// Like document type definition, match angle brackets.
 | 
					
						
							|  |  |  | 		pCommentBegin = P; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		int count = 1; | 
					
						
							|  |  |  | 		while (*P && count) { | 
					
						
							|  |  |  | 			if (*P == '>') { | 
					
						
							|  |  |  | 				--count; | 
					
						
							|  |  |  | 			} else if (*P == '<') { | 
					
						
							|  |  |  | 				++count; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 			next_char(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 		if (count) { | 
					
						
							|  |  |  | 			pCommentEnd = P; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			pCommentEnd = P - 1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 	node_name = String::utf8(pCommentBegin, (int)(pCommentEnd - pCommentBegin)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #ifdef DEBUG_XML
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	print_line("XML COMMENT: " + node_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void XMLParser::_parse_opening_xml_element() { | 
					
						
							|  |  |  | 	node_type = NODE_ELEMENT; | 
					
						
							|  |  |  | 	node_empty = false; | 
					
						
							|  |  |  | 	attributes.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// find name
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	const char *startName = P; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// find end of element
 | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 	while (*P && *P != '>' && !_is_white_space(*P)) { | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 		next_char(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	const char *endName = P; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// find attributes
 | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 	while (*P && *P != '>') { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (_is_white_space(*P)) { | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 			next_char(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (*P != '/') { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				// we've got an attribute
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// read the attribute names
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				const char *attributeNameBegin = P; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 				while (*P && !_is_white_space(*P) && *P != '=') { | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 					next_char(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 				if (!*P) { | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				const char *attributeNameEnd = P; | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 				next_char(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// read the attribute value
 | 
					
						
							|  |  |  | 				// check for quotes and single quotes, thx to murphy
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				while ((*P != '\"') && (*P != '\'') && *P) { | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 					next_char(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (!*P) { // malformatted xml file
 | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				const char attributeQuoteChar = *P; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 				next_char(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				const char *attributeValueBegin = P; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				while (*P != attributeQuoteChar && *P) { | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 					next_char(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				const char *attributeValueEnd = P; | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 				if (*P) { | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 					next_char(); | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				Attribute attr; | 
					
						
							|  |  |  | 				attr.name = String::utf8(attributeNameBegin, | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						(int)(attributeNameEnd - attributeNameBegin)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				String s = String::utf8(attributeValueBegin, | 
					
						
							|  |  |  | 						(int)(attributeValueEnd - attributeValueBegin)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-11 09:33:55 -06:00
										 |  |  | 				attr.value = s.xml_unescape(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				attributes.push_back(attr); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				// tag is closed directly
 | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 				next_char(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				node_empty = true; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// check if this tag is closing directly
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (endName > startName && *(endName - 1) == '/') { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		// directly closing tag
 | 
					
						
							|  |  |  | 		node_empty = true; | 
					
						
							|  |  |  | 		endName--; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	node_name = String::utf8(startName, (int)(endName - startName)); | 
					
						
							|  |  |  | #ifdef DEBUG_XML
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	print_line("XML OPEN: " + node_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 	if (*P) { | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 		next_char(); | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void XMLParser::_parse_current_node() { | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | 	const char *start = P; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	node_offset = P - data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// more forward until '<' found
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	while (*P != '<' && *P) { | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 		next_char(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (P - start > 0) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		// we found some text, store it
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (_set_text(start, P)) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-18 15:01:21 +08:00
										 |  |  | 	if (!*P) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 	next_char(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// based on current token, parse and report next element
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	switch (*P) { | 
					
						
							|  |  |  | 		case '/': | 
					
						
							|  |  |  | 			_parse_closing_xml_element(); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case '?': | 
					
						
							|  |  |  | 			_ignore_definition(); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case '!': | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			if (!_parse_cdata()) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				_parse_comment(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			_parse_opening_xml_element(); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint64_t XMLParser::get_node_offset() const { | 
					
						
							|  |  |  | 	return node_offset; | 
					
						
							| 
									
										
										
										
											2020-05-19 15:46:49 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Error XMLParser::seek(uint64_t p_pos) { | 
					
						
							| 
									
										
										
										
											2023-09-09 16:11:33 +02:00
										 |  |  | 	ERR_FAIL_NULL_V(data, ERR_FILE_EOF); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	ERR_FAIL_COND_V(p_pos >= length, ERR_FILE_EOF); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	P = data + p_pos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return read(); | 
					
						
							| 
									
										
										
										
											2020-05-19 15:46:49 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | void XMLParser::_bind_methods() { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("read"), &XMLParser::read); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_node_type"), &XMLParser::get_node_type); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_node_name"), &XMLParser::get_node_name); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_node_data"), &XMLParser::get_node_data); | 
					
						
							|  |  |  | 	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); | 
					
						
							| 
									
										
										
										
											2022-11-28 11:00:48 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_attribute_value", "idx"), &XMLParser::get_attribute_value); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("has_attribute", "name"), &XMLParser::has_attribute); | 
					
						
							| 
									
										
										
										
											2022-11-28 11:00:48 +02:00
										 |  |  | 	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); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	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); | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("seek", "position"), &XMLParser::seek); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("open", "file"), &XMLParser::open); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("open_buffer", "buffer"), &XMLParser::open_buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 	BIND_ENUM_CONSTANT(NODE_NONE); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(NODE_ELEMENT); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(NODE_ELEMENT_END); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(NODE_TEXT); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(NODE_COMMENT); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(NODE_CDATA); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(NODE_UNKNOWN); | 
					
						
							| 
									
										
										
										
											2020-05-19 15:46:49 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Error XMLParser::read() { | 
					
						
							| 
									
										
										
										
											2021-03-12 19:05:16 +05:30
										 |  |  | 	// if end not reached, parse the node
 | 
					
						
							| 
									
										
										
										
											2017-08-31 23:30:35 +02:00
										 |  |  | 	if (P && (P - data) < (int64_t)length - 1 && *P != 0) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		_parse_current_node(); | 
					
						
							|  |  |  | 		return OK; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ERR_FILE_EOF; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | XMLParser::NodeType XMLParser::get_node_type() { | 
					
						
							|  |  |  | 	return node_type; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | String XMLParser::get_node_data() const { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND_V(node_type != NODE_TEXT, ""); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return node_name; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String XMLParser::get_node_name() const { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND_V(node_type == NODE_TEXT, ""); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return node_name; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | int XMLParser::get_attribute_count() const { | 
					
						
							|  |  |  | 	return attributes.size(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | String XMLParser::get_attribute_name(int p_idx) const { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_INDEX_V(p_idx, attributes.size(), ""); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return attributes[p_idx].name; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | String XMLParser::get_attribute_value(int p_idx) const { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_INDEX_V(p_idx, attributes.size(), ""); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return attributes[p_idx].value; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool XMLParser::has_attribute(const String &p_name) const { | 
					
						
							|  |  |  | 	for (int i = 0; i < attributes.size(); i++) { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (attributes[i].name == p_name) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-28 11:00:48 +02:00
										 |  |  | String XMLParser::get_named_attribute_value(const String &p_name) const { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	int idx = -1; | 
					
						
							|  |  |  | 	for (int i = 0; i < attributes.size(); i++) { | 
					
						
							|  |  |  | 		if (attributes[i].name == p_name) { | 
					
						
							|  |  |  | 			idx = i; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 20:57:49 -06:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(idx < 0, "", "Attribute not found: " + p_name + "."); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return attributes[idx].value; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-28 11:00:48 +02:00
										 |  |  | String XMLParser::get_named_attribute_value_safe(const String &p_name) const { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	int idx = -1; | 
					
						
							|  |  |  | 	for (int i = 0; i < attributes.size(); i++) { | 
					
						
							|  |  |  | 		if (attributes[i].name == p_name) { | 
					
						
							|  |  |  | 			idx = i; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (idx < 0) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return ""; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return attributes[idx].value; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | bool XMLParser::is_empty() const { | 
					
						
							|  |  |  | 	return node_empty; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | Error XMLParser::open_buffer(const Vector<uint8_t> &p_buffer) { | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(p_buffer.size() == 0, ERR_INVALID_DATA); | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | 	if (data_copy) { | 
					
						
							|  |  |  | 		memdelete_arr(data_copy); | 
					
						
							|  |  |  | 		data_copy = nullptr; | 
					
						
							| 
									
										
										
										
											2020-01-20 11:29:14 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 	length = p_buffer.size(); | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | 	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); | 
					
						
							| 
									
										
										
										
											2023-09-09 16:11:33 +02:00
										 |  |  | 	ERR_FAIL_NULL_V(p_buffer, ERR_INVALID_DATA); | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (data_copy) { | 
					
						
							|  |  |  | 		memdelete_arr(data_copy); | 
					
						
							|  |  |  | 		data_copy = nullptr; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	length = p_size; | 
					
						
							|  |  |  | 	data = (const char *)p_buffer; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	P = data; | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | 	current_line = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-15 21:16:33 -03:00
										 |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | Error XMLParser::open(const String &p_path) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	Error err; | 
					
						
							| 
									
										
										
										
											2022-03-23 11:08:58 +02:00
										 |  |  | 	Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::READ, &err); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open file '" + p_path + "'."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 07:58:49 +01:00
										 |  |  | 	length = file->get_length(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND_V(length < 1, ERR_FILE_CORRUPT); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | 	if (data_copy) { | 
					
						
							|  |  |  | 		memdelete_arr(data_copy); | 
					
						
							|  |  |  | 		data_copy = nullptr; | 
					
						
							| 
									
										
										
										
											2020-01-20 11:29:14 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | 	data_copy = memnew_arr(char, length + 1); | 
					
						
							|  |  |  | 	file->get_buffer((uint8_t *)data_copy, length); | 
					
						
							|  |  |  | 	data_copy[length] = 0; | 
					
						
							|  |  |  | 	data = data_copy; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	P = data; | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 	current_line = 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void XMLParser::skip_section() { | 
					
						
							|  |  |  | 	// skip if this element is empty anyway.
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (is_empty()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// read until we've reached the last element in this section
 | 
					
						
							|  |  |  | 	int tagcount = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while (tagcount && read() == OK) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		if (get_node_type() == XMLParser::NODE_ELEMENT && | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				!is_empty()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			++tagcount; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} else if (get_node_type() == XMLParser::NODE_ELEMENT_END) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			--tagcount; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void XMLParser::close() { | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | 	if (data_copy) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		memdelete_arr(data); | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | 		data_copy = nullptr; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	data = nullptr; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	length = 0; | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	P = nullptr; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	node_empty = false; | 
					
						
							|  |  |  | 	node_type = NODE_NONE; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	node_offset = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int XMLParser::get_current_line() const { | 
					
						
							| 
									
										
										
										
											2022-07-05 01:23:04 +02:00
										 |  |  | 	return current_line; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | XMLParser::~XMLParser() { | 
					
						
							| 
									
										
										
										
											2022-06-14 10:29:58 +03:00
										 |  |  | 	if (data_copy) { | 
					
						
							|  |  |  | 		memdelete_arr(data_copy); | 
					
						
							|  |  |  | 		data_copy = nullptr; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } |