add file timestamps
This commit is contained in:
parent
cb8e25f859
commit
87a912818b
|
|
@ -1166,6 +1166,41 @@ compare_timestamps(const Filename &other,
|
|||
return other_missing_is_old ? 1 : -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::get_timestamp
|
||||
// Access: Published
|
||||
// Description: Returns a time_t value that represents the time the
|
||||
// file was last modified, to within whatever precision
|
||||
// the operating system records this information (on a
|
||||
// Windows95 system, for instance, this may only be
|
||||
// accurate to within 2 seconds).
|
||||
//
|
||||
// If the timestamp cannot be determined, either because
|
||||
// it is not supported by the operating system or
|
||||
// because there is some error (such as file not found),
|
||||
// returns 0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
time_t Filename::
|
||||
get_timestamp() const {
|
||||
string os_specific = get_filename_index(0).to_os_specific();
|
||||
|
||||
#ifdef WIN32_VC
|
||||
struct _stat this_buf;
|
||||
|
||||
if (_stat(os_specific.c_str(), &this_buf) == 0) {
|
||||
return this_buf.st_mtime;
|
||||
}
|
||||
#else // WIN32_VC
|
||||
struct stat this_buf;
|
||||
|
||||
if (stat(os_specific.c_str(), &this_buf) == 0) {
|
||||
return this_buf.st_mtime;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::resolve_filename
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -159,6 +159,8 @@ PUBLISHED:
|
|||
int compare_timestamps(const Filename &other,
|
||||
bool this_missing_is_old = true,
|
||||
bool other_missing_is_old = true) const;
|
||||
time_t get_timestamp() const;
|
||||
|
||||
bool resolve_filename(const DSearchPath &searchpath,
|
||||
const string &default_extension = string());
|
||||
bool make_relative_to(Filename directory, bool allow_backups = true);
|
||||
|
|
|
|||
|
|
@ -388,6 +388,31 @@ extract_files(int argc, char *argv[]) {
|
|||
return true;
|
||||
}
|
||||
|
||||
const char *
|
||||
format_timestamp(time_t timestamp) {
|
||||
static const size_t buffer_size = 512;
|
||||
static char buffer[buffer_size];
|
||||
|
||||
if (timestamp == 0) {
|
||||
// A zero timestamp is a special case.
|
||||
return " (no date) ";
|
||||
}
|
||||
|
||||
time_t now = time(NULL);
|
||||
struct tm *tm_p = localtime(×tamp);
|
||||
|
||||
if (timestamp > now || (now - timestamp > 86400 * 365)) {
|
||||
// A timestamp in the future, or more than a year in the past,
|
||||
// gets a year appended.
|
||||
strftime(buffer, buffer_size, "%b %d %Y", tm_p);
|
||||
} else {
|
||||
// Otherwise, within the past year, show the date and time.
|
||||
strftime(buffer, buffer_size, "%b %d %H:%M", tm_p);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
bool
|
||||
list_files(int argc, char *argv[]) {
|
||||
if (!multifile_name.exists()) {
|
||||
|
|
@ -419,23 +444,28 @@ list_files(int argc, char *argv[]) {
|
|||
ratio = (double)internal_length / (double)orig_length;
|
||||
}
|
||||
if (ratio > 1.0) {
|
||||
printf("%12d worse %c %s\n",
|
||||
printf("%12d worse %c %s %s\n",
|
||||
multifile->get_subfile_length(i),
|
||||
encrypted_symbol,
|
||||
format_timestamp(multifile->get_subfile_timestamp(i)),
|
||||
subfile_name.c_str());
|
||||
} else {
|
||||
printf("%12d %3.0f%% %c %s\n",
|
||||
printf("%12d %3.0f%% %c %s %s\n",
|
||||
multifile->get_subfile_length(i),
|
||||
100.0 - ratio * 100.0, encrypted_symbol,
|
||||
format_timestamp(multifile->get_subfile_timestamp(i)),
|
||||
subfile_name.c_str());
|
||||
}
|
||||
} else {
|
||||
printf("%12d %c %s\n",
|
||||
printf("%12d %c %s %s\n",
|
||||
multifile->get_subfile_length(i),
|
||||
encrypted_symbol, subfile_name.c_str());
|
||||
encrypted_symbol,
|
||||
format_timestamp(multifile->get_subfile_timestamp(i)),
|
||||
subfile_name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
cout << "Last modification " << format_timestamp(multifile->get_timestamp()) << "\n";
|
||||
fflush(stdout);
|
||||
if (multifile->get_scale_factor() != 1) {
|
||||
cout << "Scale factor is " << multifile->get_scale_factor() << "\n";
|
||||
|
|
|
|||
|
|
@ -63,6 +63,21 @@ needs_repack() const {
|
|||
return _needs_repack || (_scale_factor != _new_scale_factor);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Multifile::get_timestamp
|
||||
// Access: Published
|
||||
// Description: Returns the modification timestamp of the overall
|
||||
// Multifile. This indicates the most recent date at
|
||||
// which subfiles were added or removed from the
|
||||
// Multifile. Note that it is logically possible for an
|
||||
// individual subfile to have a more recent timestamp
|
||||
// than the overall timestamp.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE time_t Multifile::
|
||||
get_timestamp() const {
|
||||
return _timestamp;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Multifile::get_scale_factor
|
||||
// Access: Published
|
||||
|
|
@ -197,6 +212,7 @@ Subfile() {
|
|||
_index_start = 0;
|
||||
_data_start = 0;
|
||||
_data_length = 0;
|
||||
_timestamp = 0;
|
||||
_source = (istream *)NULL;
|
||||
_flags = 0;
|
||||
_compression_level = 0;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,9 @@ const size_t Multifile::_header_size = 6;
|
|||
// change in the major version is intolerable; while a Multifile with
|
||||
// an older minor version may still be read.
|
||||
const int Multifile::_current_major_ver = 1;
|
||||
const int Multifile::_current_minor_ver = 0;
|
||||
|
||||
const int Multifile::_current_minor_ver = 1;
|
||||
// Bumped to version 1.1 on 6/8/06 to add timestamps.
|
||||
|
||||
// To confirm that the supplied password matches, we write the
|
||||
// Mutifile magic header at the beginning of the encrypted stream.
|
||||
|
|
@ -63,6 +65,7 @@ const size_t Multifile::_encrypt_header_size = 6;
|
|||
// uint32 Scale factor. This scales all address references within
|
||||
// the file. Normally 1, this may be set larger to
|
||||
// support Multifiles larger than 4GB.
|
||||
// uint32 An overall modification timestamp for the entire multifile.
|
||||
|
||||
//
|
||||
// (2) Zero or more index entries, one for each subfile within the
|
||||
|
|
@ -82,6 +85,7 @@ const size_t Multifile::_encrypt_header_size = 6;
|
|||
// subfile, if it is compressed or encrypted. This field
|
||||
// is only present if one or both of the SF_compressed
|
||||
// or SF_encrypted bits are set in _flags.
|
||||
// uint32 A modification timestamp for the subfile.
|
||||
// uint16 The length in bytes of the subfile's name.
|
||||
// char[n] The subfile's name.
|
||||
//
|
||||
|
|
@ -105,6 +109,8 @@ Multifile() {
|
|||
_next_index = 0;
|
||||
_last_index = 0;
|
||||
_needs_repack = false;
|
||||
_timestamp = 0;
|
||||
_timestamp_dirty = false;
|
||||
_scale_factor = 1;
|
||||
_new_scale_factor = 1;
|
||||
_encryption_flag = false;
|
||||
|
|
@ -162,6 +168,8 @@ open_read(const Filename &multifile_name) {
|
|||
if (!fname.open_read(_read_file)) {
|
||||
return false;
|
||||
}
|
||||
_timestamp = fname.get_timestamp();
|
||||
_timestamp_dirty = true;
|
||||
_read = &_read_file;
|
||||
_multifile_name = multifile_name;
|
||||
return read_index();
|
||||
|
|
@ -188,6 +196,8 @@ open_write(const Filename &multifile_name) {
|
|||
if (!fname.open_write(_write_file, true)) {
|
||||
return false;
|
||||
}
|
||||
_timestamp = time(NULL);
|
||||
_timestamp_dirty = true;
|
||||
_write = &_write_file;
|
||||
_multifile_name = multifile_name;
|
||||
return true;
|
||||
|
|
@ -215,6 +225,12 @@ open_read_write(const Filename &multifile_name) {
|
|||
if (!fname.open_read_write(_read_write_file)) {
|
||||
return false;
|
||||
}
|
||||
if (exists) {
|
||||
_timestamp = fname.get_timestamp();
|
||||
} else {
|
||||
_timestamp = time(NULL);
|
||||
}
|
||||
_timestamp_dirty = true;
|
||||
_read = &_read_write_file;
|
||||
_write = &_read_write_file;
|
||||
_multifile_name = multifile_name;
|
||||
|
|
@ -248,8 +264,11 @@ close() {
|
|||
_next_index = 0;
|
||||
_last_index = 0;
|
||||
_needs_repack = false;
|
||||
_timestamp = 0;
|
||||
_timestamp_dirty = false;
|
||||
_scale_factor = 1;
|
||||
_new_scale_factor = 1;
|
||||
_encryption_flag = false;
|
||||
_file_major_ver = 0;
|
||||
_file_minor_ver = 0;
|
||||
|
||||
|
|
@ -335,6 +354,9 @@ add_subfile(const string &subfile_name, const Filename &filename,
|
|||
add_new_subfile(subfile, compression_level);
|
||||
}
|
||||
|
||||
_timestamp = time(NULL);
|
||||
_timestamp_dirty = true;
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
|
@ -343,9 +365,9 @@ add_subfile(const string &subfile_name, const Filename &filename,
|
|||
// Access: Published
|
||||
// Description: Adds a file on disk to the subfile. If a subfile
|
||||
// already exists with the same name, its contents are
|
||||
// compared to the disk file, and it is replaced only if
|
||||
// it is different; otherwise, the multifile is left
|
||||
// unchanged.
|
||||
// compared byte-for-byte to the disk file, and it is
|
||||
// replaced only if it is different; otherwise, the
|
||||
// multifile is left unchanged.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string Multifile::
|
||||
update_subfile(const string &subfile_name, const Filename &filename,
|
||||
|
|
@ -376,6 +398,9 @@ update_subfile(const string &subfile_name, const Filename &filename,
|
|||
add_new_subfile(subfile, compression_level);
|
||||
}
|
||||
|
||||
_timestamp = time(NULL);
|
||||
_timestamp_dirty = true;
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
|
@ -412,6 +437,13 @@ flush() {
|
|||
if (!write_header()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (_file_minor_ver != _current_minor_ver) {
|
||||
// If we *do* have an index already, but this is an old version
|
||||
// multifile, we have to completely rewrite it anyway.
|
||||
return repack();
|
||||
}
|
||||
}
|
||||
|
||||
nassertr(_write != (ostream *)NULL, false);
|
||||
|
|
@ -484,8 +516,8 @@ flush() {
|
|||
|
||||
// Now go back and fill in the proper addresses for the data start.
|
||||
// We didn't do it in the first pass, because we don't really want
|
||||
// to keep all those pile handles open, and so we didn't have to
|
||||
// determine each pile's length ahead of time.
|
||||
// to keep all those file handles open, and so we didn't have to
|
||||
// determine each file's length ahead of time.
|
||||
for (pi = _new_subfiles.begin(); pi != _new_subfiles.end(); ++pi) {
|
||||
Subfile *subfile = (*pi);
|
||||
subfile->rewrite_index_data_start(*_write, this);
|
||||
|
|
@ -494,6 +526,18 @@ flush() {
|
|||
_new_subfiles.clear();
|
||||
}
|
||||
|
||||
// Also update the overall timestamp.
|
||||
if (_timestamp_dirty) {
|
||||
nassertr(!_write->fail(), false);
|
||||
static const size_t timestamp_pos = _header_size + 2 + 2 + 4;
|
||||
_write->seekp(timestamp_pos);
|
||||
nassertr(!_write->fail(), false);
|
||||
|
||||
StreamWriter writer(*_write);
|
||||
writer.add_uint32(_timestamp);
|
||||
_timestamp_dirty = false;
|
||||
}
|
||||
|
||||
_write->flush();
|
||||
if (!wrote_ok || _write->fail()) {
|
||||
express_cat.info()
|
||||
|
|
@ -725,6 +769,9 @@ remove_subfile(int index) {
|
|||
_removed_subfiles.push_back(subfile);
|
||||
_subfiles.erase(_subfiles.begin() + index);
|
||||
|
||||
_timestamp = time(NULL);
|
||||
_timestamp_dirty = true;
|
||||
|
||||
_needs_repack = true;
|
||||
}
|
||||
|
||||
|
|
@ -756,6 +803,21 @@ get_subfile_length(int index) const {
|
|||
return _subfiles[index]->_uncompressed_length;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Multifile::get_subfile_timestamp
|
||||
// Access: Published
|
||||
// Description: Returns the modification time of the nth
|
||||
// subfile. If this is called on an older .mf file,
|
||||
// which did not store individual timestamps in the
|
||||
// file, this will return the modification time of the
|
||||
// overall multifile.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
time_t Multifile::
|
||||
get_subfile_timestamp(int index) const {
|
||||
nassertr(index >= 0 && index < (int)_subfiles.size(), 0);
|
||||
return _subfiles[index]->_timestamp;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Multifile::is_subfile_compressed
|
||||
// Access: Published
|
||||
|
|
@ -951,6 +1013,18 @@ compare_subfile(int index, const Filename &filename) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Check the file size.
|
||||
in2.seekg(0, ios::end);
|
||||
streampos file_size = in2.tellg();
|
||||
|
||||
if (file_size != (streampos)get_subfile_length(index)) {
|
||||
// The files have different sizes.
|
||||
delete in1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the file data, byte-for-byte.
|
||||
in2.seekg(0);
|
||||
int byte1 = in1->get();
|
||||
int byte2 = in2.get();
|
||||
while (!in1->fail() && !in1->eof() &&
|
||||
|
|
@ -967,6 +1041,7 @@ compare_subfile(int index, const Filename &filename) {
|
|||
delete in1;
|
||||
|
||||
nassertr(!failed, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1036,6 +1111,8 @@ read_subfile(int index, string &result) {
|
|||
bool Multifile::
|
||||
open_read(istream *multifile_stream) {
|
||||
close();
|
||||
_timestamp = time(NULL);
|
||||
_timestamp_dirty = true;
|
||||
_read = multifile_stream;
|
||||
return read_index();
|
||||
}
|
||||
|
|
@ -1053,6 +1130,8 @@ open_read(istream *multifile_stream) {
|
|||
bool Multifile::
|
||||
open_write(ostream *multifile_stream) {
|
||||
close();
|
||||
_timestamp = time(NULL);
|
||||
_timestamp_dirty = true;
|
||||
_write = multifile_stream;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1071,6 +1150,8 @@ open_write(ostream *multifile_stream) {
|
|||
bool Multifile::
|
||||
open_read_write(iostream *multifile_stream) {
|
||||
close();
|
||||
_timestamp = time(NULL);
|
||||
_timestamp_dirty = true;
|
||||
_read = multifile_stream;
|
||||
_write = multifile_stream;
|
||||
|
||||
|
|
@ -1303,6 +1384,10 @@ read_index() {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (_file_minor_ver >= 1) {
|
||||
_timestamp = reader.get_uint32();
|
||||
_timestamp_dirty = false;
|
||||
}
|
||||
|
||||
// Now read the index out.
|
||||
_next_index = _read->tellg();
|
||||
|
|
@ -1360,6 +1445,9 @@ read_index() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool Multifile::
|
||||
write_header() {
|
||||
_file_major_ver = _current_major_ver;
|
||||
_file_minor_ver = _current_minor_ver;
|
||||
|
||||
nassertr(_write != (ostream *)NULL, false);
|
||||
nassertr(_write->tellp() == (streampos)0, false);
|
||||
_write->write(_header, _header_size);
|
||||
|
|
@ -1368,6 +1456,8 @@ write_header() {
|
|||
writer.add_int16(_current_minor_ver);
|
||||
writer.add_uint32(_scale_factor);
|
||||
|
||||
writer.add_uint32(_timestamp);
|
||||
|
||||
_next_index = _write->tellp();
|
||||
_next_index = pad_to_streampos(_next_index);
|
||||
_last_index = 0;
|
||||
|
|
@ -1421,6 +1511,12 @@ read_index(istream &read, streampos fpos, Multifile *multifile) {
|
|||
} else {
|
||||
_uncompressed_length = _data_length;
|
||||
}
|
||||
if (multifile->_file_minor_ver < 1) {
|
||||
_timestamp = multifile->get_timestamp();
|
||||
} else {
|
||||
_timestamp = reader.get_uint32();
|
||||
}
|
||||
|
||||
size_t name_length = reader.get_uint16();
|
||||
if (read.eof() || read.fail()) {
|
||||
_flags |= SF_index_invalid;
|
||||
|
|
@ -1471,6 +1567,7 @@ write_index(ostream &write, streampos fpos, Multifile *multifile) {
|
|||
if ((_flags & (SF_compressed | SF_encrypted)) != 0) {
|
||||
dg.add_uint32(_uncompressed_length);
|
||||
}
|
||||
dg.add_uint32(_timestamp);
|
||||
dg.add_uint16(_name.length());
|
||||
|
||||
// For no real good reason, we'll invert all the bits in the name.
|
||||
|
|
@ -1497,7 +1594,7 @@ write_index(ostream &write, streampos fpos, Multifile *multifile) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Multifile::Subfile::write_index
|
||||
// Function: Multifile::Subfile::write_data
|
||||
// Access: Public
|
||||
// Description: Writes the data record for the Subfile to the
|
||||
// indicated ostream: the actual contents of the
|
||||
|
|
@ -1621,6 +1718,16 @@ write_data(ostream &write, istream *read, streampos fpos,
|
|||
// Subfile. (In case we are running during repack()).
|
||||
_data_start = fpos;
|
||||
|
||||
// Get the modification timestamp for this subfile. This is read
|
||||
// from the source file, if we have a filename; otherwise, it's the
|
||||
// current time.
|
||||
if (!_source_filename.empty()) {
|
||||
_timestamp = _source_filename.get_timestamp();
|
||||
}
|
||||
if (_timestamp == 0) {
|
||||
_timestamp = time(NULL);
|
||||
}
|
||||
|
||||
_source = (istream *)NULL;
|
||||
_source_filename = Filename();
|
||||
source_file.close();
|
||||
|
|
@ -1651,6 +1758,7 @@ rewrite_index_data_start(ostream &write, Multifile *multifile) {
|
|||
if ((_flags & (SF_compressed | SF_encrypted)) != 0) {
|
||||
writer.add_uint32(_uncompressed_length);
|
||||
}
|
||||
writer.add_uint32(_timestamp);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ PUBLISHED:
|
|||
INLINE bool is_write_valid() const;
|
||||
INLINE bool needs_repack() const;
|
||||
|
||||
INLINE time_t get_timestamp() const;
|
||||
|
||||
void set_scale_factor(size_t scale_factor);
|
||||
INLINE size_t get_scale_factor() const;
|
||||
|
||||
|
|
@ -77,6 +79,7 @@ PUBLISHED:
|
|||
void remove_subfile(int index);
|
||||
const string &get_subfile_name(int index) const;
|
||||
size_t get_subfile_length(int index) const;
|
||||
time_t get_subfile_timestamp(int index) const;
|
||||
bool is_subfile_compressed(int index) const;
|
||||
bool is_subfile_encrypted(int index) const;
|
||||
size_t get_subfile_internal_length(int index) const;
|
||||
|
|
@ -131,6 +134,7 @@ private:
|
|||
streampos _data_start;
|
||||
size_t _data_length;
|
||||
size_t _uncompressed_length;
|
||||
time_t _timestamp;
|
||||
istream *_source;
|
||||
Filename _source_filename;
|
||||
int _flags;
|
||||
|
|
@ -162,6 +166,8 @@ private:
|
|||
streampos _last_index;
|
||||
|
||||
bool _needs_repack;
|
||||
time_t _timestamp;
|
||||
bool _timestamp_dirty;
|
||||
size_t _scale_factor;
|
||||
size_t _new_scale_factor;
|
||||
|
||||
|
|
|
|||
|
|
@ -177,6 +177,25 @@ get_file_size(istream *stream) const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VirtualFile::get_timestamp
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns a time_t value that represents the time the
|
||||
// file was last modified, to within whatever precision
|
||||
// the operating system records this information (on a
|
||||
// Windows95 system, for instance, this may only be
|
||||
// accurate to within 2 seconds).
|
||||
//
|
||||
// If the timestamp cannot be determined, either because
|
||||
// it is not supported by the operating system or
|
||||
// because there is some error (such as file not found),
|
||||
// returns 0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
time_t VirtualFile::
|
||||
get_timestamp() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VirtualFile::close_read_file
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ PUBLISHED:
|
|||
virtual istream *open_read_file(bool auto_unwrap) const;
|
||||
void close_read_file(istream *stream) const;
|
||||
virtual streampos get_file_size(istream *stream) const;
|
||||
virtual time_t get_timestamp() const;
|
||||
|
||||
public:
|
||||
INLINE void set_original_filename(const Filename &filename);
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ public:
|
|||
virtual istream *open_read_file(const Filename &file) const=0;
|
||||
void close_read_file(istream *stream) const;
|
||||
virtual streampos get_file_size(const Filename &file, istream *stream) const=0;
|
||||
virtual time_t get_timestamp(const Filename &file) const=0;
|
||||
|
||||
virtual bool scan_directory(vector_string &contents,
|
||||
const Filename &dir) const=0;
|
||||
|
|
|
|||
|
|
@ -102,6 +102,29 @@ get_file_size(const Filename &file, istream *) const {
|
|||
return _multifile->get_subfile_length(subfile_index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VirtualFileMountMultifile::get_timestamp
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns a time_t value that represents the time the
|
||||
// file was last modified, to within whatever precision
|
||||
// the operating system records this information (on a
|
||||
// Windows95 system, for instance, this may only be
|
||||
// accurate to within 2 seconds).
|
||||
//
|
||||
// If the timestamp cannot be determined, either because
|
||||
// it is not supported by the operating system or
|
||||
// because there is some error (such as file not found),
|
||||
// returns 0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
time_t VirtualFileMountMultifile::
|
||||
get_timestamp(const Filename &file) const {
|
||||
int subfile_index = _multifile->find_subfile(file);
|
||||
if (subfile_index < 0) {
|
||||
return 0;
|
||||
}
|
||||
return _multifile->get_subfile_timestamp(subfile_index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VirtualFileMountMultifile::scan_directory
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ public:
|
|||
|
||||
virtual istream *open_read_file(const Filename &file) const;
|
||||
virtual streampos get_file_size(const Filename &file, istream *stream) const;
|
||||
virtual time_t get_timestamp(const Filename &file) const;
|
||||
|
||||
virtual bool scan_directory(vector_string &contents,
|
||||
const Filename &dir) const;
|
||||
|
|
|
|||
|
|
@ -141,6 +141,26 @@ get_file_size(const Filename &, istream *stream) const {
|
|||
return size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VirtualFileMountSystem::get_timestamp
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns a time_t value that represents the time the
|
||||
// file was last modified, to within whatever precision
|
||||
// the operating system records this information (on a
|
||||
// Windows95 system, for instance, this may only be
|
||||
// accurate to within 2 seconds).
|
||||
//
|
||||
// If the timestamp cannot be determined, either because
|
||||
// it is not supported by the operating system or
|
||||
// because there is some error (such as file not found),
|
||||
// returns 0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
time_t VirtualFileMountSystem::
|
||||
get_timestamp(const Filename &file) const {
|
||||
Filename pathname(_physical_filename, file);
|
||||
return pathname.get_timestamp();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VirtualFileMountSystem::scan_directory
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ public:
|
|||
|
||||
virtual istream *open_read_file(const Filename &file) const;
|
||||
virtual streampos get_file_size(const Filename &file, istream *stream) const;
|
||||
virtual time_t get_timestamp(const Filename &file) const;
|
||||
|
||||
virtual bool scan_directory(vector_string &contents,
|
||||
const Filename &dir) const;
|
||||
|
|
|
|||
|
|
@ -124,6 +124,25 @@ get_file_size(istream *stream) const {
|
|||
return _mount->get_file_size(_local_filename, stream);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VirtualFileSimple::get_timestamp
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns a time_t value that represents the time the
|
||||
// file was last modified, to within whatever precision
|
||||
// the operating system records this information (on a
|
||||
// Windows95 system, for instance, this may only be
|
||||
// accurate to within 2 seconds).
|
||||
//
|
||||
// If the timestamp cannot be determined, either because
|
||||
// it is not supported by the operating system or
|
||||
// because there is some error (such as file not found),
|
||||
// returns 0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
time_t VirtualFileSimple::
|
||||
get_timestamp() const {
|
||||
return _mount->get_timestamp(_local_filename);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VirtualFileSimple::scan_local_directory
|
||||
// Access: Protected, Virtual
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ public:
|
|||
|
||||
virtual istream *open_read_file(bool auto_unwrap) const;
|
||||
virtual streampos get_file_size(istream *stream) const;
|
||||
virtual time_t get_timestamp() const;
|
||||
|
||||
protected:
|
||||
virtual bool scan_local_directory(VirtualFileList *file_list,
|
||||
|
|
|
|||
Loading…
Reference in New Issue