]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Remove temporary string objects in Utilities::(un)pack. 11368/head
authorMarc Fehling <mafehling.git@gmail.com>
Sun, 13 Dec 2020 22:41:03 +0000 (15:41 -0700)
committerMarc Fehling <marc.fehling@gmx.net>
Tue, 15 Dec 2020 03:25:43 +0000 (20:25 -0700)
include/deal.II/base/utilities.h
source/base/utilities.cc
tests/base/utilities_pack_unpack_06.cc

index 8bb17607d1605f18f46a1ec3139d91e67978c5d1..bd88309c75fd3101270fe6ee3ca1205e7ccf252b 100644 (file)
@@ -45,15 +45,15 @@ DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
 #include <boost/archive/binary_iarchive.hpp>
 #include <boost/archive/binary_oarchive.hpp>
 #include <boost/core/demangle.hpp>
+#include <boost/iostreams/device/array.hpp>
+#include <boost/iostreams/device/back_inserter.hpp>
+#include <boost/iostreams/filtering_streambuf.hpp>
 #include <boost/serialization/array.hpp>
 #include <boost/serialization/complex.hpp>
 #include <boost/serialization/vector.hpp>
 
 #ifdef DEAL_II_WITH_ZLIB
-#  include <boost/iostreams/device/back_inserter.hpp>
 #  include <boost/iostreams/filter/gzip.hpp>
-#  include <boost/iostreams/filtering_stream.hpp>
-#  include <boost/iostreams/stream.hpp>
 #endif
 
 DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
@@ -1183,9 +1183,6 @@ namespace Utilities
        std::vector<char> &dest_buffer,
        const bool         allow_compression)
   {
-    // the data is never compressed when we can't use zlib.
-    (void)allow_compression;
-
     std::size_t size = 0;
 
     // see if the object is small and copyable via memcpy. if so, use
@@ -1217,31 +1214,21 @@ namespace Utilities
         // use buffer as the target of a compressing
         // stream into which we serialize the current object
         const std::size_t previous_size = dest_buffer.size();
+        {
+          boost::iostreams::filtering_ostreambuf fosb;
 #ifdef DEAL_II_WITH_ZLIB
-        if (allow_compression)
-          {
-            boost::iostreams::filtering_ostream out;
-            out.push(
-              boost::iostreams::gzip_compressor(boost::iostreams::gzip_params(
-                boost::iostreams::gzip::default_compression)));
-            out.push(boost::iostreams::back_inserter(dest_buffer));
-
-            boost::archive::binary_oarchive archive(out);
-            archive << object;
-            out.flush();
-          }
-        else
+          if (allow_compression)
+            fosb.push(boost::iostreams::gzip_compressor());
+#else
+          (void)allow_compression;
 #endif
-          {
-            std::ostringstream              out;
-            boost::archive::binary_oarchive archive(out);
-            archive << object;
-
-            const std::string s = out.str();
-            dest_buffer.reserve(dest_buffer.size() + s.size());
-            std::move(s.begin(), s.end(), std::back_inserter(dest_buffer));
-          }
+          fosb.push(boost::iostreams::back_inserter(dest_buffer));
 
+          boost::archive::binary_oarchive boa(fosb);
+          boa << object;
+          // the stream object has to be destroyed before the return statement
+          // to ensure that all data has been written in the buffer
+        }
         size = dest_buffer.size() - previous_size;
       }
 
@@ -1267,9 +1254,6 @@ namespace Utilities
   {
     T object;
 
-    // the data is never compressed when we can't use zlib.
-    (void)allow_compression;
-
     // see if the object is small and copyable via memcpy. if so, use
     // this fast path. otherwise, we have to go through the BOOST
     // serialization machinery
@@ -1292,29 +1276,18 @@ namespace Utilities
       }
     else
       {
-        std::string decompressed_buffer;
-
-        // first decompress the buffer
+        // decompress the buffer section into the object
+        boost::iostreams::filtering_istreambuf fisb;
 #ifdef DEAL_II_WITH_ZLIB
         if (allow_compression)
-          {
-            boost::iostreams::filtering_ostream decompressing_stream;
-            decompressing_stream.push(boost::iostreams::gzip_decompressor());
-            decompressing_stream.push(
-              boost::iostreams::back_inserter(decompressed_buffer));
-            decompressing_stream.write(&*cbegin, std::distance(cbegin, cend));
-          }
-        else
+          fisb.push(boost::iostreams::gzip_decompressor());
+#else
+        (void)allow_compression;
 #endif
-          {
-            decompressed_buffer.assign(cbegin, cend);
-          }
-
-        // then restore the object from the buffer
-        std::istringstream              in(decompressed_buffer);
-        boost::archive::binary_iarchive archive(in);
+        fisb.push(boost::iostreams::array_source(&*cbegin, &*cend));
 
-        archive >> object;
+        boost::archive::binary_iarchive bia(fisb);
+        bia >> object;
       }
 
     return object;
@@ -1357,30 +1330,18 @@ namespace Utilities
       }
     else
       {
-        std::string decompressed_buffer;
-
-        // first decompress the buffer
-        (void)allow_compression;
+        // decompress the buffer section into the object
+        boost::iostreams::filtering_istreambuf fisb;
 #ifdef DEAL_II_WITH_ZLIB
         if (allow_compression)
-          {
-            boost::iostreams::filtering_ostream decompressing_stream;
-            decompressing_stream.push(boost::iostreams::gzip_decompressor());
-            decompressing_stream.push(
-              boost::iostreams::back_inserter(decompressed_buffer));
-            decompressing_stream.write(&*cbegin, std::distance(cbegin, cend));
-          }
-        else
+          fisb.push(boost::iostreams::gzip_decompressor());
+#else
+        (void)allow_compression;
 #endif
-          {
-            decompressed_buffer.assign(cbegin, cend);
-          }
-
-        // then restore the object from the buffer
-        std::istringstream              in(decompressed_buffer);
-        boost::archive::binary_iarchive archive(in);
+        fisb.push(boost::iostreams::array_source(&*cbegin, &*cend));
 
-        archive >> unpacked_object;
+        boost::archive::binary_iarchive bia(fisb);
+        bia >> unpacked_object;
       }
   }
 
index 1de6dc892f06457891de04005c74badd1cbe4ded..f687aa26a90131ebc313e65c03bcd859b34c94b0 100644 (file)
@@ -398,8 +398,7 @@ namespace Utilities
     std::stringstream origin(input);
 
     bio::filtering_streambuf<bio::input> out;
-    out.push(bio::gzip_compressor(
-      bio::gzip_params(boost::iostreams::gzip::default_compression)));
+    out.push(bio::gzip_compressor());
     out.push(origin);
     bio::copy(out, compressed);
 
index 9811e2bc7376409ab297e1b2c3cc535f1cd626d7..9071725c9c592ec677794559809750f73e5088b0 100644 (file)
@@ -149,7 +149,7 @@ check(const double (&array)[N], const Point<dim>(&point))
                                       point_uncompressed.cend(),
                                       true);
     }
-  catch (const boost::archive::archive_exception &)
+  catch (const boost::iostreams::gzip_error &)
     {
       deallog << "unpacking uncompressed point with decompression failed!"
               << std::endl;
@@ -162,7 +162,7 @@ check(const double (&array)[N], const Point<dim>(&point))
                         forbidden,
                         true);
     }
-  catch (const boost::archive::archive_exception &)
+  catch (const boost::iostreams::gzip_error &)
     {
       deallog << "unpacking uncompressed array with decompression failed!"
               << std::endl;

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.