diff --git a/src/sl/saveload.cpp b/src/sl/saveload.cpp index ebb682df4f..0ac0b93d4a 100644 --- a/src/sl/saveload.cpp +++ b/src/sl/saveload.cpp @@ -2073,6 +2073,26 @@ std::pair SlSaveToTempBufferRestore(uint8 state) return result; } +SlConditionallySaveState SlConditionallySaveSetup() +{ + assert(_sl.action == SLA_SAVE); + if (_sl.dumper->IsAutoLengthActive()) { + return { (size_t)(_sl.dumper->buf - _sl.dumper->autolen_buf), 0, true }; + } else { + return { 0, SlSaveToTempBufferSetup(), false }; + } +} + +extern void SlConditionallySaveCompletion(const SlConditionallySaveState &state, bool save) +{ + if (state.nested) { + if (!save) _sl.dumper->buf = _sl.dumper->autolen_buf + state.current_len; + } else { + auto result = SlSaveToTempBufferRestore(state.need_length); + if (save) _sl.dumper->CopyBytes(result.first, result.second); + } +} + SlLoadFromBufferState SlLoadFromBufferSetup(const byte *buffer, size_t length) { assert(_sl.action == SLA_LOAD || _sl.action == SLA_LOAD_CHECK); diff --git a/src/sl/saveload.h b/src/sl/saveload.h index af0dad002f..19ba7b031e 100644 --- a/src/sl/saveload.h +++ b/src/sl/saveload.h @@ -747,6 +747,29 @@ std::vector SlSaveToVector(F proc) return std::vector(result.begin(), result.end()); } +struct SlConditionallySaveState { + size_t current_len; + uint8 need_length; + bool nested; +}; + +/** + * Run proc, saving as normal if proc returns true, otherwise the saved data is discarded + * @param proc The callback procedure that is called, this should return true to save, false to discard + * @return Whether the callback procedure returned true to save + */ +template +bool SlConditionallySave(F proc) +{ + extern SlConditionallySaveState SlConditionallySaveSetup(); + extern void SlConditionallySaveCompletion(const SlConditionallySaveState &state, bool save); + + SlConditionallySaveState state = SlConditionallySaveSetup(); + bool save = proc(); + SlConditionallySaveCompletion(state, save); + return save; +} + struct SlLoadFromBufferState { size_t old_obj_len; byte *old_bufp; diff --git a/src/sl/saveload_buffer.h b/src/sl/saveload_buffer.h index 6148fd13f9..45946441da 100644 --- a/src/sl/saveload_buffer.h +++ b/src/sl/saveload_buffer.h @@ -259,6 +259,7 @@ struct MemoryDumper { size_t GetSize() const; void StartAutoLength(); std::pair StopAutoLength(); + bool IsAutoLengthActive() const { return this->saved_buf != nullptr; } }; #endif /* SL_SAVELOAD_BUFFER_H */