00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef MULTIFILE_H
00020 #define MULTIFILE_H
00021
00022 #include "pandabase.h"
00023
00024 #include "subStream.h"
00025 #include "filename.h"
00026 #include "ordered_vector.h"
00027 #include "indirectLess.h"
00028 #include "pvector.h"
00029
00030
00031
00032
00033
00034 class EXPCL_PANDAEXPRESS Multifile {
00035 PUBLISHED:
00036 Multifile();
00037 ~Multifile();
00038
00039 private:
00040 Multifile(const Multifile ©);
00041 void operator = (const Multifile ©);
00042
00043 PUBLISHED:
00044 bool open_read(const Filename &multifile_name);
00045 bool open_write(const Filename &multifile_name);
00046 bool open_read_write(const Filename &multifile_name);
00047 void close();
00048
00049 INLINE const Filename &get_multifile_name() const;
00050
00051 INLINE bool is_read_valid() const;
00052 INLINE bool is_write_valid() const;
00053 INLINE bool needs_repack() const;
00054
00055 void set_scale_factor(size_t scale_factor);
00056 INLINE size_t get_scale_factor() const;
00057
00058 string add_subfile(const string &subfile_name, const Filename &filename,
00059 int compression_level);
00060 bool flush();
00061 bool repack();
00062
00063 int get_num_subfiles() const;
00064 int find_subfile(const string &subfile_name) const;
00065 bool has_directory(const string &subfile_name) const;
00066 bool scan_directory(vector_string &contents,
00067 const string &subfile_name) const;
00068 void remove_subfile(int index);
00069 const string &get_subfile_name(int index) const;
00070 size_t get_subfile_length(int index) const;
00071 bool is_subfile_compressed(int index) const;
00072 size_t get_subfile_compressed_length(int index) const;
00073
00074 INLINE string read_subfile(int index);
00075 istream *open_read_subfile(int index);
00076 bool extract_subfile(int index, const Filename &filename);
00077
00078 void output(ostream &out) const;
00079 void ls(ostream &out = cout) const;
00080
00081 public:
00082 bool read_subfile(int index, string &result);
00083
00084
00085 bool open_read(istream *multifile_stream);
00086 bool open_write(ostream *multifile_stream);
00087 bool open_read_write(iostream *multifile_stream);
00088 string add_subfile(const string &subfile_name, istream *subfile_data,
00089 int compression_level);
00090
00091 bool extract_subfile_to(int index, ostream &out);
00092
00093 private:
00094 enum SubfileFlags {
00095 SF_deleted = 0x0001,
00096 SF_index_invalid = 0x0002,
00097 SF_data_invalid = 0x0004,
00098 SF_compressed = 0x0008,
00099 };
00100
00101 class Subfile {
00102 public:
00103 INLINE Subfile();
00104 INLINE bool operator < (const Subfile &other) const;
00105 streampos read_index(istream &read, streampos fpos,
00106 Multifile *multfile);
00107 streampos write_index(ostream &write, streampos fpos,
00108 Multifile *multifile);
00109 streampos write_data(ostream &write, istream *read, streampos fpos);
00110 void rewrite_index_data_start(ostream &write, Multifile *multifile);
00111 void rewrite_index_flags(ostream &write);
00112 INLINE bool is_deleted() const;
00113 INLINE bool is_index_invalid() const;
00114 INLINE bool is_data_invalid() const;
00115
00116 string _name;
00117 streampos _index_start;
00118 streampos _data_start;
00119 size_t _data_length;
00120 size_t _uncompressed_length;
00121 istream *_source;
00122 Filename _source_filename;
00123 int _flags;
00124 int _compression_level;
00125 };
00126
00127 INLINE streampos word_to_streampos(size_t word) const;
00128 INLINE size_t streampos_to_word(streampos fpos) const;
00129 INLINE streampos normalize_streampos(streampos fpos) const;
00130 streampos pad_to_streampos(streampos fpos);
00131
00132 string add_new_subfile(const string &subfile_name, Subfile *subfile,
00133 int compression_level);
00134 void clear_subfiles();
00135 bool read_index();
00136 bool write_header();
00137
00138
00139 typedef ov_set<Subfile *, IndirectLess<Subfile> > Subfiles;
00140 Subfiles _subfiles;
00141 typedef pvector<Subfile *> PendingSubfiles;
00142 PendingSubfiles _new_subfiles;
00143 PendingSubfiles _removed_subfiles;
00144
00145 istream *_read;
00146 ostream *_write;
00147 streampos _next_index;
00148 streampos _last_index;
00149
00150 bool _needs_repack;
00151 size_t _scale_factor;
00152 size_t _new_scale_factor;
00153
00154 ifstream _read_file;
00155 ofstream _write_file;
00156 fstream _read_write_file;
00157 Filename _multifile_name;
00158
00159 int _file_major_ver;
00160 int _file_minor_ver;
00161
00162 static const char _header[];
00163 static const size_t _header_size;
00164 static const int _current_major_ver;
00165 static const int _current_minor_ver;
00166
00167 friend class Subfile;
00168 };
00169
00170 #include "multifile.I"
00171
00172 #endif