2014-02-14 4 views
1

gzip으로 압축되었거나 압축되지 않은 문자열 x이 있습니다. zlib 라이브러리를 사용하여, x의 압축을 풀고 싶습니다. 성공하면 함수는 압축 된 문자열을 반환합니다. 그렇지 않은 경우 (즉, x은 gzip으로 압축되지 않음) 단순히 x을 반환하고 싶습니다. 비 gzip을 문자열에 적용되는 경우 GZip.decompress으로하스켈 zlib 압축 해제 오류 처리

내가 catch 또는 유사한을 사용할 수, error을 생성하지만 나는 특히 zlib 오류 처리 메커니즘을 사용하는 솔루션을 요구하고있다.

가 어떻게 기능을 쓸 수있는, 이전에 특징을 설명하고있다 decompressIfPossible :: ByteString -> ByteString 말? 오류 또는 압축 해제 결과를 나타 내기 위해 Either String ByteString을 선호합니다.

참고 :이 즉시 Q & A-스타일의 방식으로 대답했다으로이 질문은 의도적으로, 연구 노력을 표시하지 않습니다.

답변

1

여기에 사용할 필요가 zlib에서이 기능은 decompressWithErrors라고합니다. 이 값은 사용하면 ByteString에 접을 수있는 재귀 DecompressStream 데이터 구조입니다 v:fromDecompressStream

여기에 당신이 요청한 기능을 작성하는 방법에 대한 전체 예제 :이 예는 gzipOrZlibFormat하는 자동으로 사용

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 [email protected](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 

참고 헤더가 zlib 또는 gzip 헤더인지 여부를 감지합니다.

관련 문제