[Scummvm-cvs-logs] scummvm master -> 023914d12166ea4af6e23685f96371f769cb0255

wjp wjp at usecode.org
Thu Sep 5 22:49:09 CEST 2013


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
023914d121 WINTERMUTE: Disambiguate empty and NULL strings when saving


Commit: 023914d12166ea4af6e23685f96371f769cb0255
    https://github.com/scummvm/scummvm/commit/023914d12166ea4af6e23685f96371f769cb0255
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2013-09-05T13:12:49-07:00

Commit Message:
WINTERMUTE: Disambiguate empty and NULL strings when saving

The string stored is now strlen(s)+1, with length 0 indicating NULL.

Increment savegame version for this new format.

Old savegames are fixed by assuming VAL_STRING should never be NULL.

Changed paths:
    engines/wintermute/base/base_persistence_manager.cpp
    engines/wintermute/base/base_persistence_manager.h
    engines/wintermute/base/scriptables/script_value.cpp
    engines/wintermute/dcgf.h



diff --git a/engines/wintermute/base/base_persistence_manager.cpp b/engines/wintermute/base/base_persistence_manager.cpp
index 2e2726f..e5542d9 100644
--- a/engines/wintermute/base/base_persistence_manager.cpp
+++ b/engines/wintermute/base/base_persistence_manager.cpp
@@ -465,44 +465,53 @@ uint32 BasePersistenceManager::getDWORD() {
 
 
 //////////////////////////////////////////////////////////////////////////
-void BasePersistenceManager::putString(const Common::String &val) {
-	if (!val.size()) {
-		putString("(null)");
-	} else {
-		_saveStream->writeUint32LE(val.size());
-		_saveStream->writeString(val);
+void BasePersistenceManager::putString(const char *val) {
+	if (!val) {
+		_saveStream->writeUint32LE(0);
+		return;
 	}
-}
-
-Common::String BasePersistenceManager::getStringObj() {
-	uint32 len = _loadStream->readUint32LE();
-	char *ret = new char[len + 1];
-	_loadStream->read(ret, len);
-	ret[len] = '\0';
 
-	Common::String retString = ret;
-	delete[] ret;
+	uint32 len = strlen(val);
 
-	if (retString == "(null)") {
-		retString = "";
-	}
+	_saveStream->writeUint32LE(len + 1);
+	_saveStream->write(val, len);
+}
 
-	return retString;
+Common::String BasePersistenceManager::getStringObj() {
+	return getString();
 }
 
 //////////////////////////////////////////////////////////////////////////
 char *BasePersistenceManager::getString() {
 	uint32 len = _loadStream->readUint32LE();
-	char *ret = new char[len + 1];
-	_loadStream->read(ret, len);
-	ret[len] = '\0';
 
-	if (!strcmp(ret, "(null)")) {
-		delete[] ret;
-		return nullptr;
+	if (checkVersion(1,2,2)) {
+		// Version 1.2.2 and above: len == strlen() + 1, NULL has len == 0
+
+		if (len == 0)
+			return nullptr;
+
+		char *ret = new char[len];
+		_loadStream->read(ret, len - 1);
+		ret[len - 1] = '\0';
+
+		return ret;
+
 	} else {
+
+		// Version 1.2.1 and older: NULL strings are represented as "(null)"
+		char *ret = new char[len + 1];
+		_loadStream->read(ret, len);
+		ret[len] = '\0';
+
+		if (!strcmp(ret, "(null)")) {
+			delete[] ret;
+			return nullptr;
+		}
+
 		return ret;
 	}
+
 }
 
 bool BasePersistenceManager::putTimeDate(const TimeDate &t) {
@@ -536,8 +545,7 @@ void BasePersistenceManager::putFloat(float val) {
 	int exponent = 0;
 	float significand = frexp(val, &exponent);
 	Common::String str = Common::String::format("FS%f", significand);
-	_saveStream->writeUint32LE(str.size());
-	_saveStream->writeString(str);
+	putString(str.c_str());
 	_saveStream->writeSint32LE(exponent);
 }
 
@@ -559,8 +567,7 @@ void BasePersistenceManager::putDouble(double val) {
 	int exponent = 0;
 	double significand = frexp(val, &exponent);
 	Common::String str = Common::String::format("DS%f", significand);
-	_saveStream->writeUint32LE(str.size());
-	_saveStream->writeString(str);
+	putString(str.c_str());
 	_saveStream->writeSint32LE(exponent);
 }
 
@@ -711,7 +718,7 @@ bool BasePersistenceManager::transfer(const char *name, const char **val) {
 // Common::String
 bool BasePersistenceManager::transfer(const char *name, Common::String *val) {
 	if (_saving) {
-		putString(*val);
+		putString(val->c_str());
 		return STATUS_OK;
 	} else {
 		char *str = getString();
diff --git a/engines/wintermute/base/base_persistence_manager.h b/engines/wintermute/base/base_persistence_manager.h
index c09b334..3c0587b 100644
--- a/engines/wintermute/base/base_persistence_manager.h
+++ b/engines/wintermute/base/base_persistence_manager.h
@@ -52,7 +52,7 @@ public:
 	void putDWORD(uint32 val);
 	char *getString();
 	Common::String getStringObj();
-	void putString(const Common::String &val);
+	void putString(const char *val);
 	float getFloat();
 	void putFloat(float val);
 	double getDouble();
diff --git a/engines/wintermute/base/scriptables/script_value.cpp b/engines/wintermute/base/scriptables/script_value.cpp
index 3532e12..31ec457 100644
--- a/engines/wintermute/base/scriptables/script_value.cpp
+++ b/engines/wintermute/base/scriptables/script_value.cpp
@@ -827,6 +827,17 @@ bool ScValue::persist(BasePersistenceManager *persistMgr) {
 	persistMgr->transferPtr(TMEMBER_PTR(_valRef));
 	persistMgr->transfer(TMEMBER(_valString));
 
+	if (!persistMgr->getIsSaving() && !persistMgr->checkVersion(1,2,2)) {
+		// Savegames prior to 1.2.2 stored empty strings as NULL.
+		// We disambiguate those by turning NULL strings into empty
+		// strings if _type is VAL_STRING instead of VAL_NULL.
+
+		if (_type == VAL_STRING && !_valString) {
+			_valString = new char[1];
+			_valString[0] = '\0';
+		}
+	}
+
 	/* // TODO: Convert to Debug-statements.
 	FILE* f = fopen("c:\\val.log", "a+");
 	switch(_type)
diff --git a/engines/wintermute/dcgf.h b/engines/wintermute/dcgf.h
index fe92194..3db4439 100644
--- a/engines/wintermute/dcgf.h
+++ b/engines/wintermute/dcgf.h
@@ -33,7 +33,7 @@
 //////////////////////////////////////////////////////////////////////////
 #define DCGF_VER_MAJOR 1
 #define DCGF_VER_MINOR 2
-#define DCGF_VER_BUILD 1
+#define DCGF_VER_BUILD 2
 #define DCGF_VER_SUFFIX "ScummVM"
 #define DCGF_VER_BETA true
 






More information about the Scummvm-git-logs mailing list