file_access_pack.h
1 /*************************************************************************/
2 /* file_access_pack.h */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* http://www.godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
9 /* */
10 /* Permission is hereby granted, free of charge, to any person obtaining */
11 /* a copy of this software and associated documentation files (the */
12 /* "Software"), to deal in the Software without restriction, including */
13 /* without limitation the rights to use, copy, modify, merge, publish, */
14 /* distribute, sublicense, and/or sell copies of the Software, and to */
15 /* permit persons to whom the Software is furnished to do so, subject to */
16 /* the following conditions: */
17 /* */
18 /* The above copyright notice and this permission notice shall be */
19 /* included in all copies or substantial portions of the Software. */
20 /* */
21 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
22 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
23 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
24 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
25 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
26 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
27 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
28 /*************************************************************************/
29 #ifndef FILE_ACCESS_PACK_H
30 #define FILE_ACCESS_PACK_H
31 
32 #include "os/file_access.h"
33 #include "os/dir_access.h"
34 #include "map.h"
35 #include "list.h"
36 #include "print_string.h"
37 
38 class PackSource;
39 
40 class PackedData {
41 friend class FileAccessPack;
42 friend class DirAccessPack;
43 friend class PackSource;
44 
45 public:
46  struct PackedFile {
47 
48  String pack;
49  uint64_t offset; //if offset is ZERO, the file was ERASED
50  uint64_t size;
51  uint8_t md5[16];
52  PackSource* src;
53  };
54 
55 private:
56  struct PackedDir {
57  PackedDir *parent;
58  String name;
59  Map<String,PackedDir*> subdirs;
60  Set<String> files;
61  };
62 
63  struct PathMD5 {
64  uint64_t a;
65  uint64_t b;
66  bool operator < (const PathMD5& p_md5) const {
67 
68  if (p_md5.a == a) {
69  return b < p_md5.b;
70  } else {
71  return a < p_md5.a;
72  }
73  }
74 
75  bool operator == (const PathMD5& p_md5) const {
76  return a == p_md5.a && b == p_md5.b;
77  };
78 
79  PathMD5() {
80  a = b = 0;
81  };
82 
83  PathMD5(const Vector<uint8_t> p_buf) {
84  a = *((uint64_t*)&p_buf[0]);
85  b = *((uint64_t*)&p_buf[8]);
86  };
87  };
88 
90 
91  Vector<PackSource*> sources;
92 
93  PackedDir *root;
94  //Map<String,PackedDir*> dirs;
95 
96  static PackedData *singleton;
97  bool disabled;
98 
99  void _free_packed_dirs(PackedDir *p_dir);
100 
101 public:
102 
103  void add_pack_source(PackSource* p_source);
104  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
105 
106  void set_disabled(bool p_disabled) { disabled=p_disabled; }
107  _FORCE_INLINE_ bool is_disabled() const { return disabled; }
108 
109  static PackedData *get_singleton() { return singleton; }
110  Error add_pack(const String& p_path);
111 
112  _FORCE_INLINE_ FileAccess *try_open_path(const String& p_path);
113  _FORCE_INLINE_ bool has_path(const String& p_path);
114 
115  PackedData();
116  ~PackedData();
117 };
118 
119 class PackSource {
120 
121 public:
122 
123  virtual bool try_open_pack(const String& p_path)=0;
124  virtual FileAccess* get_file(const String& p_path, PackedData::PackedFile* p_file)=0;
125  virtual ~PackSource() {}
126 };
127 
128 class PackedSourcePCK : public PackSource {
129 
130 public:
131 
132  virtual bool try_open_pack(const String &p_path);
133  virtual FileAccess* get_file(const String& p_path, PackedData::PackedFile* p_file);
134 };
135 
136 
137 class FileAccessPack : public FileAccess {
138 
140 
141  mutable size_t pos;
142  mutable bool eof;
143 
144  FileAccess *f;
145  virtual Error _open(const String& p_path, int p_mode_flags);
146  virtual uint64_t _get_modified_time(const String& p_file) { return 0; }
147 
148 public:
149 
150 
151  virtual void close();
152  virtual bool is_open() const;
153 
154  virtual void seek(size_t p_position);
155  virtual void seek_end(int64_t p_position=0);
156  virtual size_t get_pos() const;
157  virtual size_t get_len() const;
158 
159  virtual bool eof_reached() const;
160 
161  virtual uint8_t get_8() const;
162 
163 
164  virtual int get_buffer(uint8_t *p_dst,int p_length) const;
165 
166  virtual void set_endian_swap(bool p_swap);
167 
168  virtual Error get_error() const;
169 
170  virtual void store_8(uint8_t p_dest);
171 
172  virtual void store_buffer(const uint8_t *p_src,int p_length);
173 
174  virtual bool file_exists(const String& p_name);
175 
176 
177  FileAccessPack(const String& p_path, const PackedData::PackedFile& p_file);
178  ~FileAccessPack();
179 };
180 
181 
182 FileAccess *PackedData::try_open_path(const String& p_path) {
183 
184  //print_line("try open path " + p_path);
185  PathMD5 pmd5(p_path.md5_buffer());
186  Map<PathMD5,PackedFile>::Element *E=files.find(pmd5);
187  if (!E)
188  return NULL; //not found
189  if (E->get().offset==0)
190  return NULL; //was erased
191 
192  return E->get().src->get_file(p_path, &E->get());
193 }
194 
195 bool PackedData::has_path(const String& p_path) {
196 
197  return files.has(PathMD5(p_path.md5_buffer()));
198 }
199 
200 
201 class DirAccessPack : public DirAccess {
202 
203 
204  PackedData::PackedDir *current;
205 
206  List<String> list_dirs;
207  List<String> list_files;
208  bool cdir;
209 
210 public:
211 
212  virtual bool list_dir_begin();
213  virtual String get_next();
214  virtual bool current_is_dir() const;
215  virtual bool current_is_hidden() const;
216  virtual void list_dir_end();
217 
218  virtual int get_drive_count();
219  virtual String get_drive(int p_drive);
220 
221  virtual Error change_dir(String p_dir);
222  virtual String get_current_dir();
223 
224 
225  virtual bool file_exists(String p_file);
226  virtual bool dir_exists(String p_dir);
227 
228  virtual Error make_dir(String p_dir);
229 
230  virtual Error rename(String p_from, String p_to);
231  virtual Error remove(String p_name);
232 
233  size_t get_space_left();
234 
235  DirAccessPack();
236  ~DirAccessPack();
237 
238 };
239 
240 
241 #endif // FILE_ACCESS_PACK_H
Definition: file_access_pack.h:46
Definition: file_access_pack.h:119
Definition: file_access_pack.h:40
Definition: map.h:50
Definition: file_access_pack.h:128
Definition: file_access_pack.h:201
Definition: ustring.h:64
Definition: file_access_pack.h:137
Definition: file_access.h:40
Definition: dir_access.h:41