diff --git dataobj/loadsave.cc dataobj/loadsave.cc index cf3d4eb48..4911d757d 100644 --- dataobj/loadsave.cc +++ dataobj/loadsave.cc @@ -326,7 +326,7 @@ bool loadsave_t::rd_open(const char *filename_utf8 ) saving = false; if (strstart(buf, SAVEGAME_PREFIX)) { - version = int_version(buf + sizeof(SAVEGAME_PREFIX) - 1, &mode, pak_extension); + version = int_version(buf + sizeof(SAVEGAME_PREFIX) - 1, pak_extension); if( version == 0 ) { close(); last_error = FILE_ERROR_NO_VERSION; @@ -355,8 +355,7 @@ bool loadsave_t::rd_open(const char *filename_utf8 ) *s++ = c; } *s = 0; - int dummy; - version = int_version(str, &dummy, pak_extension); + version = int_version(str, pak_extension); if( version == 0 ) { close(); last_error = FILE_ERROR_NO_VERSION; @@ -466,12 +465,12 @@ bool loadsave_t::wr_open(const char *filename_utf8, mode_t m, const char *pak_ex // delete trailing path separator this->pak_extension[strlen(this->pak_extension)-1] = 0; - version = int_version( savegame_version, NULL, NULL ); + version = int_version( savegame_version, NULL ); if( !is_xml() ) { char str[4096]; size_t len; - if( version<=102002 ) { + if( is_version_less(102, 3) ) { len = sprintf( str, SAVEGAME_PREFIX "%s%s%s\n", savegame_version, "zip", this->pak_extension ); } else { @@ -1342,7 +1341,7 @@ void loadsave_t::rd_obj_id(char *id_buf, int size) } -uint32 loadsave_t::int_version(const char *version_text, int * /*mode*/, char *pak_extension_str) +uint32 loadsave_t::int_version(const char *version_text, char *pak_extension_str) { // major number (0..) uint32 v0 = atoi(version_text); @@ -1371,25 +1370,28 @@ uint32 loadsave_t::int_version(const char *version_text, int * /*mode*/, char *p // the next char is either 'b'/'z'/'-', // if it is '.' the we try to load a simutrans-experimental savegame if(*version_text == '.') { - // st-exp savegame, we can't load it, return version=0 - strcpy(pak_extension_str,"(st-exp)"); + // Simutrans Extended savegame, we can't load it, return version=0 + if (pak_extension_str) { + std::strcpy(pak_extension_str,"(st-exp)"); + } return 0; } if( version<=102002 ) { - /* the compression and the mode we determined already ourselves (otherwise we cannot read this - * => leave the mode alone but for unknown modes! + /* the compression and the mode we determined already ourselves + * (otherwise we cannot read this => leave the mode alone but for unknown modes!) */ if (strstart(version_text, "bin")) { - //*mode = binary; version_text += 3; - } else if (strstart(version_text, "zip")) { - //*mode = zipped; + } + else if (strstart(version_text, "zip")) { version_text += 3; } else if( *version_text ) { // illegal version ... - strcpy(pak_extension_str,"(broken)"); + if (pak_extension_str) { + std::strcpy(pak_extension_str,"(broken)"); + } return 0; } } diff --git dataobj/loadsave.h dataobj/loadsave.h index 84d29b500..f16a590e8 100644 --- dataobj/loadsave.h +++ dataobj/loadsave.h @@ -34,19 +34,35 @@ struct file_descriptors_t; class loadsave_t { public: - enum mode_t { text=1, xml=2, binary=0, zipped=4, xml_zipped=6, bzip2=8, xml_bzip2=10 }; - enum file_error_t { FILE_ERROR_OK=0, FILE_ERROR_NOT_EXISTING, FILE_ERROR_BZ_CORRUPT, FILE_ERROR_GZ_CORRUPT, FILE_ERROR_NO_VERSION, FILE_ERROR_FUTURE_VERSION }; + enum mode_t { + binary=0, + text=1, + xml=2, + zipped=4, + xml_zipped=6, + bzip2=8, + xml_bzip2=10 + }; + + enum file_error_t { + FILE_ERROR_OK=0, + FILE_ERROR_NOT_EXISTING, + FILE_ERROR_BZ_CORRUPT, + FILE_ERROR_GZ_CORRUPT, + FILE_ERROR_NO_VERSION, + FILE_ERROR_FUTURE_VERSION + }; private: file_error_t last_error; - int mode; + int mode; ///< See mode_t bool saving; bool buffered; unsigned curr_buff; unsigned buf_pos[2]; unsigned buf_len[2]; char* ls_buf[2]; - uint32 version; + uint32 version; ///< savegame version int ident; // only for XML formatting char pak_extension[64]; // name of the pak folder during savetime @@ -79,9 +95,17 @@ private: void flush_buffer(int buf_num); public: - static mode_t save_mode; // default to use for saving - static mode_t autosave_mode; // default to use for autosaves and network mode client temp saves - static uint32 int_version(const char *version_text, int *mode, char *pak); + static mode_t save_mode; ///< default to use for saving + static mode_t autosave_mode; ///< default to use for autosaves and network mode client temp saves + + /** + * Parses the version information from @p version_text to a version number. + * @param[out] pak Pointer to a sufficiently large buffer (>= 64 chars); when the function returns, + * @p pak contains the pakset extension string. May be NULL. + * @retval 0 if an error occurred or the save cannot be loaded + * @retval !=0 the save version; in this case we can read the save file. + */ + static uint32 int_version(const char *version_text, char *pak); loadsave_t(); ~loadsave_t(); @@ -110,10 +134,10 @@ public: bool is_xml() const { return mode&xml; } const char *get_pak_extension() const { return pak_extension; } - uint32 get_version() const { return version; } + uint32 get_version_raw() const { return version; } inline bool is_version_atleast(uint32 major, uint32 save_minor) const { return !is_version_less(major, save_minor); } - inline bool is_version_less(uint32 major, uint32 save_minor) const { return version < major * 1000U + save_minor; } - inline bool is_version_equal(uint32 major, uint32 save_minor) const { return version == major * 1000U + save_minor; } + inline bool is_version_less(uint32 major, uint32 save_minor) const { return version < major * 1000U + save_minor; } + inline bool is_version_equal(uint32 major, uint32 save_minor) const { return version == major * 1000U + save_minor; } void rdwr_byte(sint8 &c); void rdwr_byte(uint8 &c); diff --git simmain.cc simmain.cc index 3a9918d74..3a5ff871e 100644 --- simmain.cc +++ simmain.cc @@ -628,7 +628,7 @@ int simu_main(int argc, char** argv) // now read last setting (might be overwritten by the tab-files) loadsave_t file; if(file.rd_open("settings.xml")) { - if( file.get_version()>loadsave_t::int_version(SAVEGAME_VER_NR, NULL, NULL ) ) { + if( file.get_version_raw()>loadsave_t::int_version(SAVEGAME_VER_NR, NULL ) ) { // too new => remove it file.close(); dr_remove("settings.xml"); diff --git simworld.cc simworld.cc index 9f2c2e6bd..4e5cc252f 100644 --- simworld.cc +++ simworld.cc @@ -2016,7 +2016,7 @@ karte_t::karte_t() : set_dirty(); // for new world just set load version to current savegame version - load_version = loadsave_t::int_version( env_t::savegame_version_str, NULL, NULL );; + load_version = loadsave_t::int_version( env_t::savegame_version_str, NULL ); // standard prices goods_manager_t::set_multiplier( 1000 ); @@ -4976,7 +4976,7 @@ bool karte_t::load(const char *filename) if(!file.rd_open(name)) { - if( (sint32)file.get_version()==-1 || file.get_version()>loadsave_t::int_version(SAVEGAME_VER_NR, NULL, NULL ) ) { + if( file.get_version_raw()==-1 || file.get_version_raw()>loadsave_t::int_version(SAVEGAME_VER_NR, NULL ) ) { dbg->warning("karte_t::load()", translator::translate("WRONGSAVE") ); create_win( new news_img("WRONGSAVE"), w_info, magic_none ); } @@ -4991,7 +4991,7 @@ bool karte_t::load(const char *filename) create_win(new news_img("WRONGSAVE"), w_info, magic_none); } else { -DBG_MESSAGE("karte_t::load()","Savegame version is %d", file.get_version()); +DBG_MESSAGE("karte_t::load()","Savegame version is %u", file.get_version_raw()); load(&file); @@ -5202,13 +5202,13 @@ void karte_t::load(loadsave_t *file) file->set_buffered(true); // jetzt geht das laden los - dbg->warning("karte_t::load", "Fileversion: %d", file->get_version()); + dbg->warning("karte_t::load", "Fileversion: %u", file->get_version_raw()); settings = env_t::default_settings; settings.rdwr(file); loaded_rotation = settings.get_rotation(); // some functions (finish_rd) need to know what version was loaded - load_version = file->get_version(); + load_version = file->get_version_raw(); if( env_t::networkmode ) { // to have games synchronized, transfer random counter too @@ -5733,7 +5733,7 @@ DBG_MESSAGE("karte_t::load()", "%d factories loaded", fab_list.get_count()); clear_random_mode(LOAD_RANDOM); // loading finished, reset savegame version to current - load_version = loadsave_t::int_version( env_t::savegame_version_str, NULL, NULL );; + load_version = loadsave_t::int_version( env_t::savegame_version_str, NULL ); dbg->warning("karte_t::load()","loaded savegame from %i/%i, next month=%i, ticks=%i (per month=1<<%i)",last_month,last_year,next_month_ticks,ticks,karte_t::ticks_per_world_month_shift); }