| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  file_access_buffered.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_buffered.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/error_macros.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Error FileAccessBuffered::set_error(Error p_error) const { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return (last_error = p_error); | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | void FileAccessBuffered::set_cache_size(int p_size) { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	cache_size = p_size; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | int FileAccessBuffered::get_cache_size() { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return cache_size; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | int FileAccessBuffered::cache_data_left() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (file.offset >= file.size) { | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (cache.offset == -1 || file.offset < cache.offset || file.offset >= cache.offset + cache.buffer.size()) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return read_data_block(file.offset, cache_size); | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | 	return cache.buffer.size() - (file.offset - cache.offset); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | void FileAccessBuffered::seek(size_t p_position) { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	file.offset = p_position; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | void FileAccessBuffered::seek_end(int64_t p_position) { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	file.offset = file.size + p_position; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-10 15:37:49 +02:00
										 |  |  | size_t FileAccessBuffered::get_position() const { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return file.offset; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | size_t FileAccessBuffered::get_len() const { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return file.size; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool FileAccessBuffered::eof_reached() const { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return file.offset > file.size; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | uint8_t FileAccessBuffered::get_8() const { | 
					
						
							| 
									
										
										
										
											2019-08-14 20:57:49 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V_MSG(!file.open, 0, "Can't get data, when file is not opened."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	uint8_t byte = 0; | 
					
						
							|  |  |  | 	if (cache_data_left() >= 1) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		byte = cache.buffer[file.offset - cache.offset]; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	++file.offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return byte; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const { | 
					
						
							| 
									
										
										
										
											2019-08-14 20:57:49 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V_MSG(!file.open, -1, "Can't get buffer, when file is not opened."); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | 	if (p_length > cache_size) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		int total_read = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!(cache.offset == -1 || file.offset < cache.offset || file.offset >= cache.offset + cache.buffer.size())) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			int size = (cache.buffer.size() - (file.offset - cache.offset)); | 
					
						
							|  |  |  | 			size = size - (size % 4); | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 			//const uint8_t* read = cache.buffer.ptr();
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			//memcpy(p_dest, read.ptr() + (file.offset - cache.offset), size);
 | 
					
						
							|  |  |  | 			memcpy(p_dest, cache.buffer.ptr() + (file.offset - cache.offset), size); | 
					
						
							|  |  |  | 			p_dest += size; | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | 			p_length -= size; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			file.offset += size; | 
					
						
							|  |  |  | 			total_read += size; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | 		int err = read_data_block(file.offset, p_length, p_dest); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		if (err >= 0) { | 
					
						
							|  |  |  | 			total_read += err; | 
					
						
							|  |  |  | 			file.offset += err; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return total_read; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | 	int to_read = p_length; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	int total_read = 0; | 
					
						
							|  |  |  | 	while (to_read > 0) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		int left = cache_data_left(); | 
					
						
							|  |  |  | 		if (left == 0) { | 
					
						
							| 
									
										
										
										
											2019-06-20 16:59:48 +02:00
										 |  |  | 			file.offset += to_read; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return total_read; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		if (left < 0) { | 
					
						
							|  |  |  | 			return left; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		int r = MIN(left, to_read); | 
					
						
							| 
									
										
										
										
											2020-02-17 18:06:54 -03:00
										 |  |  | 		//const uint8_t* read = cache.buffer.ptr();
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		//memcpy(p_dest+total_read, &read.ptr()[file.offset - cache.offset], r);
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		memcpy(p_dest + total_read, cache.buffer.ptr() + (file.offset - cache.offset), r); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		file.offset += r; | 
					
						
							|  |  |  | 		total_read += r; | 
					
						
							|  |  |  | 		to_read -= r; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | 	return p_length; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool FileAccessBuffered::is_open() const { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return file.open; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Error FileAccessBuffered::get_error() const { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return last_error; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | FileAccessBuffered::FileAccessBuffered() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cache_size = DEFAULT_CACHE_SIZE; | 
					
						
							| 
									
										
										
										
											2019-07-01 12:59:42 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | FileAccessBuffered::~FileAccessBuffered() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } |