    {-# LANGUAGE CPP #-}
    module Codec.Picture.InternalHelper ( runGet
                                        , runGetStrict
                                        , decode
                                        , getRemainingBytes
                                        , getRemainingLazyBytes ) where

    import qualified Data.ByteString as B
    import qualified Data.ByteString.Lazy as L
    import Data.Binary( Binary( get ) )
    import Data.Binary.Get( Get
                          , getRemainingLazyByteString
                          )
    import qualified Data.Binary.Get as G

    #if MIN_VERSION_binary(0,6,4)
    #else
    import Control.Applicative( (<$>) )
    import qualified Control.Exception as E
    -- I feel so dirty. :(
    import System.IO.Unsafe( unsafePerformIO )
    #endif

    decode :: (Binary a) => B.ByteString -> Either String a
    decode = runGetStrict get

    runGet :: Get a -> L.ByteString -> Either String a
    #if MIN_VERSION_binary(0,6,4)
    runGet act = unpack . G.runGetOrFail act
        where unpack (Left (_, _, str)) = Left str
              unpack (Right (_, _, element)) = Right element
    #else
    runGet act str = unsafePerformIO $ E.catch
        (Right <$> E.evaluate (G.runGet act str))
        (\msg -> return . Left $ show (msg :: E.SomeException))
    #endif

    runGetStrict :: Get a -> B.ByteString -> Either String a
    runGetStrict act buffer = runGet act $ L.fromChunks [buffer]

    getRemainingBytes :: Get B.ByteString
    getRemainingBytes = do
        rest <- getRemainingLazyByteString
        return $ case L.toChunks rest of
            [] -> B.empty
            [a] -> a
            lst -> B.concat lst

    getRemainingLazyBytes :: Get L.ByteString
    getRemainingLazyBytes = getRemainingLazyByteString