msgpack 0.1.0 → 0.2.0
raw patch · 7 files changed
+309/−4 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Data.MessagePack.Base: instance [incoherent] Eq UnpackReturn
- Data.MessagePack.Base: instance [incoherent] Show Object
- Data.MessagePack.Base: instance [incoherent] Show UnpackReturn
- Data.MessagePack.Class: instance [overlap ok] (OBJECT a, OBJECT b) => OBJECT [(a, b)]
- Data.MessagePack.Class: instance [overlap ok] OBJECT Bool
- Data.MessagePack.Class: instance [overlap ok] OBJECT ByteString
- Data.MessagePack.Class: instance [overlap ok] OBJECT Double
- Data.MessagePack.Class: instance [overlap ok] OBJECT Int
- Data.MessagePack.Class: instance [overlap ok] OBJECT Object
- Data.MessagePack.Class: instance [overlap ok] OBJECT String
- Data.MessagePack.Class: instance [overlap ok] OBJECT a => OBJECT (Maybe a)
- Data.MessagePack.Class: instance [overlap ok] OBJECT a => OBJECT [a]
+ Data.MessagePack.Base: instance Eq UnpackReturn
+ Data.MessagePack.Base: instance Show Object
+ Data.MessagePack.Base: instance Show UnpackReturn
+ Data.MessagePack.Class: instance [incoherent] (OBJECT a, OBJECT b) => OBJECT [(a, b)]
+ Data.MessagePack.Class: instance [incoherent] OBJECT Bool
+ Data.MessagePack.Class: instance [incoherent] OBJECT ByteString
+ Data.MessagePack.Class: instance [incoherent] OBJECT Double
+ Data.MessagePack.Class: instance [incoherent] OBJECT Int
+ Data.MessagePack.Class: instance [incoherent] OBJECT Object
+ Data.MessagePack.Class: instance [incoherent] OBJECT String
+ Data.MessagePack.Class: instance [incoherent] OBJECT a => OBJECT (Maybe a)
+ Data.MessagePack.Class: instance [incoherent] OBJECT a => OBJECT [a]
+ Data.MessagePack.Feed: feederFromFile :: FilePath -> IO Feeder
+ Data.MessagePack.Feed: feederFromHandle :: Handle -> IO Feeder
+ Data.MessagePack.Feed: feederFromString :: ByteString -> IO Feeder
+ Data.MessagePack.Feed: type Feeder = IO (Maybe ByteString)
+ Data.MessagePack.Monad: PackerT :: (Packer -> m r) -> PackerT m r
+ Data.MessagePack.Monad: UnpackerT :: (Unpacker -> Feeder -> m r) -> UnpackerT m r
+ Data.MessagePack.Monad: class Monad m => MonadPacker m
+ Data.MessagePack.Monad: class Monad m => MonadUnpacker m
+ Data.MessagePack.Monad: get :: (MonadUnpacker m, OBJECT a) => m a
+ Data.MessagePack.Monad: instance Monad m => Monad (PackerT m)
+ Data.MessagePack.Monad: instance Monad m => Monad (UnpackerT m)
+ Data.MessagePack.Monad: instance MonadIO m => MonadIO (PackerT m)
+ Data.MessagePack.Monad: instance MonadIO m => MonadIO (UnpackerT m)
+ Data.MessagePack.Monad: instance MonadIO m => MonadPacker (PackerT m)
+ Data.MessagePack.Monad: instance MonadIO m => MonadUnpacker (UnpackerT m)
+ Data.MessagePack.Monad: instance MonadTrans PackerT
+ Data.MessagePack.Monad: instance MonadTrans UnpackerT
+ Data.MessagePack.Monad: newtype PackerT m r
+ Data.MessagePack.Monad: newtype UnpackerT m r
+ Data.MessagePack.Monad: packToFile :: MonadIO m => FilePath -> PackerT m r -> m ()
+ Data.MessagePack.Monad: packToHandle :: MonadIO m => Handle -> PackerT m r -> m ()
+ Data.MessagePack.Monad: packToString :: MonadIO m => PackerT m r -> m ByteString
+ Data.MessagePack.Monad: put :: (MonadPacker m, OBJECT a) => a -> m ()
+ Data.MessagePack.Monad: runPackerT :: PackerT m r -> Packer -> m r
+ Data.MessagePack.Monad: runUnpackerT :: UnpackerT m r -> Unpacker -> Feeder -> m r
+ Data.MessagePack.Monad: unpackFrom :: MonadIO m => Feeder -> UnpackerT m r -> m r
+ Data.MessagePack.Monad: unpackFromFile :: MonadIO m => FilePath -> UnpackerT m r -> m r
+ Data.MessagePack.Monad: unpackFromHandle :: MonadIO m => Handle -> UnpackerT m r -> m r
+ Data.MessagePack.Monad: unpackFromString :: MonadIO m => ByteString -> UnpackerT m r -> m r
+ Data.MessagePack.Stream: unpackObjects :: Feeder -> IO [Object]
+ Data.MessagePack.Stream: unpackObjectsFromFile :: FilePath -> IO [Object]
+ Data.MessagePack.Stream: unpackObjectsFromHandle :: Handle -> IO [Object]
+ Data.MessagePack.Stream: unpackObjectsFromString :: ByteString -> IO [Object]
Files
- msgpack.cabal +6/−2
- src/Data/MessagePack.hs +6/−0
- src/Data/MessagePack/Base.hsc +0/−2
- src/Data/MessagePack/Class.hs +1/−0
- src/Data/MessagePack/Feed.hs +59/−0
- src/Data/MessagePack/Monad.hs +153/−0
- src/Data/MessagePack/Stream.hs +84/−0
msgpack.cabal view
@@ -1,12 +1,13 @@ Name: msgpack-Version: 0.1.0+Version: 0.2.0 License: BSD3 License-File: LICENSE Author: Hideyuki Tanaka Maintainer: Hideyuki Tanaka <tanaka.hideyuki@gmail.com> Category: Data Synopsis: A Haskell binding to MessagePack-Description: A Haskell binding to MessagePack+Description:+ A Haskell binding to MessagePack <http://msgpack.sourceforge.jp/> Homepage: http://github.com/tanakh/hsmsgpack Stability: Experimental Tested-with: GHC==6.10.4@@ -23,6 +24,9 @@ Data.MessagePack Data.MessagePack.Base Data.MessagePack.Class+ Data.MessagePack.Feed+ Data.MessagePack.Monad+ Data.MessagePack.Stream C-Sources: cbits/msgpack.c
src/Data/MessagePack.hs view
@@ -15,6 +15,9 @@ module Data.MessagePack( module Data.MessagePack.Base, module Data.MessagePack.Class,+ module Data.MessagePack.Feed,+ module Data.MessagePack.Monad,+ module Data.MessagePack.Stream, -- * Pack and Unpack packb,@@ -30,6 +33,9 @@ import Data.MessagePack.Base import Data.MessagePack.Class+import Data.MessagePack.Feed+import Data.MessagePack.Monad+import Data.MessagePack.Stream -- | Pack Haskell data to MessagePack string. packb :: OBJECT a => a -> IO ByteString
src/Data/MessagePack/Base.hsc view
@@ -1,7 +1,5 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ForeignFunctionInterface #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE IncoherentInstances #-} -------------------------------------------------------------------- -- |
src/Data/MessagePack/Class.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverlappingInstances #-}+{-# LANGUAGE IncoherentInstances #-} -------------------------------------------------------------------- -- |
+ src/Data/MessagePack/Feed.hs view
@@ -0,0 +1,59 @@+--------------------------------------------------------------------+-- |+-- Module : Data.MessagePack.Feed+-- Copyright : (c) Hideyuki Tanaka, 2009+-- License : BSD3+--+-- Maintainer: tanaka.hideyuki@gmail.com+-- Stability : experimental+-- Portability: portable+--+-- Feeders for Stream Deserializers+--+--------------------------------------------------------------------++module Data.MessagePack.Feed(+ -- * Feeder type+ Feeder,+ -- * Feeders+ feederFromHandle,+ feederFromFile,+ feederFromString,+ ) where++import Control.Monad+import Data.ByteString (ByteString)+import qualified Data.ByteString as BS+import Data.IORef+import System.IO++-- | Feeder returns Just ByteString when bytes remains, otherwise Nothing.+type Feeder = IO (Maybe ByteString)++-- | Feeder from Handle+feederFromHandle :: Handle -> IO Feeder+feederFromHandle h = return $ do+ bs <- BS.hGet h bufSize+ if BS.length bs > 0+ then return $ Just bs+ else do+ hClose h+ return Nothing+ where+ bufSize = 4096++-- | Feeder from File+feederFromFile :: FilePath -> IO Feeder+feederFromFile path =+ openFile path ReadMode >>= feederFromHandle++-- | Feeder from ByteString+feederFromString :: ByteString -> IO Feeder+feederFromString bs = do+ r <- newIORef (Just bs)+ return $ f r+ where+ f r = do+ mb <- readIORef r+ writeIORef r Nothing+ return mb
+ src/Data/MessagePack/Monad.hs view
@@ -0,0 +1,153 @@+--------------------------------------------------------------------+-- |+-- Module : Data.MessagePack.Monad+-- Copyright : (c) Hideyuki Tanaka, 2009+-- License : BSD3+--+-- Maintainer: tanaka.hideyuki@gmail.com+-- Stability : experimental+-- Portability: portable+--+-- Monadic Stream Serializers and Deserializers+--+--------------------------------------------------------------------++module Data.MessagePack.Monad(+ -- * Classes+ MonadPacker(..),+ MonadUnpacker(..),+ + -- * Packer and Unpacker type+ PackerT(..),+ UnpackerT(..),+ + -- * Packers+ packToString,+ packToHandle,+ packToFile,+ + -- * Unpackers+ unpackFrom,+ unpackFromString,+ unpackFromHandle,+ unpackFromFile,+ ) where++import Control.Monad+import Control.Monad.Trans+import Data.ByteString (ByteString)+import qualified Data.ByteString as BS+import System.IO++import Data.MessagePack.Base hiding (Unpacker)+import qualified Data.MessagePack.Base as Base+import Data.MessagePack.Class+import Data.MessagePack.Feed++class Monad m => MonadPacker m where+ -- | Serialize a object+ put :: OBJECT a => a -> m ()++class Monad m => MonadUnpacker m where+ -- | Deserialize a object+ get :: OBJECT a => m a++-- | Serializer Type+newtype PackerT m r = PackerT { runPackerT :: Base.Packer -> m r }++instance Monad m => Monad (PackerT m) where+ a >>= b =+ PackerT $ \pc -> do+ r <- runPackerT a pc+ runPackerT (b r) pc+ + return r =+ PackerT $ \_ -> return r++instance MonadTrans PackerT where+ lift m = PackerT $ \_ -> m++instance MonadIO m => MonadIO (PackerT m) where+ liftIO = lift . liftIO++instance MonadIO m => MonadPacker (PackerT m) where+ put v = PackerT $ \pc -> liftIO $ do+ pack pc v++-- | Execute given serializer and returns byte sequence.+packToString :: MonadIO m => PackerT m r -> m ByteString+packToString m = do+ sb <- liftIO $ newSimpleBuffer+ pc <- liftIO $ newPacker sb+ runPackerT m pc+ liftIO $ simpleBufferData sb++-- | Execcute given serializer and write byte sequence to Handle.+packToHandle :: MonadIO m => Handle -> PackerT m r -> m ()+packToHandle h m = do+ sb <- packToString m+ liftIO $ BS.hPut h sb+ liftIO $ hFlush h++-- | Execute given serializer and write byte sequence to file.+packToFile :: MonadIO m => FilePath -> PackerT m r -> m ()+packToFile p m = do+ sb <- packToString m+ liftIO $ BS.writeFile p sb++-- | Deserializer type+newtype UnpackerT m r = UnpackerT { runUnpackerT :: Base.Unpacker -> Feeder -> m r }++instance Monad m => Monad (UnpackerT m) where+ a >>= b =+ UnpackerT $ \up feed -> do+ r <- runUnpackerT a up feed+ runUnpackerT (b r) up feed+ + return r =+ UnpackerT $ \_ _ -> return r++instance MonadTrans UnpackerT where+ lift m = UnpackerT $ \_ _ -> m++instance MonadIO m => MonadIO (UnpackerT m) where+ liftIO = lift . liftIO++instance MonadIO m => MonadUnpacker (UnpackerT m) where+ get = UnpackerT $ \up feed -> liftIO $ do+ resp <- unpackerExecute up+ guard $ resp>=0+ when (resp==0) $ do+ Just bs <- feed+ unpackerFeed up bs+ resp2 <- unpackerExecute up+ guard $ resp2==1+ obj <- unpackerData up+ freeZone =<< unpackerReleaseZone up+ unpackerReset up+ let Right r = fromObject obj+ return r++-- | Execute deserializer using given feeder.+unpackFrom :: MonadIO m => Feeder -> UnpackerT m r -> m r+unpackFrom f m = do+ up <- liftIO $ newUnpacker defaultInitialBufferSize+ runUnpackerT m up f++-- | Execute deserializer using given handle.+unpackFromHandle :: MonadIO m => Handle -> UnpackerT m r -> m r+unpackFromHandle h m =+ flip unpackFrom m =<< liftIO (feederFromHandle h)++-- | Execute deserializer using given file content.+unpackFromFile :: MonadIO m => FilePath -> UnpackerT m r -> m r+unpackFromFile p m = do+ h <- liftIO $ openFile p ReadMode+ r <- flip unpackFrom m =<< liftIO (feederFromHandle h)+ liftIO $ hClose h+ return r++-- | Execute deserializer from given byte sequence.+unpackFromString :: MonadIO m => ByteString -> UnpackerT m r -> m r+unpackFromString bs m = do+ flip unpackFrom m =<< liftIO (feederFromString bs)
+ src/Data/MessagePack/Stream.hs view
@@ -0,0 +1,84 @@+--------------------------------------------------------------------+-- |+-- Module : Data.MessagePack.Stream+-- Copyright : (c) Hideyuki Tanaka, 2009+-- License : BSD3+--+-- Maintainer: tanaka.hideyuki@gmail.com+-- Stability : experimental+-- Portability: portable+--+-- Lazy Stream Serializers and Deserializers+--+--------------------------------------------------------------------++module Data.MessagePack.Stream(+ unpackObjects,+ unpackObjectsFromFile,+ unpackObjectsFromHandle,+ unpackObjectsFromString,+ ) where++import Control.Monad+import Data.ByteString (ByteString)+import qualified Data.ByteString as BS+import System.IO+import System.IO.Unsafe++import Data.MessagePack.Base+import Data.MessagePack.Feed++-- | Unpack objects using given feeder.+unpackObjects :: Feeder -> IO [Object]+unpackObjects feeder = do+ up <- newUnpacker defaultInitialBufferSize+ f up+ where+ f up = unsafeInterleaveIO $ do+ mbo <- unpackOnce up+ case mbo of+ Just o -> do+ os <- f up+ return $ o:os+ Nothing ->+ return []++ unpackOnce up = do+ resp <- unpackerExecute up+ case resp of+ 0 -> do+ r <- feedOnce up+ if r+ then unpackOnce up+ else return Nothing+ 1 -> do+ obj <- unpackerData up+ freeZone =<< unpackerReleaseZone up+ unpackerReset up+ return $ Just obj+ _ ->+ error $ "unpackerExecute fails: " ++ show resp++ feedOnce up = do+ dat <- feeder+ case dat of+ Nothing ->+ return False+ Just bs -> do+ unpackerFeed up bs+ return True++-- | Unpack objects from file.+unpackObjectsFromFile :: FilePath -> IO [Object]+unpackObjectsFromFile fname =+ unpackObjects =<< feederFromFile fname++-- | Unpack objects from handle.+unpackObjectsFromHandle :: Handle -> IO [Object]+unpackObjectsFromHandle h =+ unpackObjects =<< feederFromHandle h+ +-- | Unpack oobjects from given byte sequence.+unpackObjectsFromString :: ByteString -> IO [Object]+unpackObjectsFromString bs =+ unpackObjects =<< feederFromString bs