summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarkvater <darkvater@openttd.org>2006-11-21 16:54:16 +0000
committerDarkvater <darkvater@openttd.org>2006-11-21 16:54:16 +0000
commit4113d151cd9bca733171a7b07d99c7abe8e6914c (patch)
treec1ce3057af274253f84f6418f2d207d69b926f06
parentc5ea9b0824a07f81c697cb5d8852199c4107b844 (diff)
downloadopenttd-4113d151cd9bca733171a7b07d99c7abe8e6914c.tar.xz
(svn r7228) -Codechange: [internal] Add the possibility to save/load string-pointers which do not
have a pre-allocated buffer.
-rw-r--r--saveload.c78
-rw-r--r--saveload.h4
2 files changed, 54 insertions, 28 deletions
diff --git a/saveload.c b/saveload.c
index 21e537084..433229a72 100644
--- a/saveload.c
+++ b/saveload.c
@@ -489,7 +489,7 @@ static void SlSaveLoadConv(void *ptr, VarType conv)
* @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 @@ static inline size_t SlCalcNetStringLen(const char *ptr, uint length)
* @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 @@ static inline size_t SlCalcStringLen(const char *ptr, uint length)
* 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) { /* 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();
+ }
- if (_sl.save) {
- len = SlCalcNetStringLen(ptr, length);
SlWriteArrayLength(len);
SlCopyBytes(ptr, len);
- return;
- }
-
- len = SlReadArrayLength();
+ } else { /* LOAD string */
+ len = SlReadArrayLength();
+
+ 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();
+ }
- 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);
+ ((char*)ptr)[len] = '\0'; // properly terminate the string
}
-
- ((char*)ptr)[len] = '\0'; // properly terminate the string
}
/**
@@ -643,7 +669,7 @@ 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);
+ case SL_STR: return SlCalcStringLen(sld->address, sld->length, sld->conv);
default: NOT_REACHED();
}
break;
diff --git a/saveload.h b/saveload.h
index bdd2de489..3a0a59010 100644
--- a/saveload.h
+++ b/saveload.h
@@ -100,10 +100,10 @@ enum VarTypes {
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 */