diff --git a/panda/src/downloader/downloadDb.cxx b/panda/src/downloader/downloadDb.cxx index c00493cd0b..61331c2b75 100644 --- a/panda/src/downloader/downloadDb.cxx +++ b/panda/src/downloader/downloadDb.cxx @@ -13,8 +13,16 @@ //////////////////////////////////////////////////////////////////// // Defines //////////////////////////////////////////////////////////////////// + +// Written at the top of the file so we know this is a downloadDb PN_uint32 DownloadDb::_magic_number = 0xfeedfeed; +// Written at the top of the file to signify we are not done +// writing to the file yet. If you load a db with this magic +// number that means the previous time it got written out was +// probably interrupted in the middle of the write. +PN_uint32 DownloadDb::_bogus_magic_number = 0x11111111; + //////////////////////////////////////////////////////////////////// // Function: DownloadDb::Constructor // Access: Public @@ -62,7 +70,7 @@ output(ostream &out) const { _client_db.output(out); out << endl; out << "============================================================" << endl; - out << " Server DB file: " << _server_db._filename << endl; + out << " Server DB file: " << endl; out << "============================================================" << endl; _server_db.output(out); output_version_map(out); @@ -235,6 +243,7 @@ read_db(Ramfile &file, bool want_server_info) { return db; } + //////////////////////////////////////////////////////////////////// // Function: DownloadDb:: // Access: Public @@ -254,10 +263,14 @@ write_db(Filename &file, Db db, bool want_server_info) { downloader_cat.debug() << "Writing to file: " << file << endl; + // Initialize the write stream with a bogus header + db.write_bogus_header(write_stream); db.write(write_stream, want_server_info); if (want_server_info) { write_version_map(write_stream); } + // Now write the real header + db.write_header(write_stream); write_stream.close(); return true; } @@ -554,7 +567,18 @@ parse_header(uchar *start, int size) { PN_uint32 magic_number = di.get_uint32(); downloader_cat.debug() << "Parsed magic number: " << magic_number << endl; - if (magic_number != _magic_number) { + // If the magic number is equal to the bogus magic number + // it signifies that the previous write was interrupted + if (magic_number == _bogus_magic_number) { + downloader_cat.error() + << "DownloadDb::parse_header() - " + << "Bogus magic number, previous write incomplete: " + << magic_number << " expected: " << _magic_number << endl; + return -1; + } + // If the magic number does not match at all, something is + // really wrong + else if (magic_number != _magic_number) { downloader_cat.error() << "DownloadDb::parse_header() - Invalid magic number: " << magic_number << " expected: " << _magic_number << endl; @@ -754,8 +778,6 @@ read(istream &read_stream, bool want_server_info) { //////////////////////////////////////////////////////////////////// bool DownloadDb::Db:: write(ofstream &write_stream, bool want_server_info) { - write_header(write_stream); - // Declare these outside the loop so we do not keep creating // and deleting them PN_int32 phase; @@ -838,10 +860,28 @@ write(ofstream &write_stream, bool want_server_info) { return true; } +//////////////////////////////////////////////////////////////////// +// Function: DownloadDb::Db::write_bogus_header +// Access: Private +// Description: Writes the bogus header uncompressed with platform- +// independent byte ordering. This header will get +// overwritten with the real magic number as the last +// step in the write +//////////////////////////////////////////////////////////////////// +bool DownloadDb::Db:: +write_bogus_header(ofstream &write_stream) { + _datagram.clear(); + // Write the db magic number + _datagram.add_uint32(_bogus_magic_number); + // Write the number of multifiles + _datagram.add_int32(get_num_multifiles()); - + string msg = _datagram.get_message(); + write_stream.write(msg.data(), msg.length()); + return true; +} //////////////////////////////////////////////////////////////////// // Function: DownloadDb::Db::write_header @@ -860,11 +900,15 @@ write_header(ofstream &write_stream) { _datagram.add_int32(get_num_multifiles()); string msg = _datagram.get_message(); + // Seek back to the beginning of the write stream + write_stream.seekp(0); + // Overwrite the old bogus header with the real header write_stream.write(msg.data(), msg.length()); return true; } + //////////////////////////////////////////////////////////////////// // FileRecord methods //////////////////////////////////////////////////////////////////// diff --git a/panda/src/downloader/downloadDb.h b/panda/src/downloader/downloadDb.h index 62d125c449..887c81e765 100644 --- a/panda/src/downloader/downloadDb.h +++ b/panda/src/downloader/downloadDb.h @@ -161,13 +161,14 @@ public: bool write(ofstream &write_stream, bool want_server_info); Filename _filename; MultifileRecords _mfile_records; + bool write_header(ofstream &write_stream); + bool write_bogus_header(ofstream &write_stream); private: PN_int32 _header_length; // Datagram used for reading and writing to disk Datagram _datagram; - bool write_header(ofstream &write_stream); }; PUBLISHED: @@ -183,6 +184,7 @@ public: // Magic number for knowing this is a download Db static PN_uint32 _magic_number; + static PN_uint32 _bogus_magic_number; typedef vector vectorHash; typedef map VersionMap; diff --git a/panda/src/downloader/downloader.cxx b/panda/src/downloader/downloader.cxx index fb1502282a..c759b167a0 100644 --- a/panda/src/downloader/downloader.cxx +++ b/panda/src/downloader/downloader.cxx @@ -883,9 +883,6 @@ write_to_disk(DownloadStatus *status) { // Ensure the header has been parsed successfully first int parse_ret = parse_header(status); - if (parse_ret < 0) - return parse_ret; - if (status->_header_is_complete == false) { downloader_cat.error() << "Downloader::write_to_disk() - Incomplete HTTP header - " @@ -894,6 +891,9 @@ write_to_disk(DownloadStatus *status) { return EU_error_abort; } + if (parse_ret < 0) + return parse_ret; + // Write what we have so far to disk if (status->_bytes_in_buffer > 0) { if (downloader_cat.is_debug()) @@ -924,8 +924,6 @@ write_to_ram(DownloadStatus *status) { // Ensure the header has been parsed successfully first int parse_ret = parse_header(status); - if (parse_ret < 0) - return parse_ret; if (status->_header_is_complete == false) { downloader_cat.error() @@ -935,6 +933,10 @@ write_to_ram(DownloadStatus *status) { return EU_error_abort; } + if (parse_ret < 0) + return parse_ret; + + // Write what we have so far to memory if (status->_bytes_in_buffer > 0) { if (downloader_cat.is_debug())