changeset 5142:4ccfecbb45a6 draft

(svn r7232) -Codechange: Also allow for the save/load of non pre-allocated strings inside structs.
author Darkvater <Darkvater@openttd.org>
date Tue, 21 Nov 2006 20:23:57 +0000
parents 06642d64ce3a
children 0b23de6f5589
files saveload.c saveload.h settings.c
diffstat 3 files changed, 30 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/saveload.c
+++ b/saveload.c
@@ -487,7 +487,8 @@
  * 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 @@
 	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 @@
 
 	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 @@
 			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 @@
 		len = SlReadArrayLength();
 
 		switch (GetVarMemType(conv)) {
+			default: NOT_REACHED();
 			case SLE_VAR_STRB:
 			case SLE_VAR_STRBQ:
 				if (len >= length) {
@@ -559,7 +572,6 @@
 				ptr = *(char**)ptr;
 				SlCopyBytes(ptr, len);
 				break;
-			default: NOT_REACHED();
 		}
 
 		((char*)ptr)[len] = '\0'; // properly terminate the string
@@ -642,18 +654,18 @@
  * 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 @@
 			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 @@
 {
 	// 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 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;
 	}
 
--- a/saveload.h
+++ b/saveload.h
@@ -289,7 +289,7 @@
 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);
--- a/settings.c
+++ b/settings.c
@@ -1717,7 +1717,8 @@
 	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);