content: module System.Compress.ByteString(
    decompressLZ,
    decompressRLE,
    decompressLZRLE,
    ) where
  import qualified Prelude(); import MiniPrelude
  import Primitives(primForeignPtrToPtr)
  import qualified Data.ByteString as BS
  import Data.Function
  import Foreign.C.String
  import Foreign.C.Types
  import Foreign.Marshal.Alloc
  import Foreign.Marshal.Utils
  import Foreign.Ptr
  import Foreign.Storable
  import System.IO
  import System.IO.Internal
  import System.IO.Unsafe
  
  type PBFILE = Ptr BFILE
  type Transducer = PBFILE -> IO PBFILE
  foreign import ccall "openb_wr_mem"          c_openb_wr_mem          :: IO PBFILE
  foreign import ccall "openb_rd_mem"          c_openb_rd_mem          :: CString -> Int -> IO PBFILE
  foreign import ccall "add_lz77_compressor"   c_add_lz77_compressor   :: Transducer
  foreign import ccall "add_lz77_decompressor" c_add_lz77_decompressor :: Transducer
  foreign import ccall "add_rle_compressor"    c_add_rle_compressor    :: Transducer
  foreign import ccall "add_rle_decompressor"  c_add_rle_decompressor  :: Transducer
  foreign import ccall "add_bwt_compressor"    c_add_bwt_compressor    :: Transducer
  foreign import ccall "add_bwt_decompressor"  c_add_bwt_decompressor  :: Transducer
  foreign import ccall "putb"                  c_putb                  :: Int -> PBFILE -> IO ()
  foreign import ccall "getb"                  c_getb                  :: PBFILE -> IO Int
  foreign import ccall "get_mem"               c_get_mem               :: PBFILE -> Ptr CString -> Ptr Int -> IO ()
  foreign import ccall "closeb"                c_close                 :: PBFILE -> IO ()
  foreign import ccall "flushb"                c_flush                 :: PBFILE -> IO ()
  
  withGetTransducerBS :: Transducer -> BS.ByteString -> BS.ByteString
  withGetTransducerBS trans bs = unsafePerformIO $ do
    BS.useAsCStringLen bs $ \ (ptr, len) -> do
    bf <- c_openb_rd_mem ptr len                 -- open it for reading
    cbf <- trans bf                              -- and add transducer (e.g., decompressor)
    h <- mkHandle "withGetTransducer" cbf HRead
    seq bs (return ())
    BS.hGetContents h
  
  decompressLZ :: BS.ByteString -> BS.ByteString
  decompressLZ = withGetTransducerBS c_add_lz77_decompressor
  
  decompressRLE :: BS.ByteString -> BS.ByteString
  decompressRLE = withGetTransducerBS c_add_rle_decompressor
  
  decompressLZRLE :: BS.ByteString -> BS.ByteString
  decompressLZRLE = withGetTransducerBS (c_add_rle_decompressor <=< c_add_lz77_decompressor)
  