Panda3D
|
00001 // Filename: downloadDb.h 00002 // Created by: shochet (06Sep00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 #ifndef DOWNLOADDB_H 00015 #define DOWNLOADDB_H 00016 00017 #include "pandabase.h" 00018 #include "pnotify.h" 00019 #include "filename.h" 00020 #include "multifile.h" 00021 #include "datagram.h" 00022 #include "datagramIterator.h" 00023 00024 #include "pvector.h" 00025 #include "pointerTo.h" 00026 #include "pmap.h" 00027 00028 #include "hashVal.h" 00029 00030 class StreamReader; 00031 class StreamWriter; 00032 typedef PN_stdfloat Phase; 00033 class Ramfile; 00034 00035 /* 00036 ////////////////////////////////////////////////// 00037 // Database Format 00038 ////////////////////////////////////////////////// 00039 magic_number 00040 number_of_multifiles 00041 header_length multifile_name phase version size status num_files 00042 header_length file_name version hash 00043 header_length file_name version hash 00044 header_length multifile_name phase version size status num_files 00045 header_length file_name version hash 00046 header_length file_name version hash 00047 ... 00048 ... 00049 00050 00051 A Db is a Vector<MultifileRecord> 00052 MultifileRecord is a Vector<FileRecord> 00053 */ 00054 00055 00056 //////////////////////////////////////////////////////////////////// 00057 // Class : DownloadDb 00058 // Description : A listing of files within multifiles for management 00059 // of client-side synchronization with a server-provided 00060 // set of files. 00061 // 00062 // This class manages one copy of the database for the 00063 // client, representing the files on the client system, 00064 // and another copy for the server, representing the 00065 // files the server has available. 00066 //////////////////////////////////////////////////////////////////// 00067 class EXPCL_PANDAEXPRESS DownloadDb { 00068 PUBLISHED: 00069 // Status of a multifile is stored in this enum 00070 // Note these values are in increasing order of "doneness" 00071 // So if you are decompressed, you are complete 00072 // If you are extracted, you are decompressed and complete 00073 enum Status { 00074 Status_incomplete = 0, 00075 Status_complete = 1, 00076 Status_decompressed = 2, 00077 Status_extracted = 3 00078 }; 00079 00080 DownloadDb(); 00081 DownloadDb(Ramfile &server_file, Filename &client_file); 00082 DownloadDb(Filename &server_file, Filename &client_file); 00083 ~DownloadDb(); 00084 00085 void output(ostream &out) const; 00086 void write(ostream &out) const; 00087 void write_version_map(ostream &out) const; 00088 00089 // Write a database file 00090 bool write_client_db(Filename &file); 00091 bool write_server_db(Filename &file); 00092 00093 INLINE int get_client_num_multifiles() const; 00094 INLINE int get_server_num_multifiles() const; 00095 00096 INLINE string get_client_multifile_name(int index) const; 00097 INLINE string get_server_multifile_name(int index) const; 00098 00099 INLINE int get_client_multifile_size(string mfname) const; 00100 INLINE void set_client_multifile_size(string mfname, int size); 00101 INLINE int set_client_multifile_delta_size(string mfname, int size); 00102 INLINE int get_server_multifile_size(string mfname) const; 00103 INLINE void set_server_multifile_size(string mfname, int size); 00104 00105 INLINE Phase get_client_multifile_phase(string mfname) const; 00106 INLINE Phase get_server_multifile_phase(string mfname) const; 00107 00108 INLINE void set_client_multifile_incomplete(string mfname); 00109 INLINE void set_client_multifile_complete(string mfname); 00110 INLINE void set_client_multifile_decompressed(string mfname); 00111 INLINE void set_client_multifile_extracted(string mfname); 00112 00113 INLINE int get_server_num_files(string mfname) const; 00114 INLINE string get_server_file_name(string mfname, int index) const; 00115 00116 // Queries from the Launcher 00117 bool client_multifile_exists(string mfname) const; 00118 bool client_multifile_complete(string mfname) const; 00119 bool client_multifile_decompressed(string mfname) const; 00120 bool client_multifile_extracted(string mfname) const; 00121 00122 // Ask what version (told with the hash) this multifile is 00123 HashVal get_client_multifile_hash(string mfname) const; 00124 void set_client_multifile_hash(string mfname, HashVal val); 00125 HashVal get_server_multifile_hash(string mfname) const; 00126 void set_server_multifile_hash(string mfname, HashVal val); 00127 00128 // Operations on multifiles 00129 void delete_client_multifile(string mfname); 00130 void add_client_multifile(string server_mfname); 00131 void expand_client_multifile(string mfname); 00132 00133 // Server side operations to create multifile records 00134 void create_new_server_db(); 00135 void server_add_multifile(string mfname, Phase phase, int size, int status); 00136 void server_add_file(string mfname, string fname); 00137 00138 public: 00139 00140 class EXPCL_PANDAEXPRESS FileRecord : public ReferenceCount { 00141 public: 00142 FileRecord(); 00143 FileRecord(string name); 00144 void write(ostream &out) const; 00145 string _name; 00146 }; 00147 00148 typedef pvector< PT(FileRecord) > FileRecords; 00149 00150 class EXPCL_PANDAEXPRESS MultifileRecord : public ReferenceCount { 00151 public: 00152 MultifileRecord(); 00153 MultifileRecord(string name, Phase phase, int size, int status); 00154 void write(ostream &out) const; 00155 int get_num_files() const; 00156 string get_file_name(int index) const; 00157 bool file_exists(string fname) const; 00158 PT(FileRecord) get_file_record_named(string fname) const; 00159 void add_file_record(PT(FileRecord) fr); 00160 string _name; 00161 Phase _phase; 00162 int _size; 00163 int _status; 00164 HashVal _hash; 00165 PN_int32 _num_files; 00166 FileRecords _file_records; 00167 }; 00168 00169 typedef pvector< PT(MultifileRecord) > MultifileRecords; 00170 00171 class EXPCL_PANDAEXPRESS Db { 00172 public: 00173 Db(); 00174 void write(ostream &out) const; 00175 int get_num_multifiles() const; 00176 string get_multifile_name(int index) const; 00177 bool multifile_exists(string mfname) const; 00178 PT(MultifileRecord) get_multifile_record_named(string mfname) const; 00179 void add_multifile_record(PT(MultifileRecord) mfr); 00180 int parse_header(const string &data); 00181 int parse_record_header(const string &data); 00182 PT(MultifileRecord) parse_mfr(const string &data); 00183 PT(FileRecord) parse_fr(const string &data); 00184 bool read(StreamReader &sr, bool want_server_info); 00185 bool write(StreamWriter &sw, bool want_server_info); 00186 Filename _filename; 00187 MultifileRecords _mfile_records; 00188 bool write_header(ostream &write_stream); 00189 bool write_bogus_header(StreamWriter &sw); 00190 private: 00191 PN_int32 _header_length; 00192 }; 00193 00194 PUBLISHED: 00195 Db read_db(Filename &file, bool want_server_info); 00196 Db read_db(Ramfile &file, bool want_server_info); 00197 bool write_db(Filename &file, Db db, bool want_server_info); 00198 00199 public: 00200 // The download db stores two databases, one that represents the 00201 // client's state and one that represents the server state. 00202 Db _client_db; 00203 Db _server_db; 00204 00205 // Magic number for knowing this is a download Db 00206 static PN_uint32 _magic_number; 00207 static PN_uint32 _bogus_magic_number; 00208 typedef pvector<HashVal> VectorHash; 00209 typedef pmap<Filename, VectorHash> VersionMap; 00210 00211 PUBLISHED: 00212 void add_version(const Filename &name, const HashVal &hash, int version); 00213 void insert_new_version(const Filename &name, const HashVal &hash); 00214 bool has_version(const Filename &name) const; 00215 int get_num_versions(const Filename &name) const; 00216 void set_num_versions(const Filename &name, int num_versions); 00217 00218 int get_version(const Filename &name, const HashVal &hash) const; 00219 const HashVal &get_hash(const Filename &name, int version) const; 00220 00221 protected: 00222 void write_version_map(StreamWriter &sw); 00223 bool read_version_map(StreamReader &sr); 00224 VersionMap _versions; 00225 }; 00226 00227 INLINE ostream &operator << (ostream &out, const DownloadDb &dldb) { 00228 dldb.output(out); 00229 return out; 00230 } 00231 00232 00233 #include "downloadDb.I" 00234 00235 #endif