This is an automated email from the git hooks/post-receive script. smcv pushed a commit to branch debian/master in repository openjk.
commit fecff2e8baa53afada3194fa7533e87d08e72b72 Author: bibendovsky <[email protected]> Date: Sat Aug 6 20:24:49 2016 +0300 Revise saved game classes --- code/CMakeLists.txt | 6 +- code/game/CMakeLists.txt | 6 +- code/rd-vanilla/CMakeLists.txt | 6 +- codeJK2/game/CMakeLists.txt | 6 +- shared/qcommon/ojk_i_saved_game_file.h | 101 +++++++ shared/qcommon/ojk_i_saved_game_stream.h | 103 ------- shared/qcommon/ojk_saved_game_file.cpp | 302 +++++++++++++-------- shared/qcommon/ojk_saved_game_file.h | 66 ++--- ...tream_helper.h => ojk_saved_game_file_helper.h} | 273 +++++++++++-------- ...lper_fwd.h => ojk_saved_game_file_helper_fwd.h} | 81 ++++-- 10 files changed, 548 insertions(+), 402 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index db03e34..43d9542 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -178,11 +178,11 @@ if(BuildSPEngine OR BuildJK2SPEngine) "${SharedDir}/qcommon/ojk_exception.cpp" "${SharedDir}/qcommon/ojk_saved_game_exception.h" "${SharedDir}/qcommon/ojk_saved_game_exception.cpp" - "${SharedDir}/qcommon/ojk_i_saved_game_stream.h" + "${SharedDir}/qcommon/ojk_i_saved_game_file.h" "${SharedDir}/qcommon/ojk_saved_game_file.h" "${SharedDir}/qcommon/ojk_saved_game_file.cpp" - "${SharedDir}/qcommon/ojk_saved_game_stream_helper.h" - "${SharedDir}/qcommon/ojk_saved_game_stream_helper_fwd.h" + "${SharedDir}/qcommon/ojk_saved_game_file_helper.h" + "${SharedDir}/qcommon/ojk_saved_game_file_helper_fwd.h" "${SharedDir}/qcommon/ojk_scope_guard.h" ${SharedCommonFiles} diff --git a/code/game/CMakeLists.txt b/code/game/CMakeLists.txt index df94c7e..bdafd86 100644 --- a/code/game/CMakeLists.txt +++ b/code/game/CMakeLists.txt @@ -261,11 +261,11 @@ set(SPGameCommonFiles "${SPDir}/qcommon/q_shared.cpp" "${SPDir}/qcommon/q_shared.h" "${SPDir}/rd-common/mdx_format.h" - "${SharedDir}/qcommon/ojk_i_saved_game_stream.h" + "${SharedDir}/qcommon/ojk_i_saved_game_file.h" "${SharedDir}/qcommon/ojk_saved_game_file.h" "${SharedDir}/qcommon/ojk_saved_game_file.cpp" - "${SharedDir}/qcommon/ojk_saved_game_stream_helper.h" - "${SharedDir}/qcommon/ojk_saved_game_stream_helper_fwd.h" + "${SharedDir}/qcommon/ojk_saved_game_file_helper.h" + "${SharedDir}/qcommon/ojk_saved_game_file_helper_fwd.h" "${SharedDir}/qcommon/ojk_scope_guard.h" ${SharedCommonFiles} ) diff --git a/code/rd-vanilla/CMakeLists.txt b/code/rd-vanilla/CMakeLists.txt index dd4e50b..c3025e2 100644 --- a/code/rd-vanilla/CMakeLists.txt +++ b/code/rd-vanilla/CMakeLists.txt @@ -78,11 +78,11 @@ if(BuildSPRdVanilla OR BuildJK2SPRdVanilla) "${SPDir}/qcommon/q_math.cpp" "${SPDir}/qcommon/q_shared.cpp" "${SPDir}/qcommon/q_shared.h" - "${SharedDir}/qcommon/ojk_i_saved_game_stream.h" + "${SharedDir}/qcommon/ojk_i_saved_game_file.h" "${SharedDir}/qcommon/ojk_saved_game_file.h" "${SharedDir}/qcommon/ojk_saved_game_file.cpp" - "${SharedDir}/qcommon/ojk_saved_game_stream_helper.h" - "${SharedDir}/qcommon/ojk_saved_game_stream_helper_fwd.h" + "${SharedDir}/qcommon/ojk_saved_game_file_helper.h" + "${SharedDir}/qcommon/ojk_saved_game_file_helper_fwd.h" "${SharedDir}/qcommon/ojk_scope_guard.h" ${SharedCommonFiles} ) diff --git a/codeJK2/game/CMakeLists.txt b/codeJK2/game/CMakeLists.txt index 4ddfdaf..605cec6 100644 --- a/codeJK2/game/CMakeLists.txt +++ b/codeJK2/game/CMakeLists.txt @@ -233,11 +233,11 @@ set(JK2SPGameCommonFiles "${SPDir}/qcommon/q_shared.h" "${SPDir}/qcommon/strippublic.h" "${SPDir}/rd-common/mdx_format.h" - "${SharedDir}/qcommon/ojk_i_saved_game_stream.h" + "${SharedDir}/qcommon/ojk_i_saved_game_file.h" "${SharedDir}/qcommon/ojk_saved_game_file.h" "${SharedDir}/qcommon/ojk_saved_game_file.cpp" - "${SharedDir}/qcommon/ojk_saved_game_stream_helper.h" - "${SharedDir}/qcommon/ojk_saved_game_stream_helper_fwd.h" + "${SharedDir}/qcommon/ojk_saved_game_file_helper.h" + "${SharedDir}/qcommon/ojk_saved_game_file_helper_fwd.h" "${SharedDir}/qcommon/ojk_scope_guard.h" ${SharedCommonFiles} ) diff --git a/shared/qcommon/ojk_i_saved_game_file.h b/shared/qcommon/ojk_i_saved_game_file.h new file mode 100644 index 0000000..73f5b70 --- /dev/null +++ b/shared/qcommon/ojk_i_saved_game_file.h @@ -0,0 +1,101 @@ +// +// Saved game file interface. +// + + +#ifndef OJK_I_SAVED_GAME_FILE_INCLUDED +#define OJK_I_SAVED_GAME_FILE_INCLUDED + + +#include <cstdint> + + +namespace ojk +{ + + +class ISavedGameFile +{ +public: + ISavedGameFile() + { + } + + ISavedGameFile( + const ISavedGameFile& that) = delete; + + ISavedGameFile& operator=( + const ISavedGameFile& that) = delete; + + virtual ~ISavedGameFile() + { + } + + + // Tries to reads a chunk from the file into the internal buffer. + virtual bool read_chunk( + const uint32_t chunk_id) = 0; + + // Returns true if all data read from the internal buffer. + virtual bool is_all_data_read() const = 0; + + // Calls error method if all data not read from the internal buffer. + virtual void ensure_all_data_read() = 0; + + + // Writes a chunk into the file from the internal buffer. + virtual bool write_chunk( + const uint32_t chunk_id) = 0; + + + // Reads data from the internal buffer. + virtual bool read( + void* dst_data, + int dst_size) = 0; + + // Writes data into the internal buffer. + virtual bool write( + const void* src_data, + int src_size) = 0; + + // Increments buffer's offset by the specified non-negative count. + virtual bool skip( + int count) = 0; + + + // Stores current I/O buffer and it's position. + virtual void save_buffer() = 0; + + // Restores saved I/O buffer and it's position. + virtual void load_buffer() = 0; + + // Returns a pointer to data in the I/O buffer. + virtual const void* get_buffer_data() const = 0; + + // Returns a current size of the I/O buffer. + virtual int get_buffer_size() const = 0; + + + // Clears buffer and resets it's offset to the beginning. + virtual void reset_buffer() = 0; + + // Resets buffer offset to the beginning. + virtual void reset_buffer_offset() = 0; + + + // Error flag. + // Returns true if read/write operation failed otherwise false. + virtual bool is_failed() const = 0; + + // Clears error flag and message. + virtual void clear_error() = 0; + + // Calls Com_Error with last error message or with a generic one. + virtual void throw_error() = 0; +}; // ISavedGameFile + + +} // ojk + + +#endif // OJK_I_SAVED_GAME_FILE_INCLUDED diff --git a/shared/qcommon/ojk_i_saved_game_stream.h b/shared/qcommon/ojk_i_saved_game_stream.h deleted file mode 100644 index 4c6a6bf..0000000 --- a/shared/qcommon/ojk_i_saved_game_stream.h +++ /dev/null @@ -1,103 +0,0 @@ -// -// Saved game stream interface. -// - - -#ifndef OJK_I_SAVED_GAME_STREAM_INCLUDED -#define OJK_I_SAVED_GAME_STREAM_INCLUDED - - -#include <cstdint> - - -namespace ojk -{ - - -class ISavedGameStream -{ -public: - ISavedGameStream() - { - } - - ISavedGameStream( - const ISavedGameStream& that) = delete; - - ISavedGameStream& operator=( - const ISavedGameStream& that) = delete; - - virtual ~ISavedGameStream() - { - } - - - // Returns true if the saved game opened for reading. - virtual bool is_readable() const = 0; - - // Returns true if the saved game opened for writing. - virtual bool is_writable() const = 0; - - - // Reads a chunk from the file into the internal buffer. - virtual void read_chunk( - const uint32_t chunk_id) = 0; - - // Returns true if all data read from the internal buffer. - virtual bool is_all_data_read() const = 0; - - // Throws an exception if all data not read. - virtual void ensure_all_data_read() const = 0; - - - // Writes a chunk into the file from the internal buffer. - virtual void write_chunk( - const uint32_t chunk_id) = 0; - - - // Reads a raw data from the internal buffer. - virtual void read( - void* dst_data, - int dst_size) = 0; - - // Writes a raw data into the internal buffer. - virtual void write( - const void* src_data, - int src_size) = 0; - - // Increments buffer's offset by the specified non-negative count. - virtual void skip( - int count) = 0; - - - // Stores current I/O buffer and it's position. - virtual void save_buffer() = 0; - - // Restores saved I/O buffer and it's position. - virtual void load_buffer() = 0; - - // Returns a pointer to data in the I/O buffer. - virtual const void* get_buffer_data() const = 0; - - // Returns a current size of the I/O buffer. - virtual int get_buffer_size() const = 0; - - - // Clears buffer and resets it's offset to the beginning. - virtual void reset_buffer() = 0; - - // Resets buffer offset to the beginning. - virtual void reset_buffer_offset() = 0; - - - // If true won't throw an exception when buffer offset is beyond it's size. - // Although, no data will be read beyond the buffer. - virtual void allow_read_overflow( - bool value) = 0; -}; // ISavedGameStream - - -} // ojk - - -#endif // OJK_I_SAVED_GAME_STREAM_INCLUDED diff --git a/shared/qcommon/ojk_saved_game_file.cpp b/shared/qcommon/ojk_saved_game_file.cpp index bcee5f7..e883310 100644 --- a/shared/qcommon/ojk_saved_game_file.cpp +++ b/shared/qcommon/ojk_saved_game_file.cpp @@ -4,9 +4,8 @@ #include "ojk_saved_game_file.h" -#include "ojk_saved_game_stream_helper.h" +#include "ojk_saved_game_file_helper.h" #include <algorithm> -#include "ojk_saved_game_exception.h" #include "qcommon/qcommon.h" #include "server/server.h" @@ -16,6 +15,7 @@ namespace ojk SavedGameFile::SavedGameFile() : + error_message_(), file_handle_(), io_buffer_(), saved_io_buffer_(), @@ -24,8 +24,7 @@ SavedGameFile::SavedGameFile() : rle_buffer_(), is_readable_(), is_writable_(), - is_write_failed_(), - is_read_overflow_allowed_() + is_failed_() { } @@ -40,10 +39,10 @@ bool SavedGameFile::open( close(); - const auto&& file_path = generate_path( + const auto file_path = generate_path( base_file_name); - auto is_succeed = true; + bool is_succeed = true; static_cast<void>(::FS_FOpenFileRead( file_path.c_str(), @@ -54,13 +53,13 @@ bool SavedGameFile::open( { is_succeed = false; - const auto&& error_message = + error_message_ = S_COLOR_RED "Failed to open a saved game file: \"" + file_path + "\"."; ::Com_DPrintf( "%s\n", - error_message.c_str()); + error_message_.c_str()); } if (is_succeed) @@ -68,25 +67,35 @@ bool SavedGameFile::open( is_readable_ = true; } - auto sg_version = -1; if (is_succeed) { - SavedGameStreamHelper sgsh(this); + SavedGameFileHelper sgfh( + this); + + int sg_version = -1; - static_cast<void>(sgsh.read_chunk<int32_t>( + if (sgfh.try_read_chunk<int32_t>( INT_ID('_', 'V', 'E', 'R'), - sg_version)); + sg_version)) + { + if (sg_version != iSAVEGAME_VERSION) + { + is_succeed = false; - if (sg_version != iSAVEGAME_VERSION) + ::Com_Printf( + S_COLOR_RED "File \"%s\" has version # %d (expecting %d)\n", + base_file_name.c_str(), + sg_version, + iSAVEGAME_VERSION); + } + } + else { is_succeed = false; ::Com_Printf( - S_COLOR_RED "File \"%s\" has version # %d (expecting %d)\n", - base_file_name.c_str(), - sg_version, - iSAVEGAME_VERSION); + S_COLOR_RED "Failed to read a version.\n"); } } @@ -107,7 +116,7 @@ bool SavedGameFile::create( remove( base_file_name); - const auto&& file_path = generate_path( + const auto file_path = generate_path( base_file_name); file_handle_ = ::FS_FOpenFileWrite( @@ -115,7 +124,7 @@ bool SavedGameFile::create( if (file_handle_ == 0) { - const auto&& error_message = + const auto error_message = S_COLOR_RED "Failed to create a saved game file: \"" + file_path + "\"."; @@ -131,12 +140,18 @@ bool SavedGameFile::create( const auto sg_version = iSAVEGAME_VERSION; - SavedGameStreamHelper sgsh(this); + SavedGameFileHelper sgsh(this); sgsh.write_chunk<int32_t>( INT_ID('_', 'V', 'E', 'R'), sg_version); + if (is_failed()) + { + close(); + return false; + } + return true; } @@ -148,30 +163,33 @@ void SavedGameFile::close() file_handle_ = 0; } + error_message_.clear(); + io_buffer_.clear(); io_buffer_offset_ = 0; + saved_io_buffer_.clear(); + saved_io_buffer_offset_ = 0; + + rle_buffer_.clear(); + is_readable_ = false; is_writable_ = false; - is_write_failed_ = false; + is_failed_ = false; } -bool SavedGameFile::is_readable() const +bool SavedGameFile::read_chunk( + const uint32_t chunk_id) { - return is_readable_; -} + if (is_failed_) + { + return false; + } -bool SavedGameFile::is_writable() const -{ - return is_writable_; -} -void SavedGameFile::read_chunk( - const uint32_t chunk_id) -{ io_buffer_offset_ = 0; - const auto&& chunk_id_string = get_chunk_id_string( + const auto chunk_id_string = get_chunk_id_string( chunk_id); ::Com_DPrintf( @@ -191,7 +209,7 @@ void SavedGameFile::read_chunk( static_cast<int>(sizeof(uiLoadedLength)), file_handle_); - const auto bBlockIsCompressed = (static_cast<int32_t>(uiLoadedLength) < 0); + const bool bBlockIsCompressed = (static_cast<int32_t>(uiLoadedLength) < 0); if (bBlockIsCompressed) { @@ -202,18 +220,19 @@ void SavedGameFile::read_chunk( // if (ulLoadedChid != chunk_id) { - const auto&& loaded_chunk_id_string = get_chunk_id_string( + is_failed_ = true; + + const auto loaded_chunk_id_string = get_chunk_id_string( ulLoadedChid); - const auto&& error_message = + error_message_ = "Loaded chunk ID (" + - loaded_chunk_id_string + - ") does not match requested chunk ID (" + - chunk_id_string + - ")."; + loaded_chunk_id_string + + ") does not match requested chunk ID (" + + chunk_id_string + + ")."; - throw_error( - error_message); + return false; } uint32_t uiLoadedCksum = 0; @@ -274,11 +293,12 @@ void SavedGameFile::read_chunk( if (uiLoadedMagic != get_jo_magic_value()) { - const auto&& error_message = + is_failed_ = true; + + error_message_ = "Bad saved game magic for chunk " + chunk_id_string + "."; - throw_error( - error_message); + return false; } #endif // JK2_MODE @@ -299,11 +319,12 @@ void SavedGameFile::read_chunk( if (uiLoadedCksum != uiCksum) { - const auto&& error_message = + is_failed_ = true; + + error_message_ = "Failed checksum check for chunk " + chunk_id_string + "."; - throw_error( - error_message); + return false; } // Make sure we didn't encounter any read errors... @@ -318,12 +339,15 @@ void SavedGameFile::read_chunk( #endif 0) { - const auto&& error_message = + is_failed_ = true; + + error_message_ = "Error during loading chunk " + chunk_id_string + "."; - throw_error( - error_message); + return false; } + + return true; } bool SavedGameFile::is_all_data_read() const @@ -331,19 +355,26 @@ bool SavedGameFile::is_all_data_read() const return io_buffer_.size() == io_buffer_offset_; } -void SavedGameFile::ensure_all_data_read() const +void SavedGameFile::ensure_all_data_read() { if (!is_all_data_read()) { - throw_error( - "Not all expected data read."); + error_message_ = "Not all expected data read."; + + throw_error(); } } -void SavedGameFile::write_chunk( +bool SavedGameFile::write_chunk( const uint32_t chunk_id) { - const auto&& chunk_id_string = get_chunk_id_string( + if (is_failed_) + { + return false; + } + + + const auto chunk_id_string = get_chunk_id_string( chunk_id); ::Com_DPrintf( @@ -352,7 +383,7 @@ void SavedGameFile::write_chunk( if (::sv_testsave->integer != 0) { - return; + return true; } const auto src_size = static_cast<int>(io_buffer_.size()); @@ -435,13 +466,16 @@ void SavedGameFile::write_chunk( #endif // JK2_MODE 0) { - is_write_failed_ = true; + is_failed_ = true; + + error_message_ = "Failed to write " + chunk_id_string + " chunk."; ::Com_Printf( - S_COLOR_RED "Failed to write %s chunk\n", - chunk_id_string.c_str()); + "%s%s\n", + S_COLOR_RED, + error_message_.c_str()); - return; + return false; } } else @@ -489,91 +523,107 @@ void SavedGameFile::write_chunk( #endif // JK2_MODE 0) { - is_write_failed_ = true; + is_failed_ = true; + + error_message_ = "Failed to write " + chunk_id_string + " chunk."; ::Com_Printf( - S_COLOR_RED "Failed to write %s chunk\n", - chunk_id_string.c_str()); + "%s%s\n", + S_COLOR_RED, + error_message_.c_str()); - return; + return false; } } + + return true; } -void SavedGameFile::read( +bool SavedGameFile::read( void* dst_data, int dst_size) { + if (is_failed_) + { + return false; + } + if (!dst_data) { - throw_error( - "Null pointer."); + is_failed_ = true; + error_message_ = "Null pointer."; + return false; } if (dst_size < 0) { - throw_error( - "Negative size."); + is_failed_ = true; + error_message_ = "Negative size."; + return false; } if (!is_readable_) { - throw_error( - "Not readable."); + is_failed_ = true; + error_message_ = "Not readable."; + return false; } if (dst_size == 0) { - return; + return true; } - auto is_overflowed = ((io_buffer_offset_ + dst_size) > io_buffer_.size()); - - if (is_overflowed) + if ((io_buffer_offset_ + dst_size) > io_buffer_.size()) { - if (!is_read_overflow_allowed_) - { - throw_error( - "Not enough data."); - } + is_failed_ = true; + error_message_ = "Not enough data."; + return false; } - if (!is_overflowed) - { - std::uninitialized_copy_n( - &io_buffer_[io_buffer_offset_], - dst_size, - static_cast<uint8_t*>(dst_data)); - } + std::uninitialized_copy_n( + &io_buffer_[io_buffer_offset_], + dst_size, + static_cast<uint8_t*>(dst_data)); io_buffer_offset_ += dst_size; + + return true; } -void SavedGameFile::write( +bool SavedGameFile::write( const void* src_data, int src_size) { + if (is_failed_) + { + return false; + } + if (!src_data) { - throw_error( - "Null pointer."); + is_failed_ = true; + error_message_ = "Null pointer."; + return false; } if (src_size < 0) { - throw_error( - "Negative size."); + is_failed_ = true; + error_message_ = "Negative size."; + return false; } if (!is_writable_) { - throw_error( - "Not writable."); + is_failed_ = true; + error_message_ = "Not writable."; + return false; } if (src_size == 0) { - return; + return true; } const auto new_buffer_size = io_buffer_offset_ + src_size; @@ -587,31 +637,40 @@ void SavedGameFile::write( &io_buffer_[io_buffer_offset_]); io_buffer_offset_ = new_buffer_size; + + return true; } -bool SavedGameFile::is_write_failed() const +bool SavedGameFile::is_failed() const { - return is_write_failed_; + return is_failed_; } -void SavedGameFile::skip( +bool SavedGameFile::skip( int count) { + if (is_failed_) + { + return false; + } + if (!is_readable_ && !is_writable_) { - throw_error( - "Not open or created."); + is_failed_ = true; + error_message_ = "Not open or created."; + return false; } if (count < 0) { - throw_error( - "Negative count."); + is_failed_ = true; + error_message_ = "Negative count."; + return false; } if (count == 0) { - return; + return true; } const auto new_offset = io_buffer_offset_ + count; @@ -621,8 +680,9 @@ void SavedGameFile::skip( { if (is_readable_) { - throw_error( - "Not enough data."); + is_failed_ = true; + error_message_ = "Not enough data."; + return false; } else if (is_writable_) { @@ -635,6 +695,8 @@ void SavedGameFile::skip( } io_buffer_offset_ = new_offset; + + return true; } void SavedGameFile::save_buffer() @@ -677,7 +739,7 @@ void SavedGameFile::rename( { ::Com_Printf( S_COLOR_RED "Error during savegame-rename." - " Check \"%s\" for write-protect or disk full!\n", + " Check \"%s\" for write-protect or disk full!\n", new_path.c_str()); } } @@ -698,24 +760,30 @@ SavedGameFile& SavedGameFile::get_instance() return result; } -void SavedGameFile::allow_read_overflow( - bool value) +bool SavedGameFile::is_failed() const { - is_read_overflow_allowed_ = value; + return is_failed_; } -void SavedGameFile::throw_error( - const char* message) +void SavedGameFile::clear_error() { - throw SavedGameException( - message); + is_failed_ = false; + error_message_.clear(); } -void SavedGameFile::throw_error( - const std::string& message) +void SavedGameFile::throw_error() { - throw SavedGameException( - message); + if (error_message_.empty()) + { + error_message_ = "Generic error."; + } + + error_message_ = "SG: " + error_message_; + + ::Com_Error( + ERR_DROP, + "%s", + error_message_.c_str()); } void SavedGameFile::compress( diff --git a/shared/qcommon/ojk_saved_game_file.h b/shared/qcommon/ojk_saved_game_file.h index 1ffa06c..1de9c97 100644 --- a/shared/qcommon/ojk_saved_game_file.h +++ b/shared/qcommon/ojk_saved_game_file.h @@ -11,7 +11,7 @@ #include <cstdint> #include <string> #include <vector> -#include "ojk_i_saved_game_stream.h" +#include "ojk_i_saved_game_file.h" namespace ojk @@ -19,7 +19,7 @@ namespace ojk class SavedGameFile : - public ISavedGameStream + public ISavedGameFile { public: SavedGameFile(); @@ -45,48 +45,41 @@ public: void close(); - // Returns true if the saved game opened for reading. - bool is_readable() const override; - - // Returns true if the saved game opened for writing. - bool is_writable() const override; - - // Reads a chunk from the file into the internal buffer. - void read_chunk( + bool read_chunk( const uint32_t chunk_id) override; - using ISavedGameStream::read_chunk; - // Returns true if all data read from the internal buffer. bool is_all_data_read() const override; - // Throws an exception if all data not read. - void ensure_all_data_read() const override; + // Calls error method if all data not read. + void ensure_all_data_read() override; // Writes a chunk into the file from the internal buffer. - void write_chunk( + // Returns true on success or false otherwise. + bool write_chunk( const uint32_t chunk_id) override; // Reads a raw data from the internal buffer. - void read( + // Returns true on success or false otherwise. + bool read( void* dst_data, int dst_size) override; // Writes a raw data into the internal buffer. - void write( + // Returns true on success or false otherwise. + bool write( const void* src_data, int src_size) override; - bool is_write_failed() const; - // Increments buffer's offset by the specified non-negative count. - void skip( + // Returns true on success or false otherwise. + bool skip( int count) override; @@ -110,10 +103,16 @@ public: // Resets buffer offset to the beginning. void reset_buffer_offset() override; - // If true won't throw an exception when buffer offset is beyond it's size. - // Although, no data will be read beyond the buffer. - void allow_read_overflow( - bool value) override; + + // Returns true if read/write operation failed otherwise false. + // Any chunk related try-method clears at the beginning this flag. + bool is_failed() const override; + + // Clears error flag and message. + void clear_error() override; + + // Calls Com_Error with last error message or with a generic one. + void throw_error() override; // Renames a saved game file. @@ -135,6 +134,9 @@ private: using Paths = std::vector<std::string>; + // Last error message. + std::string error_message_; + // A handle to a file. int32_t file_handle_; @@ -159,20 +161,8 @@ private: // True if saved game opened for writing. bool is_writable_; - // True if any previous write operation failed. - bool is_write_failed_; - - // Controls exception throw on read overflow. - bool is_read_overflow_allowed_; - - - // Throws an exception. - static void throw_error( - const char* message); - - // Throws an exception. - static void throw_error( - const std::string& message); + // Error flag. + bool is_failed_; // Compresses data. diff --git a/shared/qcommon/ojk_saved_game_stream_helper.h b/shared/qcommon/ojk_saved_game_file_helper.h similarity index 74% rename from shared/qcommon/ojk_saved_game_stream_helper.h rename to shared/qcommon/ojk_saved_game_file_helper.h index 6af5dd0..05fbfa0 100644 --- a/shared/qcommon/ojk_saved_game_stream_helper.h +++ b/shared/qcommon/ojk_saved_game_file_helper.h @@ -1,15 +1,15 @@ // -// Saved game stream helper. +// Saved game file helper. // -#ifndef OJK_SAVED_GAME_STREAM_HELPER_INCLUDED -#define OJK_SAVED_GAME_STREAM_HELPER_INCLUDED +#ifndef OJK_SAVED_GAME_FILE_HELPER_INCLUDED +#define OJK_SAVED_GAME_FILE_HELPER_INCLUDED #include <cstdint> #include <type_traits> -#include "ojk_saved_game_stream_helper_fwd.h" +#include "ojk_saved_game_file_helper_fwd.h" #include "ojk_scope_guard.h" @@ -20,9 +20,9 @@ namespace ojk // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< // Class stuff -inline SavedGameStreamHelper::SavedGameStreamHelper( - ISavedGameStream* saved_game_stream) : - saved_game_stream_(saved_game_stream) +inline SavedGameFileHelper::SavedGameFileHelper( + ISavedGameFile* saved_game_file) : + saved_game_file_(saved_game_file) { } @@ -31,36 +31,61 @@ inline SavedGameStreamHelper::SavedGameStreamHelper( // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -// read_chunk +// try_read_chunk template<typename TSrc, typename TDst> -void SavedGameStreamHelper::read_chunk( +bool SavedGameFileHelper::try_read_chunk( const uint32_t chunk_id, TDst& dst_value) { - saved_game_stream_->read_chunk( - chunk_id); + if (!saved_game_file_->read_chunk( + chunk_id);) + { + return false; + } - read<TSrc>( - dst_value); + if (!try_read<TSrc>( + dst_value)) + { + return false; + } - saved_game_stream_->ensure_all_data_read(); + return saved_game_file_->is_all_data_read(); } +// try_read_chunk +// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + +// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +// read_chunk + template<typename TSrc, typename TDst> -void SavedGameStreamHelper::read_chunk( +void SavedGameFileHelper::read_chunk( + const uint32_t chunk_id, + TDst& dst_value) +{ + if (!try_read_chunk<TSrc>( + chunk_id, + dst_value)) + { + saved_game_file_->throw_error(); + } +} + +template<typename TSrc, typename TDst> +void SavedGameFileHelper::read_chunk( const uint32_t chunk_id, TDst* dst_values, int dst_count) { - saved_game_stream_->read_chunk( - chunk_id); - - read<TSrc>( - dst_values, - dst_count); - - saved_game_stream_->ensure_all_data_read(); + if (!try_read_chunk<TSrc>( + chunk_id, + dst_value, + dst_count)) + { + saved_game_file_->throw_error(); + } } // read_chunk @@ -71,53 +96,53 @@ void SavedGameStreamHelper::read_chunk( // write_chunk template<typename TSize> -void SavedGameStreamHelper::write_chunk_and_size( +void SavedGameFileHelper::write_chunk_and_size( const uint32_t size_chunk_id, const uint32_t data_chunk_id) { - saved_game_stream_->save_buffer(); + saved_game_file_->save_buffer(); - auto data_size = saved_game_stream_->get_buffer_size(); + auto data_size = saved_game_file_->get_buffer_size(); - saved_game_stream_->reset_buffer(); + saved_game_file_->reset_buffer(); write_chunk<TSize>( size_chunk_id, data_size); - saved_game_stream_->load_buffer(); + saved_game_file_->load_buffer(); - saved_game_stream_->write_chunk( + saved_game_file_->write_chunk( data_chunk_id); } template<typename TDst, typename TSrc> -void SavedGameStreamHelper::write_chunk( +void SavedGameFileHelper::write_chunk( const uint32_t chunk_id, const TSrc& src_value) { - saved_game_stream_->reset_buffer(); + saved_game_file_->reset_buffer(); write<TDst>( src_value); - saved_game_stream_->write_chunk( + saved_game_file_->write_chunk( chunk_id); } template<typename TDst, typename TSrc> -void SavedGameStreamHelper::write_chunk( +void SavedGameFileHelper::write_chunk( const uint32_t chunk_id, const TSrc* src_values, int src_count) { - saved_game_stream_->reset_buffer(); + saved_game_file_->reset_buffer(); write<TDst>( src_values, src_count); - saved_game_stream_->write_chunk( + saved_game_file_->write_chunk( chunk_id); } @@ -126,10 +151,10 @@ void SavedGameStreamHelper::write_chunk( // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -// read +// try_read template<typename TSrc, typename TDst> -void SavedGameStreamHelper::read( +bool SavedGameFileHelper::try_read( TDst& dst_value) { using Tag = typename std::conditional < @@ -162,13 +187,32 @@ void SavedGameStreamHelper::read( !std::is_same<Tag, void>::value, "Unsupported type."); - read<TSrc>( + return try_read<TSrc>( dst_value, Tag()); } +// try_read +// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + +// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +// read + template<typename TSrc, typename TDst> -void SavedGameStreamHelper::read( +void SavedGameFileHelper::read( + TDst& dst_value) +{ + if (!try_read<TSrc>( + dst_value, + Tag())) + { + saved_game_file_->throw_error(); + } +} + +template<typename TSrc, typename TDst> +bool SavedGameFileHelper::try_read( TDst& dst_value, BooleanTag) { @@ -176,18 +220,23 @@ void SavedGameStreamHelper::read( TSrc src_value; - saved_game_stream_->read( + if (!saved_game_file_->read( &src_value, - static_cast<int>(sizeof(TSrc))); + static_cast<int>(sizeof(TSrc)))) + { + return false; + } // FIXME Byte order // dst_value = (src_value != 0); + + return true; } template<typename TSrc, typename TDst> -void SavedGameStreamHelper::read( +bool SavedGameFileHelper::try_read( TDst& dst_value, NumericTag) { @@ -195,18 +244,23 @@ void SavedGameStreamHelper::read( TSrc src_value; - saved_game_stream_->read( + if (!saved_game_file_->read( &src_value, - src_size); + src_size)) + { + return false; + } // FIXME Byte order // dst_value = static_cast<TDst>(src_value); + + return true; } template<typename TSrc, typename TDst> -void SavedGameStreamHelper::read( +bool SavedGameFileHelper::try_read( TDst*& dst_value, PointerTag) { @@ -223,15 +277,20 @@ void SavedGameStreamHelper::read( auto dst_number = DstNumeric(); - read<TSrc>( + if (!try_read<TSrc>( dst_number, - NumericTag()); + NumericTag())) + { + return false; + } dst_value = reinterpret_cast<TDst*>(dst_number); + + return true; } template<typename TSrc, typename TDst> -void SavedGameStreamHelper::read( +bool SavedGameFileHelper::try_read( TDst& dst_value, ClassTag) { @@ -240,25 +299,27 @@ void SavedGameStreamHelper::read( "Unsupported types."); dst_value.sg_import( - saved_game_stream_); + saved_game_file_); + + return !saved_game_file_->is_failed(); } template<typename TSrc, typename TDst, int TCount> -void SavedGameStreamHelper::read( +bool SavedGameFileHelper::try_read( TDst(&dst_values)[TCount], Array1dTag) { - read<TSrc>( + return try_read<TSrc>( &dst_values[0], TCount); } template<typename TSrc, typename TDst, int TCount1, int TCount2> -void SavedGameStreamHelper::read( +bool SavedGameFileHelper::try_read( TDst(&dst_values)[TCount1][TCount2], Array2dTag) { - read<TSrc>( + return try_read<TSrc>( &dst_values[0][0], TCount1 * TCount2); } @@ -268,42 +329,10 @@ void SavedGameStreamHelper::read( // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -// try_read +// try_read (C-array) template<typename TSrc, typename TDst> -bool SavedGameStreamHelper::try_read( - TDst& dst_value) -{ - ScopeGuard scope_guard( - [saved_game_stream_]() - { - saved_game_stream_->allow_read_overflow( - true); - }, - - [saved_game_stream_]() - { - saved_game_stream_->allow_read_overflow( - false); - } - ); - - - read<TSrc>( - dst_value); - - return saved_game_stream_->is_all_data_read(); -} - -// try_read -// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - - -// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -// read (C-array) - -template<typename TSrc, typename TDst> -void SavedGameStreamHelper::read( +bool SavedGameFileHelper::try_read( TDst* dst_values, int dst_count) { @@ -353,30 +382,55 @@ void SavedGameStreamHelper::read( CastTag >::type; - read<TSrc>( + return try_read<TSrc>( dst_values, dst_count, Tag()); } +// try_read (C-array) +// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + + +// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +// read (C-array) + +template<typename TSrc, typename TDst> +void SavedGameFileHelper::read( + TDst* dst_values, + int dst_count) +{ + if (!try_read<TSrc>( + dst_values, + dst_count)) + { + saved_game_file_->throw_error(); + } +} + template<typename TSrc, typename TDst> -void SavedGameStreamHelper::read( +bool SavedGameFileHelper::try_read( TDst* dst_values, int dst_count, InplaceTag) { const auto dst_size = dst_count * static_cast<int>(sizeof(TDst)); - saved_game_stream_->read( + if (!saved_game_file_->read( dst_values, - dst_size); + dst_size)) + { + return false; + } // FIXME Byte order // + + return true; } template<typename TSrc, typename TDst> -void SavedGameStreamHelper::read( +bool SavedGameFileHelper::try_read( TDst* dst_values, int dst_count, CastTag) @@ -397,10 +451,15 @@ void SavedGameStreamHelper::read( for (int i = 0; i < dst_count; ++i) { - read<TSrc>( + if (!try_read<TSrc>( dst_values[i], - Tag()); + Tag())) + { + return false; + } } + + return true; } // read (C-array) @@ -411,7 +470,7 @@ void SavedGameStreamHelper::read( // write template<typename TDst, typename TSrc> -void SavedGameStreamHelper::write( +void SavedGameFileHelper::write( const TSrc& src_value) { using Tag = typename std::conditional< @@ -446,7 +505,7 @@ void SavedGameStreamHelper::write( } template<typename TDst, typename TSrc> -void SavedGameStreamHelper::write( +void SavedGameFileHelper::write( const TSrc& src_value, NumericTag) { @@ -457,13 +516,13 @@ void SavedGameStreamHelper::write( // FIXME Byte order // - saved_game_stream_->write( + saved_game_file_->write( &dst_value, dst_size); } template<typename TDst, typename TSrc> -void SavedGameStreamHelper::write( +void SavedGameFileHelper::write( const TSrc* src_value, PointerTag) { @@ -481,7 +540,7 @@ void SavedGameStreamHelper::write( } template<typename TDst, typename TSrc> -void SavedGameStreamHelper::write( +void SavedGameFileHelper::write( const TSrc& src_value, ClassTag) { @@ -490,11 +549,11 @@ void SavedGameStreamHelper::write( "Unsupported types."); src_value.sg_export( - saved_game_stream_); + saved_game_file_); } template<typename TDst, typename TSrc, int TCount> -void SavedGameStreamHelper::write( +void SavedGameFileHelper::write( const TSrc(&src_values)[TCount], Array1dTag) { @@ -504,7 +563,7 @@ void SavedGameStreamHelper::write( } template<typename TDst, typename TSrc, int TCount1, int TCount2> -void SavedGameStreamHelper::write( +void SavedGameFileHelper::write( const TSrc(&src_values)[TCount1][TCount2], Array2dTag) { @@ -521,7 +580,7 @@ void SavedGameStreamHelper::write( // write (C-array) template<typename TDst, typename TSrc> -void SavedGameStreamHelper::write( +void SavedGameFileHelper::write( const TSrc* src_values, int src_count) { @@ -577,14 +636,14 @@ void SavedGameStreamHelper::write( } template<typename TDst, typename TSrc> -void SavedGameStreamHelper::write( +void SavedGameFileHelper::write( const TSrc* src_values, int src_count, InplaceTag) { const auto src_size = src_count * static_cast<int>(sizeof(TSrc)); - saved_game_stream_->write( + saved_game_file_->write( src_values, src_size); @@ -593,7 +652,7 @@ void SavedGameStreamHelper::write( } template<typename TDst, typename TSrc> -void SavedGameStreamHelper::write( +void SavedGameFileHelper::write( const TSrc* src_values, int src_count, CastTag) @@ -627,4 +686,4 @@ void SavedGameStreamHelper::write( } // ojk -#endif // OJK_SAVED_GAME_STREAM_HELPER_INCLUDED +#endif // OJK_SAVED_GAME_FILE_HELPER_INCLUDED diff --git a/shared/qcommon/ojk_saved_game_stream_helper_fwd.h b/shared/qcommon/ojk_saved_game_file_helper_fwd.h similarity index 71% rename from shared/qcommon/ojk_saved_game_stream_helper_fwd.h rename to shared/qcommon/ojk_saved_game_file_helper_fwd.h index 63d2fe6..fb9dfb4 100644 --- a/shared/qcommon/ojk_saved_game_stream_helper_fwd.h +++ b/shared/qcommon/ojk_saved_game_file_helper_fwd.h @@ -1,29 +1,38 @@ // -// Saved game stream helper. +// Saved game file helper. // (forward declaration) // -#ifndef OJK_SAVED_GAME_STREAM_HELPER_FWD_INCLUDED -#define OJK_SAVED_GAME_STREAM_HELPER_FWD_INCLUDED +#ifndef OJK_SAVED_GAME_FILE_HELPER_FWD_INCLUDED +#define OJK_SAVED_GAME_FILE_HELPER_FWD_INCLUDED -#include "ojk_i_saved_game_stream.h" +#include "ojk_i_saved_game_file.h" namespace ojk { -class SavedGameStreamHelper +class SavedGameFileHelper { public: - SavedGameStreamHelper( - ISavedGameStream* saved_game_stream); + SavedGameFileHelper( + ISavedGameFile* saved_game_file); + // Tries to read a value or an array of values from the file via + // the internal buffer. + // Return true on success or false otherwise. + template<typename TSrc = void, typename TDst = void> + bool try_read_chunk( + const uint32_t chunk_id, + TDst& dst_value); + // Reads a value or an array of values from the file via // the internal buffer. + // Calls error method on error. template<typename TSrc = void, typename TDst = void> void read_chunk( const uint32_t chunk_id, @@ -31,6 +40,16 @@ public: // Reads an array of values with specified count from // the file via the internal buffer. + // Return true on success or false otherwise. + template<typename TSrc = void, typename TDst = void> + bool try_read_chunk( + const uint32_t chunk_id, + TDst* dst_values, + int dst_count); + + // Reads an array of values with specified count from + // the file via the internal buffer. + // Calls error method on error. template<typename TSrc = void, typename TDst = void> void read_chunk( const uint32_t chunk_id, @@ -59,31 +78,43 @@ public: const TSrc* src_values, int src_count); + + // Tries to read a value or array of values from the internal buffer. + // Returns true on success or false otherwise. + template<typename TSrc = void, typename TDst = void> + bool try_read( + TDst& dst_value); + // Reads a value or array of values from the internal buffer. + // Calls error method on error. template<typename TSrc = void, typename TDst = void> void read( TDst& dst_value); - // Reads an array of values with specificed count from the internal buffer. + // Tries to read an array of values with specificed count from the internal buffer. + // Calls error method on error. + // Return true on success or false otherwise. template<typename TSrc = void, typename TDst = void> - void read( + bool try_read( TDst* dst_values, int dst_count); - - // Tries to read a value or array of values from the internal buffer. - // Returns true on success or false otherwise. + // Reads an array of values with specificed count from the internal buffer. + // Calls error method on error. template<typename TSrc = void, typename TDst = void> - bool try_read( - TDst& dst_value); + void read( + TDst* dst_values, + int dst_count); // Writes a value or array of values into the internal buffer. + // Returns true on success or false otherwise. template<typename TDst = void, typename TSrc = void> void write( const TSrc& src_value); // Writes an array of values with specificed count into the internal buffer. + // Returns true on success or false otherwise. template<typename TDst = void, typename TSrc = void> void write( const TSrc* src_values, @@ -91,7 +122,7 @@ public: private: - ISavedGameStream* saved_game_stream_; + ISavedGameFile* saved_game_file_; // Tags for dispatching. @@ -106,44 +137,44 @@ private: template<typename TSrc, typename TDst> - void read( + bool try_read( TDst& dst_value, BooleanTag); template<typename TSrc, typename TDst> - void read( + bool try_read( TDst& dst_value, NumericTag); template<typename TSrc, typename TDst> - void read( + bool try_read( TDst*& dst_value, PointerTag); template<typename TSrc, typename TDst> - void read( + bool try_read( TDst& dst_value, ClassTag); template<typename TSrc, typename TDst, int TCount> - void read( + bool try_read( TDst(&dst_values)[TCount], Array1dTag); template<typename TSrc, typename TDst, int TCount1, int TCount2> - void read( + bool try_read( TDst(&dst_values)[TCount1][TCount2], Array2dTag); template<typename TSrc, typename TDst> - void read( + bool try_read( TDst* dst_values, int dst_count, InplaceTag); template<typename TSrc, typename TDst> - void read( + bool try_read( TDst* dst_values, int dst_count, CastTag); @@ -186,11 +217,11 @@ private: const TSrc* src_values, int src_count, CastTag); -}; // SavedGameStreamHelper +}; // SavedGameFileHelper } -#endif // OJK_SAVED_GAME_STREAM_HELPER_FWD_INCLUDED +#endif // OJK_SAVED_GAME_FILE_HELPER_FWD_INCLUDED -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/openjk.git _______________________________________________ Pkg-games-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits

