Add support for save/loading std::strings.
This commit is contained in:
@@ -1078,6 +1078,18 @@ static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
|
|||||||
return min(strlen(ptr), length - 1);
|
return min(strlen(ptr), length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the gross length of the std::string that it
|
||||||
|
* will occupy in the savegame. This includes the real length,
|
||||||
|
* and the length that the index will occupy.
|
||||||
|
* @param str reference to the std::string
|
||||||
|
* @return return the gross length of the string
|
||||||
|
*/
|
||||||
|
static inline size_t SlCalcStdStrLen(const std::string &str)
|
||||||
|
{
|
||||||
|
return str.size() + SlGetArrayLength(str.size()); // also include the length of the index
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the gross length of the string that it
|
* Calculate the gross length of the string that it
|
||||||
* will occupy in the savegame. This includes the real length, returned
|
* will occupy in the savegame. This includes the real length, returned
|
||||||
@@ -1189,6 +1201,41 @@ static void SlString(void *ptr, size_t length, VarType conv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save/Load a std::string.
|
||||||
|
* @param ptr the std::string being manipulated
|
||||||
|
* @param conv must be SLE_FILE_STRING
|
||||||
|
*/
|
||||||
|
static void SlStdString(std::string &str, VarType conv)
|
||||||
|
{
|
||||||
|
switch (_sl.action) {
|
||||||
|
case SLA_SAVE: {
|
||||||
|
SlWriteArrayLength(str.size());
|
||||||
|
SlCopyBytes(const_cast<char *>(str.data()), str.size());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SLA_LOAD_CHECK:
|
||||||
|
case SLA_LOAD: {
|
||||||
|
size_t len = SlReadArrayLength();
|
||||||
|
str.resize(len);
|
||||||
|
SlCopyBytes(const_cast<char *>(str.c_str()), len);
|
||||||
|
|
||||||
|
StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK;
|
||||||
|
if ((conv & SLF_ALLOW_CONTROL) != 0) {
|
||||||
|
settings = settings | SVS_ALLOW_CONTROL_CODE;
|
||||||
|
}
|
||||||
|
if ((conv & SLF_ALLOW_NEWLINE) != 0) {
|
||||||
|
settings = settings | SVS_ALLOW_NEWLINE;
|
||||||
|
}
|
||||||
|
str_validate(str, settings);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SLA_PTRS: break;
|
||||||
|
case SLA_NULL: break;
|
||||||
|
default: NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the size in bytes of a certain type of atomic array
|
* Return the size in bytes of a certain type of atomic array
|
||||||
* @param length The length of the array counted in elements
|
* @param length The length of the array counted in elements
|
||||||
@@ -1491,6 +1538,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
|
|||||||
case SL_LST:
|
case SL_LST:
|
||||||
case SL_DEQ:
|
case SL_DEQ:
|
||||||
case SL_VEC:
|
case SL_VEC:
|
||||||
|
case SL_STDSTR:
|
||||||
/* CONDITIONAL saveload types depend on the savegame version */
|
/* CONDITIONAL saveload types depend on the savegame version */
|
||||||
if (!SlIsObjectValidInSavegame(sld)) break;
|
if (!SlIsObjectValidInSavegame(sld)) break;
|
||||||
|
|
||||||
@@ -1502,6 +1550,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
|
|||||||
case SL_LST: return SlCalcListLen<std::list<void *>>(GetVariableAddress(object, sld));
|
case SL_LST: return SlCalcListLen<std::list<void *>>(GetVariableAddress(object, sld));
|
||||||
case SL_DEQ: return SlCalcListLen<std::deque<void *>>(GetVariableAddress(object, sld));
|
case SL_DEQ: return SlCalcListLen<std::deque<void *>>(GetVariableAddress(object, sld));
|
||||||
case SL_VEC: return SlCalcListLen<std::vector<void *>>(GetVariableAddress(object, sld));
|
case SL_VEC: return SlCalcListLen<std::vector<void *>>(GetVariableAddress(object, sld));
|
||||||
|
case SL_STDSTR: return SlCalcStdStrLen(*static_cast<std::string *>(GetVariableAddress(object, sld)));
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1550,6 +1599,9 @@ static bool IsVariableSizeRight(const SaveLoad *sld)
|
|||||||
/* These should be pointer sized, or fixed array. */
|
/* These should be pointer sized, or fixed array. */
|
||||||
return sld->size == sizeof(void *) || sld->size == sld->length;
|
return sld->size == sizeof(void *) || sld->size == sld->length;
|
||||||
|
|
||||||
|
case SL_STDSTR:
|
||||||
|
return sld->size == sizeof(std::string);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1572,6 +1624,7 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
|
|||||||
case SL_LST:
|
case SL_LST:
|
||||||
case SL_DEQ:
|
case SL_DEQ:
|
||||||
case SL_VEC:
|
case SL_VEC:
|
||||||
|
case SL_STDSTR:
|
||||||
/* CONDITIONAL saveload types depend on the savegame version */
|
/* CONDITIONAL saveload types depend on the savegame version */
|
||||||
if (!SlIsObjectValidInSavegame(sld)) return false;
|
if (!SlIsObjectValidInSavegame(sld)) return false;
|
||||||
if (SlSkipVariableOnLoad(sld)) return false;
|
if (SlSkipVariableOnLoad(sld)) return false;
|
||||||
@@ -1601,6 +1654,7 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld)
|
|||||||
case SL_LST: SlList<std::list<void *>>(ptr, (SLRefType)conv); break;
|
case SL_LST: SlList<std::list<void *>>(ptr, (SLRefType)conv); break;
|
||||||
case SL_DEQ: SlList<std::deque<void *>>(ptr, (SLRefType)conv); break;
|
case SL_DEQ: SlList<std::deque<void *>>(ptr, (SLRefType)conv); break;
|
||||||
case SL_VEC: SlList<std::vector<void *>>(ptr, (SLRefType)conv); break;
|
case SL_VEC: SlList<std::vector<void *>>(ptr, (SLRefType)conv); break;
|
||||||
|
case SL_STDSTR: SlStdString(*static_cast<std::string *>(ptr), sld->conv); break;
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -207,6 +207,7 @@ enum SaveLoadTypes {
|
|||||||
SL_LST = 4, ///< Save/load a list.
|
SL_LST = 4, ///< Save/load a list.
|
||||||
SL_DEQ = 5, ///< Save/load a deque.
|
SL_DEQ = 5, ///< Save/load a deque.
|
||||||
SL_VEC = 6, ///< Save/load a vector.
|
SL_VEC = 6, ///< Save/load a vector.
|
||||||
|
SL_STDSTR = 7, ///< Save/load a std::string.
|
||||||
/* non-normal save-load types */
|
/* non-normal save-load types */
|
||||||
SL_WRITEBYTE = 8,
|
SL_WRITEBYTE = 8,
|
||||||
SL_VEH_INCLUDE = 9,
|
SL_VEH_INCLUDE = 9,
|
||||||
@@ -300,6 +301,18 @@ typedef SaveLoad SaveLoadGlobVarList;
|
|||||||
#define SLE_CONDSTR_X(base, variable, type, length, from, to, extver) SLE_GENERAL_X(SL_STR, base, variable, type, length, from, to, extver)
|
#define SLE_CONDSTR_X(base, variable, type, length, from, to, extver) SLE_GENERAL_X(SL_STR, base, variable, type, length, from, to, extver)
|
||||||
#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_CONDSTR_X(base, variable, type, length, from, to, SlXvFeatureTest())
|
#define SLE_CONDSTR(base, variable, type, length, from, to) SLE_CONDSTR_X(base, variable, type, length, from, to, SlXvFeatureTest())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage of a std::string in some savegame versions.
|
||||||
|
* @param base Name of the class or struct containing the string.
|
||||||
|
* @param variable Name of the variable in the class or struct referenced by \a base.
|
||||||
|
* @param type Storage of the data in memory and in the savegame.
|
||||||
|
* @param from First savegame version that has the string.
|
||||||
|
* @param to Last savegame version that has the string.
|
||||||
|
* @param extver SlXvFeatureTest to test (along with from and to) which savegames have the field
|
||||||
|
*/
|
||||||
|
#define SLE_CONDSTDSTR_X(base, variable, type, from, to, extver) SLE_GENERAL_X(SL_STDSTR, base, variable, type, 0, from, to, extver)
|
||||||
|
#define SLE_CONDSTDSTR(base, variable, type, from, to) SLE_CONDSTDSTR_X(base, variable, type, from, to, SlXvFeatureTest())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Storage of a list in some savegame versions.
|
* Storage of a list in some savegame versions.
|
||||||
* @param base Name of the class or struct containing the list.
|
* @param base Name of the class or struct containing the list.
|
||||||
@@ -370,6 +383,14 @@ typedef SaveLoad SaveLoadGlobVarList;
|
|||||||
*/
|
*/
|
||||||
#define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, 0, SL_MAX_VERSION)
|
#define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, 0, SL_MAX_VERSION)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage of a std::string in every savegame version.
|
||||||
|
* @param base Name of the class or struct containing the string.
|
||||||
|
* @param variable Name of the variable in the class or struct referenced by \a base.
|
||||||
|
* @param type Storage of the data in memory and in the savegame.
|
||||||
|
*/
|
||||||
|
#define SLE_STDSTR(base, variable, type) SLE_CONDSTDSTR(base, variable, type, 0, SL_MAX_VERSION)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Storage of a list in every savegame version.
|
* Storage of a list in every savegame version.
|
||||||
* @param base Name of the class or struct containing the list.
|
* @param base Name of the class or struct containing the list.
|
||||||
|
@@ -180,14 +180,7 @@ void str_fix_scc_encoded(char *str, const char *last)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
char *str_validate_intl(char *str, const char *last, StringValidationSettings settings)
|
||||||
* Scans the string for valid characters and if it finds invalid ones,
|
|
||||||
* replaces them with a question mark '?' (if not ignored)
|
|
||||||
* @param str the string to validate
|
|
||||||
* @param last the last valid character of str
|
|
||||||
* @param settings the settings for the string validation.
|
|
||||||
*/
|
|
||||||
void str_validate(char *str, const char *last, StringValidationSettings settings)
|
|
||||||
{
|
{
|
||||||
/* Assume the ABSOLUTE WORST to be in str as it comes from the outside. */
|
/* Assume the ABSOLUTE WORST to be in str as it comes from the outside. */
|
||||||
|
|
||||||
@@ -228,7 +221,7 @@ void str_validate(char *str, const char *last, StringValidationSettings settings
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*dst = '\0';
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#define STRING_FUNC_H
|
#define STRING_FUNC_H
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "core/bitmath_func.hpp"
|
#include "core/bitmath_func.hpp"
|
||||||
#include "string_type.h"
|
#include "string_type.h"
|
||||||
@@ -41,7 +42,27 @@ int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap)
|
|||||||
char *CDECL str_fmt(const char *str, ...) WARN_FORMAT(1, 2);
|
char *CDECL str_fmt(const char *str, ...) WARN_FORMAT(1, 2);
|
||||||
char *str_vfmt(const char *str, va_list ap);
|
char *str_vfmt(const char *str, va_list ap);
|
||||||
|
|
||||||
void str_validate(char *str, const char *last, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
|
char *str_validate_intl(char *str, const char *last, StringValidationSettings settings);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans the string for valid characters and if it finds invalid ones,
|
||||||
|
* replaces them with a question mark '?' (if not ignored)
|
||||||
|
* @param str the string to validate
|
||||||
|
* @param last the last valid character of str
|
||||||
|
* @param settings the settings for the string validation.
|
||||||
|
*/
|
||||||
|
static inline void str_validate(char *str, const char *last, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK)
|
||||||
|
{
|
||||||
|
*str_validate_intl(str, last, settings) = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void str_validate(std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK)
|
||||||
|
{
|
||||||
|
if (str.empty()) return;
|
||||||
|
char *buf = const_cast<char *>(str.c_str());
|
||||||
|
str.resize(str_validate_intl(buf, buf + str.size(), settings) - buf);
|
||||||
|
}
|
||||||
|
|
||||||
void ValidateString(const char *str);
|
void ValidateString(const char *str);
|
||||||
|
|
||||||
void str_fix_scc_encoded(char *str, const char *last);
|
void str_fix_scc_encoded(char *str, const char *last);
|
||||||
|
Reference in New Issue
Block a user