diff --git a/src/sl/company_sl.cpp b/src/sl/company_sl.cpp index 5a6bb6d970..2f91742eb8 100644 --- a/src/sl/company_sl.cpp +++ b/src/sl/company_sl.cpp @@ -659,7 +659,7 @@ static void Save_PLYP() return; } - std::vector buffer = SlSaveToVector([](void *) { + std::vector buffer = SlSaveToVector([]() { SlWriteUint32((uint32)_network_company_server_id.size()); MemoryDumper::GetCurrent()->CopyBytes((const uint8 *)_network_company_server_id.data(), _network_company_server_id.size()); @@ -681,7 +681,7 @@ static void Save_PLYP() } else { SlWriteByte(0); } - }, nullptr); + }); uint8 mac[16]; /* Message authentication code */ diff --git a/src/sl/saveload.cpp b/src/sl/saveload.cpp index aaa9f153b3..ebb682df4f 100644 --- a/src/sl/saveload.cpp +++ b/src/sl/saveload.cpp @@ -2052,23 +2052,25 @@ void SlAutolength(AutolengthProc *proc, void *arg) _sl.dumper->CopyBytes(result.first, result.second); } -/** - * Run proc, saving result to a std::vector - * @param proc The callback procedure that is called - * @param arg The variable that will be used for the callback procedure - */ -std::vector SlSaveToVector(AutolengthProc *proc, void *arg) +uint8 SlSaveToTempBufferSetup() { assert(_sl.action == SLA_SAVE); NeedLength orig_need_length = _sl.need_length; _sl.need_length = NL_NONE; _sl.dumper->StartAutoLength(); - proc(arg); + + return (uint8) orig_need_length; +} + +std::pair SlSaveToTempBufferRestore(uint8 state) +{ + NeedLength orig_need_length = (NeedLength)state; + auto result = _sl.dumper->StopAutoLength(); /* Setup length */ _sl.need_length = orig_need_length; - return std::vector(result.first, result.first + result.second); + return result; } SlLoadFromBufferState SlLoadFromBufferSetup(const byte *buffer, size_t length) diff --git a/src/sl/saveload.h b/src/sl/saveload.h index f4da1c19bf..af0dad002f 100644 --- a/src/sl/saveload.h +++ b/src/sl/saveload.h @@ -712,12 +712,41 @@ void SlSetArrayIndex(uint index); int SlIterateArray(); void SlAutolength(AutolengthProc *proc, void *arg); -std::vector SlSaveToVector(AutolengthProc *proc, void *arg); size_t SlGetFieldLength(); void SlSetLength(size_t length); size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld); size_t SlCalcObjLength(const void *object, const SaveLoadTable &slt); +/** + * Run proc, saving result in the autolength temp buffer + * @param proc The callback procedure that is called + * @return Span of the saved data, in the autolength temp buffer + */ +template +span SlSaveToTempBuffer(F proc) +{ + extern uint8 SlSaveToTempBufferSetup(); + extern std::pair SlSaveToTempBufferRestore(uint8 state); + + uint8 state = SlSaveToTempBufferSetup(); + proc(); + auto result = SlSaveToTempBufferRestore(state); + return span(result.first, result.second); +} + +/** + * Run proc, saving result to a std::vector + * This is implemented in terms of SlSaveToTempBuffer + * @param proc The callback procedure that is called + * @return a vector containing the saved data + */ +template +std::vector SlSaveToVector(F proc) +{ + span result = SlSaveToTempBuffer(proc); + return std::vector(result.begin(), result.end()); +} + struct SlLoadFromBufferState { size_t old_obj_len; byte *old_bufp;