1 | /**************************************************************************/ |
2 | /* dir_access.h */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #ifndef DIR_ACCESS_H |
32 | #define DIR_ACCESS_H |
33 | |
34 | #include "core/object/ref_counted.h" |
35 | #include "core/string/ustring.h" |
36 | #include "core/typedefs.h" |
37 | |
38 | //@ TODO, excellent candidate for THREAD_SAFE MACRO, should go through all these and add THREAD_SAFE where it applies |
39 | class DirAccess : public RefCounted { |
40 | GDCLASS(DirAccess, RefCounted); |
41 | |
42 | public: |
43 | enum AccessType { |
44 | ACCESS_RESOURCES, |
45 | ACCESS_USERDATA, |
46 | ACCESS_FILESYSTEM, |
47 | ACCESS_MAX |
48 | }; |
49 | |
50 | typedef Ref<DirAccess> (*CreateFunc)(); |
51 | |
52 | private: |
53 | AccessType _access_type = ACCESS_FILESYSTEM; |
54 | static CreateFunc create_func[ACCESS_MAX]; ///< set this to instance a filesystem object |
55 | static Ref<DirAccess> _open(const String &p_path); |
56 | |
57 | Error _copy_dir(Ref<DirAccess> &p_target_da, String p_to, int p_chmod_flags, bool p_copy_links); |
58 | PackedStringArray _get_contents(bool p_directories); |
59 | |
60 | thread_local static Error last_dir_open_error; |
61 | bool include_navigational = false; |
62 | bool include_hidden = false; |
63 | |
64 | protected: |
65 | static void _bind_methods(); |
66 | |
67 | String _get_root_path() const; |
68 | virtual String _get_root_string() const; |
69 | |
70 | AccessType get_access_type() const; |
71 | virtual String fix_path(String p_path) const; |
72 | |
73 | template <class T> |
74 | static Ref<DirAccess> _create_builtin() { |
75 | return memnew(T); |
76 | } |
77 | |
78 | public: |
79 | virtual Error list_dir_begin() = 0; ///< This starts dir listing |
80 | virtual String get_next() = 0; |
81 | virtual bool current_is_dir() const = 0; |
82 | virtual bool current_is_hidden() const = 0; |
83 | |
84 | virtual void list_dir_end() = 0; ///< |
85 | |
86 | virtual int get_drive_count() = 0; |
87 | virtual String get_drive(int p_drive) = 0; |
88 | virtual int get_current_drive(); |
89 | virtual bool drives_are_shortcuts(); |
90 | |
91 | virtual Error change_dir(String p_dir) = 0; ///< can be relative or absolute, return false on success |
92 | virtual String get_current_dir(bool p_include_drive = true) const = 0; ///< return current dir location |
93 | virtual Error make_dir(String p_dir) = 0; |
94 | virtual Error make_dir_recursive(String p_dir); |
95 | virtual Error erase_contents_recursive(); //super dangerous, use with care! |
96 | |
97 | virtual bool file_exists(String p_file) = 0; |
98 | virtual bool dir_exists(String p_dir) = 0; |
99 | virtual bool is_readable(String p_dir) { return true; }; |
100 | virtual bool is_writable(String p_dir) { return true; }; |
101 | static bool exists(String p_dir); |
102 | virtual uint64_t get_space_left() = 0; |
103 | |
104 | Error copy_dir(String p_from, String p_to, int p_chmod_flags = -1, bool p_copy_links = false); |
105 | virtual Error copy(String p_from, String p_to, int p_chmod_flags = -1); |
106 | virtual Error rename(String p_from, String p_to) = 0; |
107 | virtual Error remove(String p_name) = 0; |
108 | |
109 | virtual bool is_link(String p_file) = 0; |
110 | virtual String read_link(String p_file) = 0; |
111 | virtual Error create_link(String p_source, String p_target) = 0; |
112 | |
113 | // Meant for editor code when we want to quickly remove a file without custom |
114 | // handling (e.g. removing a cache file). |
115 | static void remove_file_or_error(String p_path) { |
116 | Ref<DirAccess> da = create(ACCESS_FILESYSTEM); |
117 | if (da->file_exists(p_path)) { |
118 | if (da->remove(p_path) != OK) { |
119 | ERR_FAIL_MSG("Cannot remove file or directory: " + p_path); |
120 | } |
121 | } else { |
122 | ERR_FAIL_MSG("Cannot remove non-existent file or directory: " + p_path); |
123 | } |
124 | } |
125 | |
126 | virtual String get_filesystem_type() const = 0; |
127 | static String get_full_path(const String &p_path, AccessType p_access); |
128 | static Ref<DirAccess> create_for_path(const String &p_path); |
129 | |
130 | static Ref<DirAccess> create(AccessType p_access); |
131 | static Error get_open_error(); |
132 | |
133 | template <class T> |
134 | static void make_default(AccessType p_access) { |
135 | create_func[p_access] = _create_builtin<T>; |
136 | } |
137 | |
138 | static Ref<DirAccess> open(const String &p_path, Error *r_error = nullptr); |
139 | |
140 | static int _get_drive_count(); |
141 | static String get_drive_name(int p_idx); |
142 | |
143 | static Error make_dir_absolute(const String &p_dir); |
144 | static Error make_dir_recursive_absolute(const String &p_dir); |
145 | static bool dir_exists_absolute(const String &p_dir); |
146 | |
147 | static Error copy_absolute(const String &p_from, const String &p_to, int p_chmod_flags = -1); |
148 | static Error rename_absolute(const String &p_from, const String &p_to); |
149 | static Error remove_absolute(const String &p_path); |
150 | |
151 | PackedStringArray get_files(); |
152 | static PackedStringArray get_files_at(const String &p_path); |
153 | PackedStringArray get_directories(); |
154 | static PackedStringArray get_directories_at(const String &p_path); |
155 | String _get_next(); |
156 | |
157 | void set_include_navigational(bool p_enable); |
158 | bool get_include_navigational() const; |
159 | void set_include_hidden(bool p_enable); |
160 | bool get_include_hidden() const; |
161 | |
162 | DirAccess() {} |
163 | virtual ~DirAccess() {} |
164 | }; |
165 | |
166 | #endif // DIR_ACCESS_H |
167 | |