summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarkvater <darkvater@openttd.org>2006-11-21 20:23:57 +0000
committerDarkvater <darkvater@openttd.org>2006-11-21 20:23:57 +0000
commitdf54f52e20f91953d33ddc1c38929c67acaa86dc (patch)
tree5cf07a8e7335d947c4bbb671d2c6842acfe4e99d
parent2a91c8d723ae2e9a71d964b35977799f3134fe84 (diff)
downloadopenttd-df54f52e20f91953d33ddc1c38929c67acaa86dc.tar.xz
(svn r7232) -Codechange: Also allow for the save/load of non pre-allocated strings inside structs.
-rw-r--r--saveload.c42
-rw-r--r--saveload.h2
-rw-r--r--settings.c3
3 files changed, 30 insertions, 17 deletions
diff --git a/saveload.c b/saveload.c
index 9383b55f9..00df02bdb 100644
--- a/saveload.c
+++ b/saveload.c
@@ -487,7 +487,8 @@ static void SlSaveLoadConv(void *ptr, VarType conv)
* just strlen(), but if the string is not properly terminated, we'll
* resort to the maximum length of the buffer.
* @param ptr pointer to the stringbuffer
- * @param length maximum length of the string (buffer)
+ * @param length maximum length of the string (buffer). If -1 we don't care
+ * about a maximum length, but take string length as it is.
* @return return the net length of the string */
static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
{
@@ -505,10 +506,21 @@ static inline size_t SlCalcStringLen(const void *ptr, size_t length, VarType con
size_t len;
const char *str;
- conv = GetVarMemType(conv);
- /* For strings without a pre-allocated buffer, we need an extra indirection of course */
- str = (conv == SLE_VAR_STR || conv == SLE_VAR_STRQ) ? *(const char**)ptr : (const char*)ptr;
- len = SlCalcNetStringLen(str, length);
+ switch (GetVarMemType(conv)) {
+ default: NOT_REACHED();
+ case SLE_VAR_STR:
+ case SLE_VAR_STRQ:
+ str = *(const char**)ptr;
+ len = -1;
+ break;
+ case SLE_VAR_STRB:
+ case SLE_VAR_STRBQ:
+ str = (const char*)ptr;
+ len = length;
+ break;
+ }
+
+ len = SlCalcNetStringLen(str, len);
return len + SlGetArrayLength(len); // also include the length of the index
}
@@ -523,6 +535,7 @@ static void SlString(void *ptr, size_t length, VarType conv)
if (_sl.save) { /* SAVE string */
switch (GetVarMemType(conv)) {
+ default: NOT_REACHED();
case SLE_VAR_STRB:
case SLE_VAR_STRBQ:
len = SlCalcNetStringLen(ptr, length);
@@ -530,9 +543,8 @@ static void SlString(void *ptr, size_t length, VarType conv)
case SLE_VAR_STR:
case SLE_VAR_STRQ:
ptr = *(char**)ptr;
- len = SlCalcNetStringLen(ptr, 0);
+ len = SlCalcNetStringLen(ptr, -1);
break;
- default: NOT_REACHED();
}
SlWriteArrayLength(len);
@@ -541,6 +553,7 @@ static void SlString(void *ptr, size_t length, VarType conv)
len = SlReadArrayLength();
switch (GetVarMemType(conv)) {
+ default: NOT_REACHED();
case SLE_VAR_STRB:
case SLE_VAR_STRBQ:
if (len >= length) {
@@ -559,7 +572,6 @@ static void SlString(void *ptr, size_t length, VarType conv)
ptr = *(char**)ptr;
SlCopyBytes(ptr, len);
break;
- default: NOT_REACHED();
}
((char*)ptr)[len] = '\0'; // properly terminate the string
@@ -642,18 +654,18 @@ static inline bool SlSkipVariableOnLoad(const SaveLoad *sld)
* Calculate the size of an object.
* @param sld The @SaveLoad description of the object so we know how to manipulate it
*/
-static size_t SlCalcObjLength(const SaveLoad *sld)
+static size_t SlCalcObjLength(const void *object, const SaveLoad *sld)
{
size_t length = 0;
// Need to determine the length and write a length tag.
for (; sld->cmd != SL_END; sld++) {
- length += SlCalcObjMemberLength(sld);
+ length += SlCalcObjMemberLength(object, sld);
}
return length;
}
-size_t SlCalcObjMemberLength(const SaveLoad *sld)
+size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
{
assert(_sl.save);
@@ -669,12 +681,12 @@ size_t SlCalcObjMemberLength(const SaveLoad *sld)
case SL_VAR: return SlCalcConvFileLen(sld->conv);
case SL_REF: return SlCalcRefLen();
case SL_ARR: return SlCalcArrayLen(sld->length, sld->conv);
- case SL_STR: return SlCalcStringLen(sld->address, sld->length, sld->conv);
+ case SL_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv);
default: NOT_REACHED();
}
break;
case SL_WRITEBYTE: return 1; // a byte is logically of size 1
- case SL_INCLUDE: return SlCalcObjLength(_sl.includes[sld->version_from]);
+ case SL_INCLUDE: return SlCalcObjLength(object, _sl.includes[sld->version_from]);
default: NOT_REACHED();
}
return 0;
@@ -746,7 +758,7 @@ void SlObject(void *object, const SaveLoad *sld)
{
// Automatically calculate the length?
if (_sl.need_length != NL_NONE) {
- SlSetLength(SlCalcObjLength(sld));
+ SlSetLength(SlCalcObjLength(object, sld));
if (_sl.need_length == NL_CALCLENGTH) return;
}
@@ -763,7 +775,7 @@ void SlObject(void *object, const SaveLoad *sld)
void SlGlobList(const SaveLoadGlobVarList *sldg)
{
if (_sl.need_length != NL_NONE) {
- SlSetLength(SlCalcObjLength((const SaveLoad*)sldg));
+ SlSetLength(SlCalcObjLength(NULL, (const SaveLoad*)sldg));
if (_sl.need_length == NL_CALCLENGTH) return;
}
diff --git a/saveload.h b/saveload.h
index 56c3a314d..5d490b35a 100644
--- a/saveload.h
+++ b/saveload.h
@@ -289,7 +289,7 @@ int SlIterateArray(void);
void SlAutolength(AutolengthProc *proc, void *arg);
uint SlGetFieldLength(void);
void SlSetLength(size_t length);
-size_t SlCalcObjMemberLength(const SaveLoad *sld);
+size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld);
byte SlReadByte(void);
void SlWriteByte(byte b);
diff --git a/settings.c b/settings.c
index 2672f202a..4e94a97e6 100644
--- a/settings.c
+++ b/settings.c
@@ -1717,7 +1717,8 @@ static void SaveSettings(const SettingDesc *sd, void *object)
const SettingDesc *i;
size_t length = 0;
for (i = sd; i->save.cmd != SL_END; i++) {
- length += SlCalcObjMemberLength(&i->save);
+ const void *ptr = GetVariableAddress(object, &i->save);
+ length += SlCalcObjMemberLength(ptr, &i->save);
}
SlSetLength(length);