Index: cpp/common/util-file.cpp
===================================================================
--- cpp/common/util-file.cpp	(revision 1330)
+++ cpp/common/util-file.cpp	(revision 1331)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2021  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2024  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -19,12 +19,12 @@
 #ifdef USE_VIRTFILE
 #ifdef DEBUGGING_READWRITECOMPLETEFILE
-	logPrintf("","readCompleteFile",LOG_DEBUG,"virtfile: '%s'",filename);
+	logPrintf("", "readCompleteFile", LOG_DEBUG, "virtfile: '%s'", filename);
 #endif	
-//	if (!isAbsolutePath(filename))
+	//	if (!isAbsolutePath(filename))
 	{
-		VirtFILE *f=Vfopen(filename,FOPEN_READ_BINARY);
+		VirtFILE *f = Vfopen(filename, FOPEN_READ_BINARY);
 		if (f)
 		{
-			int size=f->getSize();
+			int size = f->getSize();
 			data.resize(size);
 			int przeczytane = (int)f->Vread(&data[0], size, 1);
@@ -33,16 +33,16 @@
 		}
 	}
-//	else
+	//	else
 #endif
 	{
 #ifdef DEBUGGING_READWRITECOMPLETEFILE
-	if (isAbsolutePath(filename))
-		logPrintf("","readCompleteFile",LOG_DEBUG,"mfopen absolute path: '%s'",filename);
-	else
-		logPrintf("","readCompleteFile",LOG_DEBUG,"mfopen: '%s' in current dir: '%s'",filename,getCurrentDirectory().c_str());
+		if (isAbsolutePath(filename))
+			logPrintf("", "readCompleteFile", LOG_DEBUG, "mfopen absolute path: '%s'", filename);
+		else
+			logPrintf("", "readCompleteFile", LOG_DEBUG, "mfopen: '%s' in current dir: '%s'", filename, getCurrentDirectory().c_str());
 #endif	
 		MFILE *f = mfopen(filename, FOPEN_READ_BINARY);
 #ifdef DEBUGGING_READWRITECOMPLETEFILE
-	logPrintf("", "readCompleteFile", LOG_DEBUG, "mfopen status: %s", f?"ok":"fail");
+		logPrintf("", "readCompleteFile", LOG_DEBUG, "mfopen status: %s", f ? "ok" : "fail");
 #endif
 		if (f)
@@ -58,5 +58,5 @@
 		logPrintf("", "readCompleteFile", LOG_WARN, "Couldn't open file '%s'", filename);
 #ifdef DEBUGGING_READWRITECOMPLETEFILE
-	logPrintf("", "readCompleteFile", LOG_DEBUG, "bytes:%d status: %s", data.size(), ok?"ok":"fail");
+	logPrintf("", "readCompleteFile", LOG_DEBUG, "bytes:%d status: %s", data.size(), ok ? "ok" : "fail");
 #endif
 	return ok;
@@ -74,9 +74,9 @@
 }
 
-bool writeCompleteFile(const char* filename, const string& text, bool warn_on_fail)
+bool writeCompleteFile(const char* filename, const span<char>& data, bool warn_on_fail)
 {
 #ifdef USE_VIRTFILE
 #ifdef DEBUGGING_READWRITECOMPLETEFILE
-	logPrintf("","writeCompleteFile",LOG_DEBUG,"virtfile: '%s'",filename);
+	logPrintf("", "writeCompleteFile", LOG_DEBUG, "virtfile: '%s'", filename);
 #endif	
 	VirtFILE *f = Vfopen(filename, FOPEN_WRITE_BINARY);
@@ -84,5 +84,5 @@
 	if (f)
 	{
-		int zapisane = (int)f->Vwrite(text.c_str(), text.length(), 1);
+		int zapisane = data.size() > 0 ? (int)f->Vwrite(data.begin(), data.size(), 1) : 1; //size()==0 is a special case (creating an empty file)
 		delete f;
 		ok &= (zapisane == 1);
@@ -91,16 +91,16 @@
 #ifdef DEBUGGING_READWRITECOMPLETEFILE
 	if (isAbsolutePath(filename))
-		logPrintf("","writeCompleteFile",LOG_DEBUG,"mfopen absolute path: '%s'",filename);
+		logPrintf("", "writeCompleteFile", LOG_DEBUG, "mfopen absolute path: '%s'", filename);
 	else
-		logPrintf("","writeCompleteFile",LOG_DEBUG,"mfopen: '%s' in current dir: '%s'",filename,getCurrentDirectory().c_str());
+		logPrintf("", "writeCompleteFile", LOG_DEBUG, "mfopen: '%s' in current dir: '%s'", filename, getCurrentDirectory().c_str());
 #endif
 	MFILE *f = mfopen(filename, FOPEN_WRITE_BINARY);
 	bool ok = f != NULL;
 #ifdef DEBUGGING_READWRITECOMPLETEFILE
-	logPrintf("", "writeCompleteFile", LOG_DEBUG, "mfopen status: %s", ok?"ok":"fail");
+	logPrintf("", "writeCompleteFile", LOG_DEBUG, "mfopen status: %s", ok ? "ok" : "fail");
 #endif
 	if (f)
 	{
-		int zapisane = (int)mfwrite(text.c_str(), text.length(), 1, f);
+		int zapisane = data.size() > 0 ? (int)mfwrite(data.begin(), data.size(), 1, f) : 1; //size()==0 is a special case (creating an empty file)
 		mfclose(f);
 		ok &= (zapisane == 1);
@@ -110,14 +110,24 @@
 		logPrintf("", "writeCompleteFile", LOG_WARN, "Couldn't write file '%s'", filename);
 #ifdef DEBUGGING_READWRITECOMPLETEFILE
-	logPrintf("", "writeCompleteFile", LOG_DEBUG, "status: %s", ok?"ok":"fail");
+	logPrintf("", "writeCompleteFile", LOG_DEBUG, "status: %s", ok ? "ok" : "fail");
 #endif
 	return ok;
 }
 
-bool writeCompleteFile(const char* filename, vector<char>& data, bool warn_on_fail)
+bool writeCompleteFile(const char* filename, const span<uint8_t>& data, bool warn_on_fail)
 {
-	string s(&data[0], data.size());
-	return writeCompleteFile(filename, s, warn_on_fail);
+	return writeCompleteFile(filename, span<char>((char*)&data[0], data.size()), warn_on_fail);
 }
+
+bool writeCompleteFile(const char* filename, const vector<char>& data, bool warn_on_fail)
+{
+	return writeCompleteFile(filename, span<char>((char*)&data[0], data.size()), warn_on_fail);
+}
+
+bool writeCompleteFile(const char* filename, const string& text, bool warn_on_fail)
+{
+	return writeCompleteFile(filename, span<char>((char*)text.c_str(), text.size()), warn_on_fail);
+}
+
 
 // Just like fgets(), but string length is unlimited and does not store trailing \r \n
@@ -134,9 +144,9 @@
 	while ((line =
 #ifdef USE_VIRTFILE
-            f->Vgets(buf, sizeof(buf))
+		f->Vgets(buf, sizeof(buf))
 #else
-            fgets(buf, sizeof(buf), f)
+		fgets(buf, sizeof(buf), f)
 #endif
-            ))
+		))
 	{
 		char* end = line + strlen(line);
Index: cpp/common/util-file.h
===================================================================
--- cpp/common/util-file.h	(revision 1330)
+++ cpp/common/util-file.h	(revision 1331)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2021  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2024  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -12,9 +12,12 @@
 #include <stdio.h>
 #endif
+#include <common/nonstd_span.h>
 
 bool readCompleteFile(const char* filename, vector<char>& data, bool warn_on_missing_file = true);
 bool readCompleteFile(const char* filename, string& out, bool warn_on_missing_file = true);
 bool writeCompleteFile(const char* filename, const std::string& text, bool warn_on_fail = true);
-bool writeCompleteFile(const char* filename, vector<char>& data, bool warn_on_fail = true);
+bool writeCompleteFile(const char* filename, const span<char>& data, bool warn_on_fail = true);
+bool writeCompleteFile(const char* filename, const span<uint8_t>& data, bool warn_on_fail = true);
+bool writeCompleteFile(const char* filename, const vector<char>& data, bool warn_on_fail);
 #ifdef USE_VIRTFILE
 string readUntilEOL(VirtFILE *f);
