snappy (empty) → 0.1.0.0
raw patch · 9 files changed
+248/−0 lines, 9 filesdep +basedep +bytestringsetup-changed
Dependencies added: base, bytestring
Files
- Codec/Compression/Snappy.hs +73/−0
- LICENSE +29/−0
- README.md +29/−0
- Setup.lhs +3/−0
- cbits/hs_snappy.cpp +26/−0
- include/hs_snappy.h +27/−0
- snappy.cabal +38/−0
- tests/Makefile +9/−0
- tests/Properties.hs +14/−0
+ Codec/Compression/Snappy.hs view
@@ -0,0 +1,73 @@+{-# LANGUAGE ForeignFunctionInterface #-}++-- |+-- Module: Codec.Compression.Snappy+-- Copyright: (c) 2011 MailRank, Inc.+-- License: Apache+-- Maintainer: Bryan O'Sullivan <bos@mailrank.com>+-- Stability: experimental+-- Portability: portable+--+-- This library provides fast, pure Haskell bindings to Google's+-- Snappy compression and decompression library:+-- <http://code.google.com/p/snappy/>++module Codec.Compression.Snappy+ (+ compress+ , decompress+ ) where++import Control.Monad (unless)+import Data.ByteString.Internal (ByteString(..), mallocByteString)+import Data.Word (Word8)+import Foreign.C.Types (CSize)+import Foreign.ForeignPtr (withForeignPtr)+import Foreign.Marshal.Alloc (alloca)+import Foreign.Marshal.Utils (with)+import Foreign.Ptr (Ptr, plusPtr)+import Foreign.Storable (peek)+import System.IO.Unsafe (unsafePerformIO)+import qualified Data.ByteString as B++-- | Compress data into the Snappy format.+compress :: ByteString -> ByteString+compress bs@(PS sfp off len) = unsafePerformIO $ do+ let dlen0 = fromIntegral . c_MaxCompressedLength . fromIntegral $ len+ dfp <- mallocByteString dlen0+ withForeignPtr sfp $ \sptr ->+ withForeignPtr dfp $ \dptr ->+ with (fromIntegral dlen0) $ \dlenPtr -> do+ c_RawCompress (sptr `plusPtr` off) (fromIntegral len) dptr dlenPtr+ (PS dfp 0 . fromIntegral) `fmap` peek dlenPtr++-- | Decompress data in the Snappy format.+--+-- If the input is not compressed or is corrupt, an exception will be+-- thrown.+decompress :: ByteString -> ByteString+decompress (PS sfp off slen) = unsafePerformIO $+ withForeignPtr sfp $ \sptr0 -> do+ let sptr = sptr0 `plusPtr` off+ len = fromIntegral slen+ alloca $ \dlenPtr -> do+ ok0 <- c_GetUncompressedLength sptr len dlenPtr+ unless ok0 $ error "Codec.Compression.Snappy.decompress: corrupt input"+ dlen <- fromIntegral `fmap` peek dlenPtr+ dfp <- mallocByteString dlen+ withForeignPtr dfp $ \dptr -> do+ ok1 <- c_RawUncompress sptr len dptr+ unless ok1 $ error "Codec.Compression.Snappy.decompress: corrupt input"+ return (PS dfp 0 dlen)++foreign import ccall unsafe "hs_snappy.h _hsnappy_MaxCompressedLength"+ c_MaxCompressedLength :: CSize -> CSize++foreign import ccall unsafe "hs_snappy.h _hsnappy_RawCompress"+ c_RawCompress :: Ptr a -> CSize -> Ptr Word8 -> Ptr CSize -> IO ()++foreign import ccall unsafe "hs_snappy.h _hsnappy_GetUncompressedLength"+ c_GetUncompressedLength :: Ptr a -> CSize -> Ptr CSize -> IO Bool++foreign import ccall unsafe "hs_snappy.h _hsnappy_RawUncompress"+ c_RawUncompress :: Ptr a -> CSize -> Ptr Word8 -> IO Bool
+ LICENSE view
@@ -0,0 +1,29 @@+Copyright (c) 2011, MailRank Inc.+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++ * Redistributions of source code must retain the above copyright+notice, this list of conditions and the following disclaimer.+ * Redistributions in binary form must reproduce the above+copyright notice, this list of conditions and the following disclaimer+in the documentation and/or other materials provided with the+distribution.+ * Neither the name of MailRank Inc. nor the names of its+contributors may be used to endorse or promote products derived+from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE+POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,29 @@+# Welcome to snappy++snappy is a fast Haskell library for working with data compressed+using Google's Snappy format. It is implemented as a binding to the+[Snappy library](http://code.google.com/p/snappy/).++# Join in!++We are happy to receive bug reports, fixes, documentation enhancements,+and other improvements.++Please report bugs via the+[github issue tracker](http://github.com/mailrank/snappy/issues).++Master [git repository](http://github.com/mailrank/snappy):++* `git clone git://github.com/mailrank/snappy.git`++There's also a [Mercurial mirror](http://bitbucket.org/bos/snappy):++* `hg clone http://bitbucket.org/bos/snappy`++(You can create and contribute changes using either git or Mercurial.)++Authors+-------++This library is written and maintained by Bryan O'Sullivan,+<bos@mailrank.com>.
+ Setup.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ cbits/hs_snappy.cpp view
@@ -0,0 +1,26 @@+#include "hs_snappy.h"+#include "snappy.h"++size_t _hsnappy_MaxCompressedLength(size_t n)+{+ return snappy::MaxCompressedLength(n);+}++void _hsnappy_RawCompress(const char *input, size_t input_length,+ char *compressed, size_t *compressed_length)+{+ snappy::RawCompress(input, input_length, compressed, compressed_length);+}++bool _hsnappy_GetUncompressedLength(const char *compressed,+ size_t compressed_length,+ size_t *result)+{+ return snappy::GetUncompressedLength(compressed, compressed_length, result);+}++bool _hsnappy_RawUncompress(const char *compressed, size_t compressed_length,+ char *uncompressed)+{+ return snappy::RawUncompress(compressed, compressed_length, uncompressed);+}
+ include/hs_snappy.h view
@@ -0,0 +1,27 @@+#ifndef _hs_snappy_h+#define _hs_snappy_h++#include <stddef.h>++#ifdef __cplusplus+extern "C" +{+#endif++size_t _hsnappy_MaxCompressedLength(size_t);++void _hsnappy_RawCompress(const char *input, size_t input_length,+ char *compressed, size_t *compressed_length);++bool _hsnappy_GetUncompressedLength(const char *compressed,+ size_t compressed_length,+ size_t *result);++bool _hsnappy_RawUncompress(const char *compressed, size_t compressed_length,+ char *uncompressed);++#ifdef __cplusplus+}+#endif++#endif /* _hs_snappy_h */
+ snappy.cabal view
@@ -0,0 +1,38 @@+name: snappy+version: 0.1.0.0+homepage: http://github.com/mailrank/snappy+bug-reports: http://github.com/mailrank/snappy/issues+synopsis:+ Bindings to the Google Snappy library for fast compression/decompression+description:+ This library provides fast, pure Haskell bindings to Google's Snappy+ compression and decompression library: <http://code.google.com/p/snappy/>+license: BSD3+license-file: LICENSE+author: Bryan O'Sullivan <bos@mailrank.com>+maintainer: Bryan O'Sullivan <bos@mailrank.com>+copyright: Copyright 2011 MailRank, Inc.+category: Codec, Compression+build-type: Simple+cabal-version: >= 1.6+extra-source-files:+ README.md+ include/hs_snappy.h+ tests/Makefile+ tests/Properties.hs++library+ c-sources: cbits/hs_snappy.cpp+ include-dirs: include+ extra-libraries: snappy stdc++++ build-depends: base < 5, bytestring+ if impl(ghc >= 6.10)+ build-depends: base >= 4++ exposed-modules:+ Codec.Compression.Snappy++source-repository head+ type: git+ location: http://github.com/mailrank/snappy
+ tests/Makefile view
@@ -0,0 +1,9 @@+ghc := ghc++all: qc++qc: Properties.hs+ $(ghc) --make -o $@ $^++clean:+ -rm -f qc *.o *.hi
+ tests/Properties.hs view
@@ -0,0 +1,14 @@+import Codec.Compression.Snappy+import Test.Framework (defaultMain, testGroup)+import Test.Framework.Providers.QuickCheck2 (testProperty)+import Test.QuickCheck (Arbitrary(..))+import qualified Data.ByteString as B++roundtrip s = decompress (compress bs) == bs+ where bs = B.pack s++main = defaultMain tests++tests = [+ testProperty "roundtrip" roundtrip+ ]