Made String::vsprintf behave properly with long strings.

Wed, 20 Jul 2016 17:47:42 +0300

author
Teemu Piippo <teemu@compsta2.com>
date
Wed, 20 Jul 2016 17:47:42 +0300
changeset 148
19e98695e584
parent 147
12c93c4a137c
child 149
7643c21d546b

Made String::vsprintf behave properly with long strings.

sources/list.h file | annotate | diff | comparison | revisions
sources/mystring.cpp file | annotate | diff | comparison | revisions
--- a/sources/list.h	Wed Jul 20 17:31:51 2016 +0300
+++ b/sources/list.h	Wed Jul 20 17:47:42 2016 +0300
@@ -352,6 +352,9 @@
 
 	Vector(){}
 
+	Vector(int numvalues) :
+	    Super(numvalues){}
+
 	Vector (T* data, size_t length) :
 		Super (std::vector<T> (data, data + length)) {}
 
--- a/sources/mystring.cpp	Wed Jul 20 17:31:51 2016 +0300
+++ b/sources/mystring.cpp	Wed Jul 20 17:47:42 2016 +0300
@@ -376,26 +376,32 @@
 }
 
 /*!
- * \brief Formats this string using \c vsnprintf, using the provided arguments. The buffer string will be repeatedly
- *        allocated larger and larger until \c vsnprintf succeeds.
+ * \brief Formats this string using \c vsnprintf, using the provided arguments.
  * \param formatString Template string to use with formatting.
  * \param args Variadic arguments to use with formatting.
  */
 void String::vsprintf (const char* formatString, va_list args)
 {
-	char* buf = nullptr;
-	int bufsize = 256;
+	// Copy the argument list so that we have something to provide to vsnprintf in case we have to call it again.
+	va_list argsCopy;
+	va_copy(argsCopy, args);
 
-	do
+	// First, attempt to format using a fixed-size buffer.
+	static char buffer[64];
+	size_t length = vsnprintf(buffer, sizeof buffer, formatString, args);
+
+	if (length < sizeof buffer)
 	{
-		bufsize *= 2;
-		delete[] buf;
-		buf = new char[bufsize];
+		// vsnprintf succeeded in fitting the formatted string into the buffer, so we're done.
+		m_string = buffer;
 	}
-	while (vsnprintf (buf, bufsize, formatString, args) >= bufsize);
-
-	m_string = buf;
-	delete[] buf;
+	else
+	{
+		// vsnprintf needs more space, so we have to allocate a new buffer and try again.
+		Vector<char> newBuffer(length + 1);
+		vsnprintf(newBuffer.data(), length + 1, formatString, argsCopy);
+		m_string = newBuffer;
+	}
 }
 
 /*!

mercurial