More robust implementation of decompression
authorunc0rr
Wed, 22 Jan 2014 23:06:50 +0400
changeset 10055 f738693be9be
parent 10054 6357b3099e1f
child 10056 cb9e07753802
More robust implementation of decompression
gameServer/EngineInteraction.hs
--- a/gameServer/EngineInteraction.hs	Wed Jan 22 19:55:52 2014 +0100
+++ b/gameServer/EngineInteraction.hs	Wed Jan 22 23:06:50 2014 +0400
@@ -19,6 +19,22 @@
 import CoreTypes
 import Utils
 
+{-
+    this is snippet from http://stackoverflow.com/questions/10043102/how-to-catch-the-decompress-ioerror
+    because standard 'catch' doesn't seem to catch decompression errors for some reason
+-}
+import qualified Codec.Compression.Zlib.Internal as Z
+import Control.Arrow (right)
+
+decompressWithoutExceptions :: BL.ByteString -> Either Z.DecompressError BL.ByteString
+decompressWithoutExceptions = finalise
+                            . Z.foldDecompressStream cons nil err
+                            . Z.decompressWithErrors Z.gzipFormat Z.defaultDecompressParams
+  where err errorCode errorString = Left errorCode
+        nil = Right []
+        cons chunk = right (chunk :)
+        finalise = right BL.fromChunks
+{- end snippet  -}
 
 toEngineMsg :: B.ByteString -> B.ByteString
 toEngineMsg msg = B.pack $ Base64.encode (fromIntegral (BW.length msg) : BW.unpack msg)
@@ -57,7 +73,6 @@
         slotMessages = "\128\129\130\131\132\133\134\135\136\137\138"
         timedMessages = Set.fromList $ "+LlRrUuDdZzAaSjJ,NpPwtgc12345" ++ slotMessages
 
-
 replayToDemo :: [TeamInfo]
         -> Map.Map B.ByteString B.ByteString
         -> Map.Map B.ByteString [B.ByteString]
@@ -117,7 +132,8 @@
           L.map (\m -> eml ["edraw ", BW.pack m])
         . L.unfoldr by200
         . BL.unpack
-        . Z.decompress
+        . either (const BL.empty) id
+        . decompressWithoutExceptions
         . BL.pack
         . L.drop 4
         . fromMaybe []