diff Core/Compression/ZlibCompressor.cpp @ 1511:7962563129c9

starting support of deflate/gzip content types
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 10 Aug 2015 14:18:24 +0200
parents 6e7e5ed91c2d
children 52dc56bcec7d
line wrap: on
line diff
--- a/Core/Compression/ZlibCompressor.cpp	Mon Aug 10 10:27:05 2015 +0200
+++ b/Core/Compression/ZlibCompressor.cpp	Mon Aug 10 14:18:24 2015 +0200
@@ -61,25 +61,32 @@
       return;
     }
 
-    uLongf compressedSize = compressBound(uncompressedSize);
-    compressed.resize(compressedSize + sizeof(size_t));
+    uLongf compressedSize = compressBound(uncompressedSize) + 1024 /* security margin */;
+    if (compressedSize == 0)
+    {
+      compressedSize = 1;
+    }
 
-    int error = compress2
-      (reinterpret_cast<uint8_t*>(&compressed[0]) + sizeof(size_t),
-       &compressedSize,
-       const_cast<Bytef *>(static_cast<const Bytef *>(uncompressed)), 
-       uncompressedSize,
-       compressionLevel_);
-
-    memcpy(&compressed[0], &uncompressedSize, sizeof(size_t));
-  
-    if (error == Z_OK)
+    uint8_t* target;
+    if (prefixWithUncompressedSize_)
     {
-      compressed.resize(compressedSize + sizeof(size_t));
-      return;
+      compressed.resize(compressedSize + sizeof(uint64_t));
+      target = reinterpret_cast<uint8_t*>(&compressed[0]) + sizeof(uint64_t);
     }
     else
     {
+      compressed.resize(compressedSize);
+      target = reinterpret_cast<uint8_t*>(&compressed[0]);
+    }
+
+    int error = compress2(target,
+                          &compressedSize,
+                          const_cast<Bytef *>(static_cast<const Bytef *>(uncompressed)), 
+                          uncompressedSize,
+                          compressionLevel_);
+
+    if (error != Z_OK)
+    {
       compressed.clear();
 
       switch (error)
@@ -91,6 +98,18 @@
         throw OrthancException(ErrorCode_InternalError);
       }  
     }
+
+    // The compression was successful
+    if (prefixWithUncompressedSize_)
+    {
+      uint64_t s = static_cast<uint64_t>(uncompressedSize);
+      memcpy(&compressed[0], &s, sizeof(uint64_t));
+      compressed.resize(compressedSize + sizeof(uint64_t));
+    }
+    else
+    {
+      compressed.resize(compressedSize);
+    }
   }
 
 
@@ -104,29 +123,29 @@
       return;
     }
 
-    if (compressedSize < sizeof(size_t))
+    if (compressedSize < sizeof(uint64_t))
     {
       throw OrthancException("Zlib: The compressed buffer is ill-formed");
     }
 
-    size_t uncompressedLength;
-    memcpy(&uncompressedLength, compressed, sizeof(size_t));
+    uint64_t uncompressedSize;
+    memcpy(&uncompressedSize, compressed, sizeof(uint64_t));
     
     try
     {
-      uncompressed.resize(uncompressedLength);
+      uncompressed.resize(uncompressedSize);
     }
     catch (...)
     {
       throw OrthancException("Zlib: Corrupted compressed buffer");
     }
 
-    uLongf tmp = uncompressedLength;
+    uLongf tmp = uncompressedSize;
     int error = uncompress
       (reinterpret_cast<uint8_t*>(&uncompressed[0]), 
        &tmp,
-       reinterpret_cast<const uint8_t*>(compressed) + sizeof(size_t),
-       compressedSize - sizeof(size_t));
+       reinterpret_cast<const uint8_t*>(compressed) + sizeof(uint64_t),
+       compressedSize - sizeof(uint64_t));
 
     if (error != Z_OK)
     {