| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  file_access_pack.h                                                   */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							|  |  |  | /*                    http://www.godotengine.org                         */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2017-01-01 22:01:57 +01:00
										 |  |  | /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							| 
									
										
										
										
											2017-04-08 00:11:42 +02:00
										 |  |  | /* Copyright (c) 2014-2017 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.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | #ifndef FILE_ACCESS_PACK_H
 | 
					
						
							|  |  |  | #define FILE_ACCESS_PACK_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "list.h"
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | #include "map.h"
 | 
					
						
							|  |  |  | #include "os/dir_access.h"
 | 
					
						
							|  |  |  | #include "os/file_access.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "print_string.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PackSource; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PackedData { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	friend class FileAccessPack; | 
					
						
							|  |  |  | 	friend class DirAccessPack; | 
					
						
							|  |  |  | 	friend class PackSource; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  | 	struct PackedFile { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		String pack; | 
					
						
							| 
									
										
										
										
											2014-02-13 18:03:28 -03:00
										 |  |  | 		uint64_t offset; //if offset is ZERO, the file was ERASED
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		uint64_t size; | 
					
						
							| 
									
										
										
										
											2014-02-13 18:03:28 -03:00
										 |  |  | 		uint8_t md5[16]; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		PackSource *src; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  | 	struct PackedDir { | 
					
						
							|  |  |  | 		PackedDir *parent; | 
					
						
							|  |  |  | 		String name; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Map<String, PackedDir *> subdirs; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		Set<String> files; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 22:10:38 -03:00
										 |  |  | 	struct PathMD5 { | 
					
						
							|  |  |  | 		uint64_t a; | 
					
						
							|  |  |  | 		uint64_t b; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		bool operator<(const PathMD5 &p_md5) const { | 
					
						
							| 
									
										
										
										
											2014-08-01 22:10:38 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (p_md5.a == a) { | 
					
						
							|  |  |  | 				return b < p_md5.b; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				return a < p_md5.a; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		bool operator==(const PathMD5 &p_md5) const { | 
					
						
							| 
									
										
										
										
											2014-08-01 22:10:38 -03:00
										 |  |  | 			return a == p_md5.a && b == p_md5.b; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		PathMD5() { | 
					
						
							|  |  |  | 			a = b = 0; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		PathMD5(const Vector<uint8_t> p_buf) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			a = *((uint64_t *)&p_buf[0]); | 
					
						
							|  |  |  | 			b = *((uint64_t *)&p_buf[8]); | 
					
						
							| 
									
										
										
										
											2014-08-01 22:10:38 -03:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Map<PathMD5, PackedFile> files; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Vector<PackSource *> sources; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	PackedDir *root; | 
					
						
							|  |  |  | 	//Map<String,PackedDir*> dirs;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	static PackedData *singleton; | 
					
						
							|  |  |  | 	bool disabled; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-20 19:38:02 -03:00
										 |  |  | 	void _free_packed_dirs(PackedDir *p_dir); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	void add_pack_source(PackSource *p_source); | 
					
						
							|  |  |  | 	void add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src); // for PackSource
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	void set_disabled(bool p_disabled) { disabled = p_disabled; } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	_FORCE_INLINE_ bool is_disabled() const { return disabled; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	static PackedData *get_singleton() { return singleton; } | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Error add_pack(const String &p_path); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	_FORCE_INLINE_ FileAccess *try_open_path(const String &p_path); | 
					
						
							|  |  |  | 	_FORCE_INLINE_ bool has_path(const String &p_path); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	PackedData(); | 
					
						
							| 
									
										
										
										
											2015-04-20 19:38:02 -03:00
										 |  |  | 	~PackedData(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PackSource { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	virtual bool try_open_pack(const String &p_path) = 0; | 
					
						
							|  |  |  | 	virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0; | 
					
						
							| 
									
										
										
										
											2015-04-20 19:38:02 -03:00
										 |  |  | 	virtual ~PackSource() {} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class PackedSourcePCK : public PackSource { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  | 	virtual bool try_open_pack(const String &p_path); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class FileAccessPack : public FileAccess { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PackedData::PackedFile pf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mutable size_t pos; | 
					
						
							|  |  |  | 	mutable bool eof; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	FileAccess *f; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	virtual Error _open(const String &p_path, int p_mode_flags); | 
					
						
							|  |  |  | 	virtual uint64_t _get_modified_time(const String &p_file) { return 0; } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  | 	virtual void close(); | 
					
						
							|  |  |  | 	virtual bool is_open() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual void seek(size_t p_position); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	virtual void seek_end(int64_t p_position = 0); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	virtual size_t get_pos() const; | 
					
						
							|  |  |  | 	virtual size_t get_len() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual bool eof_reached() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual uint8_t get_8() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	virtual int get_buffer(uint8_t *p_dst, int p_length) const; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	virtual void set_endian_swap(bool p_swap); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual Error get_error() const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual void store_8(uint8_t p_dest); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	virtual void store_buffer(const uint8_t *p_src, int p_length); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	virtual bool file_exists(const String &p_name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	~FileAccessPack(); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | FileAccess *PackedData::try_open_path(const String &p_path) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 22:10:38 -03:00
										 |  |  | 	//print_line("try open path " + p_path);
 | 
					
						
							|  |  |  | 	PathMD5 pmd5(p_path.md5_buffer()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Map<PathMD5, PackedFile>::Element *E = files.find(pmd5); | 
					
						
							| 
									
										
										
										
											2014-02-13 18:03:28 -03:00
										 |  |  | 	if (!E) | 
					
						
							|  |  |  | 		return NULL; //not found
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (E->get().offset == 0) | 
					
						
							| 
									
										
										
										
											2014-02-13 18:03:28 -03:00
										 |  |  | 		return NULL; //was erased
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-13 18:03:28 -03:00
										 |  |  | 	return E->get().src->get_file(p_path, &E->get()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | bool PackedData::has_path(const String &p_path) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-01 22:10:38 -03:00
										 |  |  | 	return files.has(PathMD5(p_path.md5_buffer())); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class DirAccessPack : public DirAccess { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	PackedData::PackedDir *current; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	List<String> list_dirs; | 
					
						
							|  |  |  | 	List<String> list_files; | 
					
						
							|  |  |  | 	bool cdir; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2017-01-14 09:16:41 -03:00
										 |  |  | 	virtual Error list_dir_begin(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	virtual String get_next(); | 
					
						
							|  |  |  | 	virtual bool current_is_dir() const; | 
					
						
							| 
									
										
										
										
											2015-03-21 18:33:32 +01:00
										 |  |  | 	virtual bool current_is_hidden() const; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	virtual void list_dir_end(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual int get_drive_count(); | 
					
						
							|  |  |  | 	virtual String get_drive(int p_drive); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual Error change_dir(String p_dir); | 
					
						
							|  |  |  | 	virtual String get_current_dir(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual bool file_exists(String p_file); | 
					
						
							| 
									
										
										
										
											2014-05-25 11:34:51 +08:00
										 |  |  | 	virtual bool dir_exists(String p_dir); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	virtual Error make_dir(String p_dir); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	virtual Error rename(String p_from, String p_to); | 
					
						
							|  |  |  | 	virtual Error remove(String p_name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	size_t get_space_left(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	DirAccessPack(); | 
					
						
							|  |  |  | 	~DirAccessPack(); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif // FILE_ACCESS_PACK_H
 |