(svn r7228) -Codechange: [internal] Add the possibility to save/load string-pointers which do not
authorDarkvater
Tue, 21 Nov 2006 16:54:16 +0000
changeset 5140 b1097c36a598
parent 5139 7bdb1b79daa5
child 5141 63e24cb6f071
(svn r7228) -Codechange: [internal] Add the possibility to save/load string-pointers which do not
have a pre-allocated buffer.
saveload.c
saveload.h
--- a/saveload.c	Tue Nov 21 16:24:13 2006 +0000
+++ b/saveload.c	Tue Nov 21 16:54:16 2006 +0000
@@ -489,7 +489,7 @@
  * @param ptr pointer to the stringbuffer
  * @param length maximum length of the string (buffer)
  * @return return the net length of the string */
-static inline size_t SlCalcNetStringLen(const char *ptr, uint length)
+static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
 {
 	return minu(strlen(ptr), length - 1);
 }
@@ -500,9 +500,15 @@
  * @param ptr pointer to the stringbuffer
  * @param length maximum length of the string (buffer size, etc.)
  * @return return the gross length of the string */
-static inline size_t SlCalcStringLen(const char *ptr, uint length)
+static inline size_t SlCalcStringLen(const void *ptr, size_t length, VarType conv)
 {
-	uint len = SlCalcNetStringLen(ptr, length);
+	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);
 	return len + SlGetArrayLength(len); // also include the length of the index
 }
 
@@ -510,34 +516,54 @@
  * Save/Load a string.
  * @param ptr the string being manipulated
  * @param the length of the string (full length)
- * @param conv must be SLE_FILE_STRING
- * XXX - only works with global strings of a pre-allocated buffer */
-static void SlString(void *ptr, uint length, VarType conv)
+ * @param conv must be SLE_FILE_STRING */
+static void SlString(void *ptr, size_t length, VarType conv)
 {
-	uint len;
-	assert(GetVarFileType(conv) == SLE_FILE_STRING);
-	assert(GetVarMemType(conv) == SLE_VAR_STRB || GetVarMemType(conv) == SLE_VAR_STRBQ);
-	assert(ptr != NULL);
+	size_t len;
 
-	if (_sl.save) {
-		len = SlCalcNetStringLen(ptr, length);
+	if (_sl.save) { /* SAVE string */
+		switch (GetVarMemType(conv)) {
+			case SLE_VAR_STRB:
+			case SLE_VAR_STRBQ:
+				len = SlCalcNetStringLen(ptr, length);
+				break;
+			case SLE_VAR_STR:
+			case SLE_VAR_STRQ:
+				ptr = *(char**)ptr;
+				len = SlCalcNetStringLen(ptr, 0);
+				break;
+			default: NOT_REACHED();
+		}
+
 		SlWriteArrayLength(len);
 		SlCopyBytes(ptr, len);
-		return;
-	}
-
-	len = SlReadArrayLength();
+	} else { /* LOAD string */
+		len = SlReadArrayLength();
 
-	if (len >= length) {
-		DEBUG(misc, 0) ("[Sl] String length in savegame is bigger than buffer, truncating");
-		SlCopyBytes(ptr, length);
-		SlSkipBytes(len - length);
-		len = length - 1;
-	} else {
-		SlCopyBytes(ptr, len);
+		switch (GetVarMemType(conv)) {
+			case SLE_VAR_STRB:
+			case SLE_VAR_STRBQ:
+				if (len >= length) {
+					DEBUG(misc, 0) ("[Sl] String length in savegame is bigger than buffer, truncating");
+					SlCopyBytes(ptr, length);
+					SlSkipBytes(len - length);
+					len = length - 1;
+				} else {
+					SlCopyBytes(ptr, len);
+				}
+				break;
+			case SLE_VAR_STR:
+			case SLE_VAR_STRQ: /* Malloc'd string, free previous incarnation, and allocate */
+				free(*(char**)ptr);
+				*(char**)ptr = malloc(len + 1); // terminating '\0'
+				ptr = *(char**)ptr;
+				SlCopyBytes(ptr, len);
+				break;
+			default: NOT_REACHED();
+		}
+
+		((char*)ptr)[len] = '\0'; // properly terminate the string
 	}
-
-	((char*)ptr)[len] = '\0'; // properly terminate the string
 }
 
 /**
@@ -643,7 +669,7 @@
 			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);
+			case SL_STR: return SlCalcStringLen(sld->address, sld->length, sld->conv);
 			default: NOT_REACHED();
 			}
 			break;
--- a/saveload.h	Tue Nov 21 16:24:13 2006 +0000
+++ b/saveload.h	Tue Nov 21 16:54:16 2006 +0000
@@ -100,10 +100,10 @@
 	SLE_VAR_I64   =  7 << 4,
 	SLE_VAR_U64   =  8 << 4,
 	SLE_VAR_NULL  =  9 << 4, ///< useful to write zeros in savegame.
-	SLE_VAR_STRB  = 10 << 4, ///< normal string (with pre-allocated buffer)
+	SLE_VAR_STRB  = 10 << 4, ///< string (with pre-allocated buffer)
 	SLE_VAR_STRBQ = 11 << 4, ///< string enclosed in quotes (with pre-allocated buffer)
 	SLE_VAR_STR   = 12 << 4, ///< string pointer
-	SLE_VAR_STRQ  = 13 << 4, ///< string enclosed in quotes
+	SLE_VAR_STRQ  = 13 << 4, ///< string pointer enclosed in quotes
 	/* 2 more possible memory-primitives */
 
 	/* Shortcut values */