处理Haskell zlib解压缩错误 [英] Handling Haskell zlib decompression errors

查看:66
本文介绍了处理Haskell zlib解压缩错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个String x ,它可能会或可能不会经过gzip压缩.我想使用 zlib 库来尝试解压缩 x-如果成功,该函数将返回压缩的String.如果不是这样(即 x 未被gzip压缩),我只想返回 x .

I have a String x which may or may not be gzip-compressed. Using the zlib library, I want to try decompressing x -- if it succeeds, the function shall return the compressed String. If not (i.e. x is not gzip-compressed) I want to simply return x.

如果将 GZip.decompress 应用于非gzip字符串,则会生成 error ,因此我可以使用 catch 或类似的方法,但是我我专门要求使用 zlib 错误处理机制的解决方案.

As GZip.decompress generates an error if applied to a non-gzip string, I could use catch or similar, but I'm specifically asking for a solution that uses the zlib error handling mechanism.

如何编写函数,例如 decompressIfPossible :: ByteString->具有上述特征的ByteString ?我更喜欢使用 Ether String ByteString 来表示错误或解压缩结果.

How can I write a function, say decompressIfPossible :: ByteString -> ByteString that has the previously described characteristics? I'd prefer a Either String ByteString to represent either the error or the decompression result.

注意:该问题有意不显示研究成果,因为它立即以Q& A方式回答.

Note: This question intentionally does not show research effort, as it was immediately answered in a Q&A-style manner.

推荐答案

您需要在此处使用的 zlib 中的函数称为

The function from zlib you need to use here is called decompressWithErrors. Its value is the recursive DecompressStream data structure that you can fold to a ByteString using v:fromDecompressStream

这是如何编写您要求的功能的完整示例:

Here's a full example of how to write the function you asked for:

import Data.Either
import Codec.Compression.Zlib.Internal
import qualified Data.ByteString.Lazy.Char8 as LB

-- | Convert & unfold the custom DecompressStream
--   error format from zlib to a Either
decompressStreamToEither :: DecompressStream -> Either String LB.ByteString
decompressStreamToEither (StreamError _ errmsg) = Left errmsg
decompressStreamToEither stream@(StreamChunk _ _) = Right $ fromDecompressStream stream
decompressStreamToEither StreamEnd = Right $ ""

-- | Decompress with explicit error handling
safeDecompress :: LB.ByteString -> Either String LB.ByteString
safeDecompress bstr = decompressStreamToEither $ decompressWithErrors gzipOrZlibFormat defaultDecompressParams bstr

-- | Decompress gzip, if it fails, return uncompressed String
decompressIfPossible :: LB.ByteString -> LB.ByteString
decompressIfPossible bstr =
    let conv (Left a) = bstr
        conv (Right a) = a
    in (conv . safeDecompress) bstr

请注意,此示例使用

Note that this example uses gzipOrZlibFormat which automatically detects if the header is a zlib or a gzip header.

这篇关于处理Haskell zlib解压缩错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆