tdf#63130 improve the performance in librevenge

we end up generating a ton of base64 encoded strings when loading a
visio file, so reduce some copying here

Change-Id: I2d56fda867032b23b03971731b2565f1edc2e1a4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151882
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/external/librevenge/UnpackedTarball_librevenge.mk b/external/librevenge/UnpackedTarball_librevenge.mk
index 74f2875..5fcc2e3 100644
--- a/external/librevenge/UnpackedTarball_librevenge.mk
+++ b/external/librevenge/UnpackedTarball_librevenge.mk
@@ -17,6 +17,7 @@ $(eval $(call gb_UnpackedTarball_set_patchlevel,librevenge,0))

$(eval $(call gb_UnpackedTarball_add_patches,librevenge, \
    external/librevenge/rpath.patch \
    external/librevenge/tdf63130-improve-perf.patch.0 \
))

ifneq ($(OS),MACOSX)
diff --git a/external/librevenge/tdf63130-improve-perf.patch.0 b/external/librevenge/tdf63130-improve-perf.patch.0
new file mode 100644
index 0000000..02a8a6e
--- /dev/null
+++ b/external/librevenge/tdf63130-improve-perf.patch.0
@@ -0,0 +1,80 @@
--- inc/librevenge/RVNGString.h	2023-05-17 15:48:15.373159469 +0200
+++ inc/librevenge/RVNGString.h	2023-05-17 15:49:00.781411917 +0200
@@ -22,6 +22,7 @@
 #define RVNGSTRING_H
 
 #include "librevenge-api.h"
+#include <string>
 
 namespace librevenge
 {
@@ -36,6 +37,7 @@
 	RVNGString();
 	RVNGString(const RVNGString &other);
 	RVNGString(const char *str);
+	RVNGString(std::string&&);
 	~RVNGString();
 
 	/** Create a new string from \a s as escaped XML.
--- src/lib/RVNGBinaryData.cpp	2023-05-17 15:48:15.373159469 +0200
+++ src/lib/RVNGBinaryData.cpp	2023-05-17 15:49:00.773411873 +0200
@@ -67,9 +67,9 @@
 	boost::archive::iterators::transform_width<std::vector<unsigned char>::const_iterator, 6, 8 > > base64_encoder;
 
 	// Encode the buffer and create a string
-	std::copy(
+	result.insert(result.begin(),
 	    base64_encoder(source.begin()),
-	    base64_encoder(source.end()), std::back_inserter(result));
+	    base64_encoder(source.end()));
 
 	result.append(numPadding, '=');  // add '=' for each padded character
 }
@@ -150,10 +150,10 @@
 {
 	m_binaryDataImpl->makeUnique();
 
-	unsigned long previousSize = m_binaryDataImpl->m_ptr->m_buf.size();
-	m_binaryDataImpl->m_ptr->m_buf.reserve(previousSize + data.m_binaryDataImpl->m_ptr->m_buf.size());
-	for (unsigned long i = 0; i < data.m_binaryDataImpl->m_ptr->m_buf.size(); i++)
-		m_binaryDataImpl->m_ptr->m_buf.push_back(data.m_binaryDataImpl->m_ptr->m_buf[i]);
+	m_binaryDataImpl->m_ptr->m_buf.insert(
+		m_binaryDataImpl->m_ptr->m_buf.end(),
+		data.m_binaryDataImpl->m_ptr->m_buf.begin(),
+		data.m_binaryDataImpl->m_ptr->m_buf.end());
 }
 
 void RVNGBinaryData::appendBase64Data(const RVNGString &base64)
@@ -231,8 +231,9 @@
 const RVNGString RVNGBinaryData::getBase64Data() const
 {
 	std::string base64;
+	base64.reserve(m_binaryDataImpl->m_ptr->m_buf.size() / 4 * 3);
 	convertToBase64(base64, m_binaryDataImpl->m_ptr->m_buf);
-	return RVNGString(base64.c_str());
+	return RVNGString(std::move(base64));
 }
 
 RVNGInputStream *RVNGBinaryData::getDataStream() const
--- src/lib/RVNGString.cpp	2023-05-17 15:48:15.373159469 +0200
+++ src/lib/RVNGString.cpp	2023-05-17 15:49:00.773411873 +0200
@@ -73,6 +73,7 @@
 {
 public:
 	RVNGStringImpl() : m_buf() {}
+	RVNGStringImpl(std::string&& str) : m_buf(std::move(str)) {}
 	bool empty() const
 	{
 		return m_buf.empty();
@@ -157,6 +158,11 @@
 		m_stringImpl->m_buf = str;
 }
 
+RVNGString::RVNGString(std::string&& str) :
+	m_stringImpl(new RVNGStringImpl(std::move(str)))
+{
+}
+
 RVNGString RVNGString::escapeXML(const RVNGString &s)
 {
 	RVNGString escaped;