| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  file_access_memory.cpp                                               */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2020-01-01 11:16:22 +01:00
										 |  |  | /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* 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"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/map.h"
 | 
					
						
							|  |  |  | #include "core/os/copymem.h"
 | 
					
						
							|  |  |  | #include "core/os/dir_access.h"
 | 
					
						
							|  |  |  | #include "core/project_settings.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | static Map<String, Vector<uint8_t> > *files = NULL; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | void FileAccessMemory::register_file(String p_name, Vector<uint8_t> p_data) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!files) { | 
					
						
							|  |  |  | 		files = memnew((Map<String, Vector<uint8_t> >)); | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	String name; | 
					
						
							| 
									
										
										
										
											2017-07-19 17:00:46 -03:00
										 |  |  | 	if (ProjectSettings::get_singleton()) | 
					
						
							|  |  |  | 		name = ProjectSettings::get_singleton()->globalize_path(p_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		name = p_name; | 
					
						
							| 
									
										
										
										
											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() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!files) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memdelete(files); | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool FileAccessMemory::file_exists(const String &p_name) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	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
										 |  |  | 
 | 
					
						
							|  |  |  | 	return files && (files->find(name) != NULL); | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | Error FileAccessMemory::open_custom(const uint8_t *p_data, int p_len) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	data = (uint8_t *)p_data; | 
					
						
							|  |  |  | 	length = p_len; | 
					
						
							|  |  |  | 	pos = 0; | 
					
						
							| 
									
										
										
										
											2015-05-31 01:59:42 -03:00
										 |  |  | 	return OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | Error FileAccessMemory::_open(const String &p_path, int p_mode_flags) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!files, ERR_FILE_NOT_FOUND); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Map<String, Vector<uint8_t> >::Element *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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	data = E->get().ptrw(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	length = E->get().size(); | 
					
						
							|  |  |  | 	pos = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OK; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | void FileAccessMemory::close() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	data = NULL; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool FileAccessMemory::is_open() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return data != NULL; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | void FileAccessMemory::seek(size_t p_position) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!data); | 
					
						
							|  |  |  | 	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) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!data); | 
					
						
							|  |  |  | 	pos = length + p_position; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | size_t FileAccessMemory::get_position() const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!data, 0); | 
					
						
							|  |  |  | 	return pos; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | size_t FileAccessMemory::get_len() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!data, 0); | 
					
						
							|  |  |  | 	return length; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool FileAccessMemory::eof_reached() const { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-27 19:58:28 -03: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | int FileAccessMemory::get_buffer(uint8_t *p_dst, int p_length) const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(!data, -1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int left = length - pos; | 
					
						
							|  |  |  | 	int read = MIN(p_length, left); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (read < p_length) { | 
					
						
							|  |  |  | 		WARN_PRINT("Reading less data than requested"); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	copymem(p_dst, &data[pos], read); | 
					
						
							|  |  |  | 	pos += p_length; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	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() { | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!data); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void FileAccessMemory::store_8(uint8_t p_byte) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!data); | 
					
						
							|  |  |  | 	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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void FileAccessMemory::store_buffer(const uint8_t *p_src, int p_length) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	int left = length - pos; | 
					
						
							|  |  |  | 	int write = MIN(p_length, left); | 
					
						
							|  |  |  | 	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
										 |  |  | 
 | 
					
						
							|  |  |  | 	copymem(&data[pos], p_src, write); | 
					
						
							|  |  |  | 	pos += p_length; | 
					
						
							| 
									
										
										
										
											2015-05-03 01:48:20 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | FileAccessMemory::FileAccessMemory() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	data = NULL; | 
					
						
							|  |  |  | } |