| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /**************************************************************************/ | 
					
						
							|  |  |  | /*  file_access_memory.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 "file_access_memory.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-07 19:33:38 -03:00
										 |  |  | #include "core/config/project_settings.h"
 | 
					
						
							| 
									
										
										
										
											2021-06-11 14:51:48 +02:00
										 |  |  | #include "core/io/dir_access.h"
 | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | #include "core/templates/rb_map.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | static HashMap<String, Vector<uint8_t>> *files = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | void FileAccessMemory::register_file(String p_name, Vector<uint8_t> p_data) { | 
					
						
							|  |  |  | 	if (!files) { | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 		files = memnew((HashMap<String, Vector<uint8_t>>)); | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	String name; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (ProjectSettings::get_singleton()) { | 
					
						
							| 
									
										
										
										
											2017-07-19 17:00:46 -03:00
										 |  |  | 		name = ProjectSettings::get_singleton()->globalize_path(p_name); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		name = p_name; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-06-18 11:12:08 -03:00
										 |  |  | 	//name = DirAccess::normalize_path(name);
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	(*files)[name] = p_data; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | void FileAccessMemory::cleanup() { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!files) { | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							|  |  |  | 	memdelete(files); | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-23 11:08:58 +02:00
										 |  |  | Ref<FileAccess> FileAccessMemory::create() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return memnew(FileAccessMemory); | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool FileAccessMemory::file_exists(const String &p_name) { | 
					
						
							|  |  |  | 	String name = fix_path(p_name); | 
					
						
							| 
									
										
										
										
											2017-01-14 12:26:56 +01:00
										 |  |  | 	//name = DirAccess::normalize_path(name);
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	return files && (files->find(name) != nullptr); | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 18:51:13 +01:00
										 |  |  | Error FileAccessMemory::open_custom(const uint8_t *p_data, uint64_t p_len) { | 
					
						
							| 
									
										
										
										
											2015-05-31 01:59:42 -03:00
										 |  |  | 	data = (uint8_t *)p_data; | 
					
						
							|  |  |  | 	length = p_len; | 
					
						
							|  |  |  | 	pos = 0; | 
					
						
							|  |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-05 13:01:31 +02:00
										 |  |  | Error FileAccessMemory::open_internal(const String &p_path, int p_mode_flags) { | 
					
						
							| 
									
										
										
										
											2023-09-09 16:11:33 +02:00
										 |  |  | 	ERR_FAIL_NULL_V(files, ERR_FILE_NOT_FOUND); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	String name = fix_path(p_path); | 
					
						
							| 
									
										
										
										
											2017-01-14 12:26:56 +01:00
										 |  |  | 	//name = DirAccess::normalize_path(name);
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 	HashMap<String, Vector<uint8_t>>::Iterator E = files->find(name); | 
					
						
							| 
									
										
										
										
											2019-09-25 10:28:50 +02:00
										 |  |  | 	ERR_FAIL_COND_V_MSG(!E, ERR_FILE_NOT_FOUND, "Can't find file '" + p_path + "'."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 	data = E->value.ptrw(); | 
					
						
							|  |  |  | 	length = E->value.size(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	pos = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OK; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool FileAccessMemory::is_open() const { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	return data != nullptr; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 18:51:13 +01:00
										 |  |  | void FileAccessMemory::seek(uint64_t p_position) { | 
					
						
							| 
									
										
										
										
											2023-09-09 16:11:33 +02:00
										 |  |  | 	ERR_FAIL_NULL(data); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	pos = p_position; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | void FileAccessMemory::seek_end(int64_t p_position) { | 
					
						
							| 
									
										
										
										
											2023-09-09 16:11:33 +02:00
										 |  |  | 	ERR_FAIL_NULL(data); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	pos = length + p_position; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 18:51:13 +01:00
										 |  |  | uint64_t FileAccessMemory::get_position() const { | 
					
						
							| 
									
										
										
										
											2023-09-09 16:11:33 +02:00
										 |  |  | 	ERR_FAIL_NULL_V(data, 0); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return pos; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-25 07:58:49 +01:00
										 |  |  | uint64_t FileAccessMemory::get_length() const { | 
					
						
							| 
									
										
										
										
											2023-09-09 16:11:33 +02:00
										 |  |  | 	ERR_FAIL_NULL_V(data, 0); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return length; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool FileAccessMemory::eof_reached() const { | 
					
						
							| 
									
										
										
										
											2024-01-25 10:35:51 +01:00
										 |  |  | 	return pos >= length; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | uint8_t FileAccessMemory::get_8() const { | 
					
						
							| 
									
										
										
										
											2015-05-03 01:45:55 +02:00
										 |  |  | 	uint8_t ret = 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (pos < length) { | 
					
						
							|  |  |  | 		ret = data[pos]; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	++pos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 18:51:13 +01:00
										 |  |  | uint64_t FileAccessMemory::get_buffer(uint8_t *p_dst, uint64_t p_length) const { | 
					
						
							| 
									
										
										
										
											2021-03-16 22:55:11 +01:00
										 |  |  | 	ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); | 
					
						
							| 
									
										
										
										
											2023-09-09 16:11:33 +02:00
										 |  |  | 	ERR_FAIL_NULL_V(data, -1); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 18:51:13 +01:00
										 |  |  | 	uint64_t left = length - pos; | 
					
						
							|  |  |  | 	uint64_t read = MIN(p_length, left); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (read < p_length) { | 
					
						
							|  |  |  | 		WARN_PRINT("Reading less data than requested"); | 
					
						
							| 
									
										
										
										
											2020-05-19 15:46:49 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-27 16:19:21 +02:00
										 |  |  | 	memcpy(p_dst, &data[pos], read); | 
					
						
							| 
									
										
										
										
											2023-04-04 09:54:33 +02:00
										 |  |  | 	pos += read; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return read; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Error FileAccessMemory::get_error() const { | 
					
						
							|  |  |  | 	return pos >= length ? ERR_FILE_EOF : OK; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-22 12:56:02 +07:00
										 |  |  | void FileAccessMemory::flush() { | 
					
						
							| 
									
										
										
										
											2023-09-09 16:11:33 +02:00
										 |  |  | 	ERR_FAIL_NULL(data); | 
					
						
							| 
									
										
										
										
											2017-09-22 12:56:02 +07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void FileAccessMemory::store_8(uint8_t p_byte) { | 
					
						
							| 
									
										
										
										
											2023-09-09 16:11:33 +02:00
										 |  |  | 	ERR_FAIL_NULL(data); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	ERR_FAIL_COND(pos >= length); | 
					
						
							|  |  |  | 	data[pos++] = p_byte; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 18:51:13 +01:00
										 |  |  | void FileAccessMemory::store_buffer(const uint8_t *p_src, uint64_t p_length) { | 
					
						
							| 
									
										
										
										
											2021-06-07 18:31:50 +02:00
										 |  |  | 	ERR_FAIL_COND(!p_src && p_length > 0); | 
					
						
							| 
									
										
										
										
											2019-03-26 18:51:13 +01:00
										 |  |  | 	uint64_t left = length - pos; | 
					
						
							|  |  |  | 	uint64_t write = MIN(p_length, left); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	if (write < p_length) { | 
					
						
							|  |  |  | 		WARN_PRINT("Writing less data than requested"); | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-27 16:19:21 +02:00
										 |  |  | 	memcpy(&data[pos], p_src, write); | 
					
						
							| 
									
										
										
										
											2023-04-04 09:54:33 +02:00
										 |  |  | 	pos += write; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } |