diff options
author | Darkvater <darkvater@openttd.org> | 2006-11-21 16:54:16 +0000 |
---|---|---|
committer | Darkvater <darkvater@openttd.org> | 2006-11-21 16:54:16 +0000 |
commit | 4113d151cd9bca733171a7b07d99c7abe8e6914c (patch) | |
tree | c1ce3057af274253f84f6418f2d207d69b926f06 | |
parent | c5ea9b0824a07f81c697cb5d8852199c4107b844 (diff) | |
download | openttd-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.c | 78 | ||||
-rw-r--r-- | saveload.h | 4 |
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 */ |